MyBatis理解与掌握(输入与输出)

@(MyBatis)[Java, 框架, MyBatis]

占位符和拼接

{}:占位符

能防止sql注入问题,所一能尽量用#{}就尽量用#{}
用来传入参数,sql在解析的时候会加上 "" 当成字符串来解析 ,如这里 role_id = "roleid";
模糊查询(不同的数据库采用不同的sql拼接方式)

  • mysql:
 select * from t_user where name like concat("%",#{zhang},"%")
  • oracle:
select * from t_user where name like "%" || #{zhang} || "%"

${}:拼接符

存在sql注入问题
$一般用入传入数据库对象,比如数据库表名、列名
注意:数据库表名、列名和排序方式不能使用#,而 应该使用$

表名使用拼串:sql select * from ${tableName};
列名使用拼串:sql select ${colName} from t_user;
排序使用拼串: sql select * from t_user where age = #{age} order by name ${orderType2}

sql注入

绕过了验证机制,把不应该查询的数据也给查询出来了,存在数据安全问题。拼串存在SQL注入是因为它把参数作为sql语法的一部分进行了编译,数据库会执行这条语句。使用占位符不存在SQL注入,是因为参数是在在sql编译后传递,数据库只会把参数作为查询条件进行判断。

"select * from t_user where id =" + id;
String id = "1 or 1=1";   //sql 注入出现

如果使用的是拼接的方式,对参数不同的sql语句会多次编译,增加了编译次数,降低效率。
原因:占位符方式,sql语句到数据库中取数据前才把参数加入进去。拼接是sql语句和参数一同编译,参数不同,编译后生成的sql语句不同,需要多次编译。

输入参数类型

parameterType

指定输入参数类型, mybatis 通过 ognl 从输入对象中获取参数值放置在 sql中。

(1)简单类型(字符串类型,Integer,int...)

parameterType="Integer"
应用场景:sql中只有一个参数的时候使用

(2)自定义类型

parameterType="com.george.pojo.Employee"
注意要写类的全路径
sql的参数会从自定义类的属性中获取,执行时,会根据参数名称在对象中反射调用方法,如果相同名称的属性不存在,会发生异常,所以__参数名称必须和属性名称保持一致__
应用场景:sql中多个参数有相同的含义,使用自定义类型
User user = session.selectOne("selectUser",user );

(3)参数类型可以为集合类型

parameterType="Map"
sql的参数会从Map集合中根据key获取参数值。所以,参数名称必须和Map集合的key名称一样
应用场景:sql中多个参数没有任何的关系时,采用Map集合类型。
User user = session.selectOne("selectUser",map);

查询结果处理

resultType

指定输出结果类型, mybatis 将 sql 查询结果的一行记录数据映射为 resultType 指定类型的对象。

封装成一个类

Mybatis框架的输出主要针对的就是 查询结果输出

<select id ="selectUser" resultType="com.george.pojo.User" >

resultType属性表示将查询结果转换为指定类型的对象时需要遵循的规则:
(1)查询结果的 字段名称回和属性名称进行匹配 ,如果匹配成功,则反射调用,通过set方法,赋值给对象。
(2)如果没有相匹配的字段和属性名称,则不会赋值,特殊情况下,一个属性都没有完成匹配,那么对象不会创建,返回null
(3)在属性名称和字段名称不匹配的情况下,可以通过sql语句中取别名或者在<resultMap></resultMap>中指定字段和属性的对应关系

select  u_code as userCode from t_user;

<resultMap type="Brand" id="brand">
    <result column="id" property="id" />
    <result column="name" property="name" />
    <result column="description" property="description" />
    <result column="img_url" property="imgUrl" />
    <result column="sort" property="sort" />
    <result column="is_display" property="isDisplay" />
</resultMap>
<select id="getBrandListWithPage" parameterType="Brand"
    resultMap="brand">
    select id , name ,description,img_url,sort,is_display
    from bbs_brand
    <where>
     <if test="isDisplay != null">
       is_display = #{isDisplay}
     </if>
     <if test="name != null">
       and name = #{name}
     </if>
    </where>
    order by id desc
    limit #{startRow},#{pageSize}
</select>

封装成一个Map

将字段名作为key,查询结果值作为value,放到Map中

<select id="selectUserByCode" resultType="java.util.HashMap" >
       select * from t_uset where usercode = 'zhangsan'
</select>
Map map = session.selectOne("selectUser");

使用场景:当数据间没有任何的关系,采用Map集合类型。

封装String与简单类型

将查询结果转换为String类型

<select id="selectUser" resultType="java.lang.String" >
   select * from t_user
</select>

返回的是查询结果的第一个字段

使用场景:
当获取数量或单一字段值的时候,使用简单类型接收数据

<select id="counts" resultType="Integer">
   select count(id) from t_user
</select>

苏生
803 声望725 粉丝