最近在读刘增辉老师所著的《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测试类中添加如下测试方法:
@Test public 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_time TRACE [main] - <== Row: 1, admin, 123456, admin@mybatis.tk, 2019-06-27 18:21:07.0 DEBUG [main] - <== Total: 1 DEBUG [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_time TRACE [main] - <== Row: 1001, test, 123456, test@mybatis.tk, 2019-06-27 18:21:07.0 DEBUG [main] - <== Total: 1 DEBUG [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: 0
2. 使用if标签实现动态更新
假设有这样1个需求:更新用户信息的时候不能将原来有值但没有发生变化的字段更新为空或null,即只更新有值的字段。
首先,我们在接口SysUserMapper中添加如下方法:
/** * 根据主键选择性更新用户信息 * * @param sysUser * @return */ int updateByIdSelective(SysUser sysUser);
然后在对应的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测试类中添加如下测试方法:
@Test public 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: 1 DEBUG [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_time TRACE [main] - <== Row: 1, admin, 123456, test@mybatis.tk, 2019-06-27 18:21:07.0 DEBUG [main] - <== Total: 1
3. 使用if标签实现动态插入
假设有这样1个需求:往数据库表中插入数据的时候,如果某一列的参数值不为空,就使用传入的值,如果传入的参数值为空,就使用数据库中的默认值(通常是空),而不使用传入的空值。
为了更好的理解该示例,我们先给sys_user表的user_email字段设置默认值:test@mybatis.tk,Sql语句如下:
ALTER TABLE sys_user MODIFY 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测试类中添加如下测试方法:
@Test public 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: 1 DEBUG [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_time TRACE [main] - <== Row: 1021, test-selective, 123456, test@mybatis.tk, 2019-07-08 11:40:37.0 DEBUG [main] - <== Total: 1
4. 源码
源码地址:https://github.com/zwwhnly/mybatis-action.git,欢迎下载。
总结
以上所述是小编给大家介绍的MyBatis动态Sql之if标签的用法详解 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小牛知识库网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
本文向大家介绍Mybatis动态SQL之if、choose、where、set、trim、foreach标记实例详解,包括了Mybatis动态SQL之if、choose、where、set、trim、foreach标记实例详解的使用技巧和注意事项,需要的朋友参考一下 动态SQL就是动态的生成SQL。 if标记 假设有这样一种需求:查询用户,当用户名不等于“admin”的时候,我们还需要密码为123
本文向大家介绍mybatis的动态sql之if test的使用说明,包括了mybatis的动态sql之if test的使用说明的使用技巧和注意事项,需要的朋友参考一下 参数为String,if test读取该参数代码 参数为pojo , if test读取该参数代码 补充:关于mybatis中 if test的条件怎么写 1.mybatis 中 的 if test写法 1.1官方文档上对于if是这
MyBatis if 类似于 Java 中的 if 语句,是 MyBatis 中最常用的判断语句。使用 if 标签可以节省许多拼接 SQL 的工作,把精力集中在 XML 的维护上。 if 语句使用方法简单,常常与 test 属性联合使用。语法如下。 当判断条件为 true 时,才会执行所包含的 SQL 语句。 最常见的场景是在 if 语句中包含 where 子句,例如。 以上代表表示根据网站名称去
本文向大家介绍详解Mybatis动态sql,包括了详解Mybatis动态sql的使用技巧和注意事项,需要的朋友参考一下 1.什么是mybatis动态sql 看到动态,我们就应该想到,这是一个可以变化的sql语句 MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑 2.mybatis动态sql使用前准备 a.数据库表 b.创建类 3.使用mybatis动
本文向大家介绍MyBatis使用动态SQL标签的小陷阱,包括了MyBatis使用动态SQL标签的小陷阱的使用技巧和注意事项,需要的朋友参考一下 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plai
本文向大家介绍mybatis的动态sql详解(精),包括了mybatis的动态sql详解(精)的使用技巧和注意事项,需要的朋友参考一下 MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力。如果你有使用 JDBC 或其他 相似框架的经验,你就明白条件地串联 SQL 字符串在一起是多么的痛苦,确保不能忘了空 格或在列表的最后省略逗号。动态 SQL 可以彻底处理这种痛苦。 通常使用动态SQ