时间:2021-05-20
最近在读刘增辉老师所著的《MyBatis从入门到精通》一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸!
本篇博客主要讲解如何使用if标签生成动态的Sql,主要包含以下3个场景:
1.根据查询条件实现动态查询
2.根据参数值实现动态更新某些列
3.根据参数值实现动态插入某些列
1. 使用if标签实现动态查询
假设有这样1个需求:根据用户的输入条件来查询用户列表,如果输入了用户名,就根据用户名模糊查询,如果输入了邮箱,就根据邮箱精确查询,如果同时输入了用户名和邮箱,就用这两个条件去匹配用户。
首先,我们在接口SysUserMapper中添加如下方法:
/** * 根据动态条件查询用户信息 * * @param sysUser * @return */List<SysUser> selectByUser(SysUser sysUser);然后在对应的SysUserMapper.xml中添加如下代码:
<select id="selectByUser" resultType="com.zwwhnly.mybatisaction.model.SysUser"> SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE 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>代码简单讲解:
1)if标签的test属性必填,该属性值是一个符合OGNL要求的判断表达式,一般只用true或false作为结果。
2)判断条件property != null 或 property == null,适用于任何类型的字段,用于判断属性值是否为空。
3)判断条件property != '' 或 property == '',仅适用于String类型的字段,用于判断是否为空字符串。
4)当有多个判断条件时,使用and或or进行连接,嵌套的判断可以使用小括号分组,and相当于Java中的与(&&),or相关于Java中的或(||)。
所以上面代码的意思就是先判断字段是否为null,然后再判断字段是否为空字符串。
最后,在SysUserMapperTest测试类中添加如下测试方法:
@Testpublic void testSelectByUser() { SqlSession sqlSession = getSqlSession(); try { SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class); // 只按用户名查询 SysUser query = new SysUser(); query.setUserName("ad"); List<SysUser> sysUserList = sysUserMapper.selectByUser(query); Assert.assertTrue(sysUserList.size() > 0); // 只按邮箱查询 query = new SysUser(); query.setUserEmail("test@mybatis.tk"); sysUserList = sysUserMapper.selectByUser(query); Assert.assertTrue(sysUserList.size() > 0); // 同时按用户民和邮箱查询 query = new SysUser(); query.setUserName("ad"); query.setUserEmail("test@mybatis.tk"); sysUserList = sysUserMapper.selectByUser(query); // 由于没有同时符合这两个条件的用户,因此查询结果数为0 Assert.assertTrue(sysUserList.size() == 0); } finally { sqlSession.close(); }}运行测试代码,测试通过,输出日志如下:
DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE 1 = 1 AND user_name LIKE CONCAT('%',?,'%')DEBUG [main] - ==> Parameters: ad(String)TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_timeTRACE [main] - <== Row: 1, admin, 123456, admin@mybatis.tk, 2019-06-27 18:21:07.0DEBUG [main] - <== Total: 1DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE 1 = 1 AND user_email = ?DEBUG [main] - ==> Parameters: test@mybatis.tk(String)TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_timeTRACE [main] - <== Row: 1001, test, 123456, test@mybatis.tk, 2019-06-27 18:21:07.0DEBUG [main] - <== Total: 1DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE 1 = 1 AND user_name LIKE CONCAT('%',?,'%') AND user_email = ?DEBUG [main] - ==> Parameters: ad(String), test@mybatis.tk(String)DEBUG [main] - <== Total: 02. 使用if标签实现动态更新
假设有这样1个需求:更新用户信息的时候不能将原来有值但没有发生变化的字段更新为空或null,即只更新有值的字段。
首先,我们在接口SysUserMapper中添加如下方法:
然后在对应的SysUserMapper.xml中添加如下代码:
<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} WHERE id = #{id}</update>最后,在SysUserMapperTest测试类中添加如下测试方法:
@Testpublic void testUpdateByIdSelective() { SqlSession sqlSession = getSqlSession(); try { SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class); SysUser sysUser = new SysUser(); // 更新id=1的用户 sysUser.setId(1L); // 修改邮箱 sysUser.setUserEmail("test@mybatis.tk"); int result = sysUserMapper.updateByIdSelective(sysUser); Assert.assertEquals(1, result); // 查询id=1的用户 sysUser = sysUserMapper.selectById(1L); // 修改后的名字保持不变,但是邮箱变成了新的 Assert.assertEquals("admin", sysUser.getUserName()); Assert.assertEquals("test@mybatis.tk", sysUser.getUserEmail()); } finally { sqlSession.close(); }}运行测试代码,测试通过,输出日志如下:
DEBUG [main] - ==> Preparing: UPDATE sys_user SET user_email = ?, id = ? WHERE id = ?DEBUG [main] - ==> Parameters: test@mybatis.tk(String), 1(Long), 1(Long)DEBUG [main] - <== Updates: 1DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE id = ?DEBUG [main] - ==> Parameters: 1(Long)TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_timeTRACE [main] - <== Row: 1, admin, 123456, test@mybatis.tk, 2019-06-27 18:21:07.0DEBUG [main] - <== Total: 13. 使用if标签实现动态插入
假设有这样1个需求:往数据库表中插入数据的时候,如果某一列的参数值不为空,就使用传入的值,如果传入的参数值为空,就使用数据库中的默认值(通常是空),而不使用传入的空值。
为了更好的理解该示例,我们先给sys_user表的user_email字段设置默认值:test@mybatis.tk,Sql语句如下:
ALTER TABLE sys_userMODIFY COLUMN user_email VARCHAR(50) NULL DEFAULT 'test@mybatis.tk'COMMENT '邮箱'AFTER user_password;首先,我们在接口SysUserMapper中添加如下方法:
/** * 根据传入的参数值动态插入列 * * @param sysUser * @return */int insertSelective(SysUser sysUser);然后在对应的SysUserMapper.xml中添加如下代码:
<insert id="insertSelective" useGeneratedKeys="true" keyProperty="id"> INSERT INTO sys_user(user_name, user_password, <if test="userEmail != null and userEmail != ''"> user_email, </if> user_info, head_img, create_time) VALUES (#{userName},#{userPassword}, <if test="userEmail != null and userEmail != ''"> #{userEmail}, </if> #{userInfo},#{headImg,jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP})</insert>最后,在SysUserMapperTest测试类中添加如下测试方法:
@Testpublic void testInsertSelective() { SqlSession sqlSession = getSqlSession(); try { SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class); SysUser sysUser = new SysUser(); sysUser.setUserName("test-selective"); sysUser.setUserPassword("123456"); sysUser.setUserInfo("test info"); sysUser.setCreateTime(new Date()); sysUserMapper.insertSelective(sysUser); // 获取刚刚插入的数据 sysUser = sysUserMapper.selectById(sysUser.getId()); // 因为没有指定userEmail,所以用的是数据库的默认值 Assert.assertEquals("test@mybatis.tk", sysUser.getUserEmail()); } finally { sqlSession.close(); }}运行测试代码,测试通过,输出日志如下:
DEBUG [main] - ==> Preparing: INSERT INTO sys_user(user_name, user_password, user_info, head_img, create_time) VALUES (?,?, ?,?,?)DEBUG [main] - ==> Parameters: test-selective(String), 123456(String), test info(String), null, 2019-07-08 11:40:36.927(Timestamp)DEBUG [main] - <== Updates: 1DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, create_time FROM sys_user WHERE id = ?DEBUG [main] - ==> Parameters: 1021(Long)TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_timeTRACE [main] - <== Row: 1021, test-selective, 123456, test@mybatis.tk, 2019-07-08 11:40:37.0DEBUG [main] - <== Total: 14. 源码
源码地址:https://github.com/zwwhnly/mybatis-action.git,欢迎下载。
总结
以上所述是小编给大家介绍的MyBatis动态Sql之if标签的用法详解 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
mybatis动态sql之Map参数Mapper文件:select*fromprod_purchasewhere1=1andpurc_id=#{purc_id}
前言MyBatis的强大特性之一便是它的动态SQL。所以今天小编在这里为大家介绍一下Mybatis的一个强大功能-动态SQL动态SQL是Mybatis的一个强大
MyBatis中sql标签定义SQL片段,include标签引用,可以复用SQL片段sql标签中id属性对应include标签中的refid属性。通过inclu
动态SQL什么是动态SQL?MyBatis的官方文档中是这样介绍的?动态SQL是MyBatis的强大特性之一。如果你使用过JDBC或其它类似的框架,你应该能理解
一、简介Mybatis-Plus是一款MyBatis动态sql自动注入crud简化增删改查操作中间件。启动加载XML配置时注入mybatis单表动态SQL操作,