参数传递
有时Mapper接口需要将一个或多个参数传递到XML映射文件中,那么XML文件如何接收到来自Mapper接口的参数数据呢?
1、Mapper接口方法只有一个参数时,则XML映射文件中获取该参数数据时硬性的要求,比如:接口抽象方法参数为String id,则XML映射文件中可通过#{任意字符串 }获取到该参数的数据。
String selectUserNameById(int id);
<select id="selectUserNameById" resultType="java.lang.String">
select user_name from user_info where id=#{whatever}
</select>
2、Mapper接口方法当有多个参数时,则默认情况下MyBatis将这些参数放在Map集合中,key为arg0…argn或param1…paramn,在XML映射文件中通过#{key}获取key所对应的参数数据;但为了在获取参数数据时XML映射文件中的key有意义,可以通过在Mapper接口相应抽象方法的参数数据类型前添加@Param注解的方式指定key的值。
boolean addUserOnArg(int id, String userName, String password);
boolean addUserOnParam(@Param("id")int id, @Param("userName")String userName, @Param("password")String password);
<insert id="addUserOnArg">
insert into user_info (id, user_name, password) values (#{arg0}, #{arg1}, #{arg2})
</insert>
<insert id="addUserOnParam">
insert into user_info (id, user_name, password) values (#{id}, #{userName}, #{password})
</insert>
3、当参数为自定义引用类型时,则XML映射文件直接使用#{成员变量名}的方式获取相应成员变量的值。
4、${}
与#{}
区别:
${}
直接将数据和sql进行拼接,无法防止SQL注入;
#{}
以占位符方式作为占位符,可以防止SQL注入。
reslutMap标签
通过resultMap注册userInfo关联数据库与自定义类的属性,可在增删改查操作中直接返回自定义的resultMap。
tips:
1.resultMap与resultType不能同时使用
2.id与result作用相同,id表示主键
3.property为UserInfo类中的属性名 | column为数据库中的属性名
<resultMap type="com.zzxtit.mybatis.entity.UserInfo" id="userInfo">
<id property="id" column="user_info_id"/>
<result property="age" column="age"/>
<result property="password" column="password"/>
<result property="realName" column="user_info_real_name"/>
<result property="userName" column="user_name"/>
</resultMap>
<select id="selectUserSize" resultMap="userInfo">
select id,user_name,password from user_info
</select>
resultMap的一对多关联
当事务比较复杂,A表关联B表时,也可使用resultMap进行一对多的建立。
//此处省略了其余属性
public class UserInfo {
private Address address;
}
public class Address {
private String address;
}
<resultMap id="userInfo" type="com.zzxtit.mybatis.entity.UserInfo" >
<id property="id" column="user_info_id"/>
<result property="age" column="age"/>
<result property="password" column="password"/>
<result property="realName" column="user_info_real_name"/>
<result property="userName" column="user_name"/>
<collection property="address" ofType="com.zzxtit.mybatis.entity.Address">
<id property="id" column="address_id"/>
<result property="realName" column="address_real_name"/>
<result property="mobile" column="mobile"/>
<result property="address" column="address"/>
</collection>
</resultMap>
<select id="selectUserAndAddressById" resultMap="userInfo">
select ui.id user_info_id, ui.age, ui.`password`, ui.real_name user_info_real_name, ui.user_name,
addr.id address_id, addr.real_name address_real_name, addr.mobile, addr.address
from user_info ui
LEFT JOIN address addr on addr.user_id = ui.id
WHERE ui.id = #{id}
</select>
sql标签
sql标签可以将一段字段先定义后调用,提高代码复用性。
<sql id="barCode">
bar_code barCode
</sql>
<select id="selectAllById" resultType="com.zzxtit.entity.Goods">
select <include refid="barCode"></include> from t_goods_info where goods_id = #{goodsId}
</select>
动态sql语句处理
当我们在做多个条件的查询操作时,不一定每个属性都会有值,那么将出现某些属性传递null而导致sql无法处理的结果,而动态sql提供了一种方式,使得sql可以根据传递的值得情况,自动拼接sql语句。
<where>
+<if>
<select id="selectUserByNameOrAge" resultMap="userInfo">
select id,user_name,password,real_name,age
from user_info
<where><!-- 当其一为null时会自动消除and -->
<if test="userName != null">
and user_name like #{userName}
</if>
<if test="age != null">
and age=#{age}
</if>
</where>
</select>
<choose>
<!-- <choose>只会选择其中一个(优先选前者,类比switch)-->
<select id="selectUserByNameOrAge" resultMap="userInfo">
select id,user_name,password,real_name,age
from user_info
<choose>
<when test="userName != null">
and user_name like #{userName}
</when>
<when test="age != null">
and age=#{age}
</when>
</choose>
</select>
<set>
<update id="update">
update user_info
<set>
<if test="realName != null">
real_name=#{realName}, <!-- set标签能自动删除 "," ,若无set则出错-->
</if>
<if test="age != null">
age=#{age}
</if>
</set>
where id=#{id}
</update>
<foreach>
<!-- 批量删除 -->
<delete id="delete">
delete from user_info
where id in
<foreach collection="list" item="id" open="(" close=")" separator=",">
<!-- 传入list,自动遍历,以 "(" 开头 以 ")" 结尾 以 "," 分割
list.size=1 ==> (?)
list.size=2 ==> (?,?)
-->
#{id}
</foreach>
</delete>