动态sql在xml中支持的几种标签:
- if
- choose(when、otherwise)
- trim(where、set)
- foreach
-
4.1 if用法
4.1.1 在where条件中使用if
/*** 根据动态条件查询用户信息* @param user* @return*/List<SysUser> selectByUser(SysUser user);
<select id="selectByUser" resultType="com.ql.simple.model.SysUser">select id,user_name,user_password,user_email,user_info,head_img,create_timefrom sys_userwhere 1 = 1<if test="userName != null and userName != ''">and user_name like concat('%', #{userName}, '%')</if><if test="userEmail != null and userEmail != ''">and user_email = #{userEmail}</if></select>
if中必填的属性时test,test是一个符合OGNL要求的判断表达式
注意sql中where关键字后面的条件
- 注意条件中的and或or
测试:
@Testpublic void testSelectByUser() {SqlSession sqlSession = getSqlSession();try {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);// 只查询用户名SysUser user = new SysUser();user.setUserName("ad");List<SysUser> userList = userMapper.selectByUser(user);Assert.assertTrue(userList.size() > 0);// 只查询邮箱SysUser user2 = new SysUser();user2.setUserEmail("test@mybatis.tk");List<SysUser> userList2 = userMapper.selectByUser(user2);Assert.assertTrue(userList2.size() > 0);// 同时查询用户名和邮箱SysUser user3 = new SysUser();user3.setUserName("ad");user3.setUserEmail("test@mybatis.tk");List<SysUser> userList3 = userMapper.selectByUser(user3);Assert.assertTrue(userList3.size() == 0);}finally {sqlSession.close();}}
4.1.2 在update更新列中使用if
/*** 根据主键更新* @param sysUser* @return*/int updateByIdSelective(SysUser sysUser);
<update id="updateByIdSelective">update sys_userset<if test="userName != null and userName != ''">user_name = #{userName},</if><if test="userPassword != null and userPassword != ''">user_password = #{userPassword},</if><if test="userEmail != null and userEmail != ''">user_email = #{userEmail},</if><if test="userInfo != null and userInfo != ''">user_info = #{userInfo},</if><if test="headImg != null">head_img = #{headImg, jdbcType=BLOB},</if><if test="createTime != null">create_time = #{createTime,jdbcType=TIMESTAMP},</if>id = #{id}where id = #{id}</update>
- 注意 id = #{id}条件,防止if全部不成立时,sql语法错误
每个if查询中都是有“,”的,所以最后id = #{id}省略的话,会导致sql语法错误
4.1.3 在insert动态插入列中使用if
/*** 添加用户,使用useGenerateKeys方式* @param user* @return*/int insert2(SysUser user);
<insert id="insert2" useGeneratedKeys="true" keyProperty="id">insert into sys_user(id,user_name,user_password,<if test="userEmail != null and userEmail != ''">user_email,</if>user_info,head_img,create_time)values ( #{id}, #{userName}, #{userPassword},<if test="userEmail != null and userEmail != ''">#{userEmail},</if>#{userInfo}, #{headImg, jdbcType=BLOB}, #{createTime, jdbcType=TIMESTAMP} )</insert>
4.2 choose用法
/*** 根据用户id或用户名查询* @param sysUser* @return*/SysUser selectByIdOrUserName(SysUser sysUser);
<select id="selectByIdOrUserName" resultType="com.ql.simple.model.SysUser">select id,user_name,user_password,user_email,user_info,head_img,create_timefrom sys_userwhere 1 = 1<choose><when test="id != null">and id = #{id}</when><when test="userName != null and userName != ''">and user_name = #{userName}</when><otherwise>and 1 = 2</otherwise></choose></select>
4.3 wherre、set、trim用法
4.3.1 where用法
<select id="selectByUser" resultType="com.ql.simple.model.SysUser">select id,user_name,user_password,user_email,user_info,head_img,create_timefrom sys_user<where><if test="userName != null and userName != ''">and user_name like concat('%', #{userName}, '%')</if><if test="userEmail != null and userEmail != ''">and user_email = #{userEmail}</if></where></select>
也就是sql中where语句的作用,但是这里的where标签会把语句后面and或or开头的单词去掉,这样就不会有sql异常。这样也不需要像之前那样添加1 = 1 这样的临时条件
4.3.2 set用法
<update id="updateByIdSelective">update sys_user<set><if test="userName != null and userName != ''">user_name = #{userName},</if><if test="userPassword != null and userPassword != ''">user_password = #{userPassword},</if><if test="userEmail != null and userEmail != ''">user_email = #{userEmail},</if><if test="userInfo != null and userInfo != ''">user_info = #{userInfo},</if><if test="headImg != null">head_img = #{headImg, jdbcType=BLOB},</if><if test="createTime != null">create_time = #{createTime,jdbcType=TIMESTAMP},</if>id = #{id},</set>where id = #{id}</update>
set的作用和update语句中set语句的作用一致,只是如果该标签后面的字符串是以逗号结尾的,就将这个逗号剔除
4.3.3 trim的用法
where和set标签的功能都可以用trim标签来实现,底层就是通过TrimSqlNode来实现的
where标签对应的trim的实现:<trim prefix="WHERE" prefixOverrides="AND | OR">...</trim>
set标签对应的trim实现:
<trim prefix="SET" suffixOverrides=",">...</trim>
4.4 foreach用法
4.4.1 foreach实现in集合
/*** 根据用户id集合查询* @param idList* @return*/List<SysUser> selectByIdList(List<Long> idList);
<select id="selectByIdList" resultType="com.ql.simple.model.SysUser">select id,user_name,user_password,user_email,user_info,head_img,create_timefrom sys_userwhere id in<foreach collection="list" open="(" close=")" separator="," item="id" index="i">#{id}</foreach></select>
foreach包含的属性:
collection:必填,值为要迭代循环的属性名
- item:变量名
- index:索引的属性名
- open:整个循环内容开头的字符串
- close:整个循环内容结尾的字符串
- separator
collection属性的设置:
- 只有一个数组或集合参数
collection=”list” or collection=”array”
- 有多个参数
用@Param指定参数,将collection设为param注解指定的名字
- 参数是Map类型
与param注解相似,将collection指定为对应Map中的key即可,默认为_parameter
- 参数是一个对象
4.4.2 foreach实现批量插入
/*** 批量插入用户信息* @param userList* @return*/int insertList(List<SysUser> userList);
<insert id="insertList">insert into sys_user(user_name, user_password, user_email, user_info, head_img, create_time)values<foreach collection="list" item="user" separator=",">(#{user.userName}, #{user.userPassword}, #{user.userEmail}, #{user.userInfo}, #{user.headImg,jdbcType=BLOB},#{user.createTime,jdbcType=TIMESTAMP})</foreach></insert>
如果要在MySQL中实现批量插入返回自增主键值:
<insert id="insertList" useGeneratedKeys="true" keyProperty="id">
4.4.3 foreach实现动态update
/*** 通过Map更新列* @param map* @return*/int updateByMap(Map<String, Object> map);
<update id="updateByMap">update sys_userset<foreach collection="_parameter" item="val" index="key" separator=",">${key} = #{val}</foreach>where id = #{id}</update>
4.5 bind用法
bind标签主要是用来避免由于更换数据库带来的一些麻烦
<if test="userName != null and userName != ''">and user_name like concat('%', #{userName}, '%')</if>
该语句在mysql中正常,但是换到oracle会报错
<if test="userName != null and userName != ''"><bind name="userNameLike" value="'%' + userName + '%'"/>and user_name like #{userNameLike}</if>
