MyBatis--动态SQL(if的用法)

(ps:测试工具为idea,SpringBoot整合Mybatis,基础配置及简单的单表操作省略....)

准备工作--

1.建表

 1 CREATE TABLE `sys_user`  (
 2   `id` int(11) NOT NULL AUTO_INCREMENT,
 3   `user_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名',
 4   `user_password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密码',
 5   `user_email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱',
 6   `user_info` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '简介',
 7   `head_img` blob NULL COMMENT '头像',
 8   `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
 9   PRIMARY KEY (`id`) USING BTREE
10 ) ENGINE = InnoDB AUTO_INCREMENT = 1007 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
11 
12 -- ----------------------------
13 -- Records of sys_user
14 -- ----------------------------
15 INSERT INTO `sys_user` VALUES (1, 'admin', '123456', 'admin@qq.com', '管理员', NULL, '2020-03-04 13:01:03');
16 INSERT INTO `sys_user` VALUES (1001, 'test', '123456', 'test@mybatis.com', '测试人员', NULL, '2020-03-04 13:01:43');
17 INSERT INTO `sys_user` VALUES (1005, 'test0', '123456', 'test@mybatis.tk', NULL, NULL, '2020-06-22 14:49:48');
18 INSERT INTO `sys_user` VALUES (1006, 'test1', '123456', 'test@mybatis.tk', NULL, NULL, '2020-06-22 14:49:48');
19 INSERT INTO `sys_user` VALUES (1007, 'test2', '123456', 'test@mybatis.tk', NULL, NULL, '2020-06-22 14:49:48');
20 
21 SET FOREIGN_KEY_CHECKS = 1;
sys_user.sql

2.实体类

 1 package com.beilin.menber.entity;
 2 
 3 
 4 import lombok.Data;
 5 /**
 6  * 用户表
 7  */
 8 import java.util.Date;
 9 import java.util.List;
10 
11 @Data
12 public class SysUser {
13     private Long id;//id自增
14     private String userName;//用户名
15     private String userPassword;//密码
16     private String userEmail;//邮箱
17     private String userInfo;//简介
18     private byte[] headImg;//头像
19     private Date createTime;//创建时间
20 
21 
22 }
SysUser

3.UserMapper接口

1 package com.beilin.menber.dao;
2 import java.util.List;
3 
4 public interface UserMapper {
5 
6     //根据id查询
7     SysUser selectById(Long id);
8 
9    }
UserMapper

4.XML文件

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!-- mybatis的dtd文件 -->
 3 <!DOCTYPE mapper
 4         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 5         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 6 <!--namespace属性: 用于指定指向那个接口 -->
 7 <mapper namespace="com.beilin.menber.dao.UserMapper">
 8     <resultMap id="userMap" type="com.beilin.menber.entity.SysUser">
 9         <id property="id" column="id"/>
10         <result property="userName" column="user_name"/>
11         <result property="userPassword" column="user_password"/>
12         <result property="userEmail" column="user_email"/>
13         <result property="userInfo" column="user_info"/>
14         <result property="headImg" column="head_img" jdbcType="BLOB"/>
15         <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
16     </resultMap>
17         
18       <sql id="userBase">
19          
20    id,user_name,user_password,user_email,user_info,head_img,create_time
21     </sql>
22     
23       <select id="selectById" resultType="SysUser">
24             select * from sys_user where id =#{id}
25         </select>
26 
27 </mapper>
SysUserMapper.xml

 

  动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

  使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

if标签通常用于WHERE语句中,通过判断参数值来决定是否使用某个查询条件,它也经常用于UPDATE语句中判断是否更新某一字段,还可以在INSERT语句中用来判断是否插入某个字段的值。

  假设需求:实现一个用户管理高级查询功能,根据输入的条件去检索用户信息,当只输入用户时,需要根据用户名进行模糊搜索;当只输入邮箱时,根据邮箱进行匹配;当同时输入用户名和邮箱时,用这两个条件去查询匹配的用户。

 首先需要在UserMapper接口中增加对应的接口方法,代码如下:

1  /**
2      * 根据动态条件查询用户信息
3      * @param user
4      * @return
5      */
6     List<SysUser> selectByUser(SysUser user);

 XML文件SQL

 1 <select id="selectByUser" resultType="SysUser">
 2    select id,
 3     user_name userName,
 4     user_password userPassword,
 5     user_email userEmail,
 6     user_info userInfo,
 7     create_time createTime
 8    from sys_user
 9    where 1 = 1 
10    <if test="userName != null and userName !=''">
11    and user_name like concat('%',#{userName},'%')
12    </if>
13    <if test="userEmail != null and userEmail !=''">
14       and user_email like concat('%',#{userEmai},'%')
15    </if>
16 </select>

 新建UserMapperTest测试类

 1 package com.beilin.menber.dao;
 2 
 3 
 4 import com.beilin.menber.entity.SysUser;
 5 import org.junit.jupiter.api.Test;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.boot.test.context.SpringBootTest;
 8 import org.springframework.util.Assert;
 9 
10 import java.util.ArrayList;
11 import java.util.Date;
12 import java.util.List;
13 import static org.junit.jupiter.api.Assertions.*;
14 
15 @SpringBootTest
16 class UserMapperTest {
17     @Autowired
18     private UserMapper userMapper;
19 
20 
21     @Test
22     void test(){
23         SysUser user=new SysUser();
24         //只传入用户名时
25         user.setUserName("ad");
26         List<SysUser>userList =userMapper.selectByUser(user);
27         System.out.println(userList);
28 
29     }
30 
31      @Test
32     void test1(){
33          SysUser user=new SysUser();
34          //只传入邮箱时
35          user.setUserEmail("test");
36          List<SysUser>userList =userMapper.selectByUser(user);
37          System.out.println(userList);
38     }
39      @Test
40     void test2(){
41          SysUser user=new SysUser();
42          //同时传入用户名和邮箱
43          user.setUserEmail("@mybatis.com");
44          user.setUserName("t");
45          List<SysUser>userList =userMapper.selectByUser(user);
46          System.out.println(userList);
47     }
48 
49   
50 
51 }

右键运行,然后控制台就会输出对应的信息,这里不一一测试了

  • 注意SQL中where关键字后面的条件

    where 1 = 1

  由于两个条件都是动态的,所以如果没有1=1这个默认条件,当两个if判断都不满足时,最后生成的SQL就会以where结束,这样不符合SQL规范,因此就会报错。加上1=1这个条件就可以避免SQL语法错误导致的异常。这种写法并美观,后面可以使用where标签替代这种写法。

  • 注意条件中的and(或or)

  这里的and(或or)需要手动添加,当这部分条件拼接到where 1 = 1 后面时仍然是合法的SQL,因为有默认的1=1这个条件,我们才不需要判断第一个动态条件是否需要加上and(或or),因为这种情况下and(或or)是必须有的。

原文地址:https://www.cnblogs.com/wx60079/p/13199658.html