四. trim() 去除前后缀
<select id="findAllF3" parameterType="user" resultMap="userResultMap"> select * from user t <!-- 去掉第一个and --> <trim prefix="where" prefixOverrides="and"> <if test="name!=null and name!=''"> and t.name like concat('%',#{name},'%') </if> <if test="age!=null"> and t.age>#{age} </if> </trim> </select>
前缀 prefix 是 where , 去除前缀注解 prefixOverrides 的and , 即去除where 后的第一个and 关键字, 这样就可以在每一个 语句后面跟上 and 而不出错了。
除了前缀之外,还有后缀 suffix 和对应的suffixOverrides 。
常见的是前缀, 去除的是 and 或者是 or.
五. choose (when,otherwise) 多分支选择
在前面的两个参数 name,age 时 查询,是多条件查询, name 和sex 是没有先后顺序的。 而在业务当中,常常是有先后顺序的。 如 name 有值,则查询name, name 无值 则去查询age, 如果age 仍然没有值,则保证 description 描述不能为空, 查询的条件之间是有明显的先后顺序的。 这个时候,就需要用 choose 了。
接口:
//有顺序的查询 List<User> findAllF4(User user);
sql 语句: (先用以前的 1=1 模式)
<select id="findAllF4" parameterType="user" resultMap="userResultMap"> select * from user t where 1=1 <!--总的选择开头--> <choose> <!--对每一种情况进行判断--> <when test="name!=null and name!=''"> and t.name like concat('%',#{name},'%') </when> <when test="age!=null"> and t.age>#{age} </when> <!--所有条件都不符合,执行 otherwise --> <otherwise> and t.description is not null </otherwise> </choose> </select>
测试方法:
@Test public void findAllF4Test(){ SqlSession sqlSession=SqlSessionFactoryUtils.getSession(); UserMapper userMapper=sqlSession.getMapper(UserMapper.class); User user=new User(); //user.setName("蝴蝶飞"); //填写时, 不填写时不又其作为查询条件。 //两个条件时 有一定的先后顺序。 user.setName("蝴蝶飞"); user.setAge(24); List<User> allList=userMapper.findAllF4(user); allList.forEach(n ->System.out.println(n)); }
如果name 有值的话:
如果 name 无值, age 有值的话:
如果 name 和age 均没有值的话:
这样,就达到了 有先后顺序的查询了。
转换成 where 语句为:
<select id="findAllF4" parameterType="user" resultMap="userResultMap"> select * from user t <where> <choose> <when test="name!=null and name!=''"> and t.name like concat('%',#{name},'%') </when> <when test="age!=null"> and t.age>#{age} </when> <otherwise> and t.description is not null </otherwise> </choose> </where> </select>
六. set 更新部分字段
关于update 语句的用法,可以看第三章, 那个时候,更新都是更新全部的字段,无法进行部分字段的更新。 而以前所讲的Hibernate 只能进行全部字段的更新,这也是Hibernate 效率低的原因之一。
<update id="updateUser" parameterType="user"> update user set name=#{name},sex=#{sex},age=#{age},description=#{description} where id=#{id} </update>
而MyBatis 通过 set 语句,很好的解决了这一点。
接口:
int updateF5(User user);
sql 语句:
<update id="updateF5" parameterType="user"> update user <set> <if test="name!=null and name!=''"> name=#{name}, </if> <if test="age!=null"> age=#{age}, </if> <if test="description !=null"> description=#{description} </if> </set> where id=#{id} </update>
六.一 查询数据库更新
@Test public void findAllF51Test(){ SqlSession sqlSession=SqlSessionFactoryUtils.getSession(); UserMapper userMapper=sqlSession.getMapper(UserMapper.class); User user=userMapper.getById(1); user.setName("部分更新字段123"); user.setDescription("只修改部分字段"); userMapper.updateF5(user); sqlSession.commit(); }
会将数据库中查询出来的值进行判断,如果有值,那么就进行更新,没有值,就不更新。 如果将此时的 age字段在数据库中设置为null 的话.
再次运行的话:
发现,这个时候 就不会更新 age 字段了。
六.二 设置对象bean 更新
@Test public void findAllF52Test(){ SqlSession sqlSession=SqlSessionFactoryUtils.getSession(); UserMapper userMapper=sqlSession.getMapper(UserMapper.class); User user=new User(); user.setId(1); user.setName("部分更新字段"); user.setDescription("只修改部分字段"); userMapper.updateF5(user); sqlSession.commit(); }
这个时候,运行的话,是不会更新其他的字段的。