初识Mybatis(二)动态SQL、缓存和逆向工程

动态SQL

Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决拼接SQL语句字符串时的痛点问题。

(比如多条件查询的设置,实现判空等)

1、if

创建DynamicSQLMapper接口,DynamicSQLMapper.xml文件

 DynamicSQLMapper接口:
 List getEmpByCondition(Emp emp);

 DynamicSQLMapper.xml中:

List集合作为方法的返回值,以防查出多个数据。

以上用if条件作为sql的查询判断筛选结果,但存在问题,原意是判断如果查询条件中姓名不为空(即需要查询姓名)则将姓名条件赋值,后面对年龄、性别的if语句也是做同样的判断,实现最终sql语句的拼接。

创建测试方法DynamicSQLMapperTest

public void testGetEmpByCondition(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Emp emp = new Emp(null, "大大", 7, "女");
        List empByCondition = mapper.getEmpByCondition(emp);
        empByCondition.forEach(System.out::println);
    }

从赋值条件可以看出,是实现查询姓名为大大、年龄为7、性别为女的记录。如下得到对应的查询结果,我们可以知道如果只有性别做了指定,到那时其余为空,则我们将查询到男或女的所有数据。(这个实现其实就是if的逻辑,如果我们设定的条件不为空则会拼接到sql语句,进行条件查询)

初识Mybatis(二)动态SQL、缓存和逆向工程_第1张图片

但是如果第一个条件(上述代码为对empName是否赋值的判断)不成立,where后则会直接凭借下一个语句,为符合和语法(where后面不可以直接加and),一般会在where语句后加上一个恒成立条件,拼接较为完善的sql语句

2、where

where和if一般结合使用:


a>若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字

eg:上述条件都不满足,则会执行select * from t_emp


b>若where标签中的if条件满足,则where标签会自动添加where关键字,

eg:第一个条件满足,但前面没有where会自动添加即select * from t_emp  where emp_name = #{empName}

并将条件最前方多余的and去掉 ,eg:第一个条件不满足,后面带有and的条件满足,则自动去掉and拼接,

select * from t_emp  where age = #{age} and gender = #{gender} (后面两个都满足)
注意:where标签不能去掉条件最后多余的and(即把and放在条件后面时,age = #{age} and)

3、trim

trim用于去掉或添加标签中的内容
常用属性:
prefix:在trim标签中的内容的前面添加某些内容
prefixOverrides:在trim标签中的内容的前面去掉某些内容
suffix:在trim标签中的内容的后面添加某些内容
suffixOverrides:在trim标签中的内容的后面去掉某些内容


        select * from t_emp
        
            
                
                    emp_name = #{empName}
                
                
                    age = #{age}
                
                
                    gender = #{gender}
                
            
        
    

上述逻辑:当为empName赋值查询(即不为null或空字符串时)将emp_name = #{empName}拼接到sql语句,但是后面的内容将不再判断执行,只要有一个满足要求,后面都不会再继续判断,而当前面都不满足代码中有othwise标签,则执行该标签的内容(即都没有给empName合age赋值,则根据gender赋值查询(注意,当查询内容条件都为空时,因为在where标签下,会自动补上where,则查询语句变成select * from t_emp WHERE gender = ?,查询结果如下

初识Mybatis(二)动态SQL、缓存和逆向工程_第2张图片

a

5、foreach

1、用foreach实现批量添加

 
    
        insert into t_emp values
        
            (null,#{emp.empName},#{emp.age},#{emp.gender},null)
        
    

如果传输过来的是list集合数据,collection属性应该写list,可以采取@param注解方法,那么下次直接填写设置的参数名即可。即@param(“emps”),则collection=emps获取该list集合数据。

且item的赋值就是个参数名,可以自己取,记得插入的值不是empName,而是emp.empName(因为item在这里为emp,所以是item.empName),我们获取的是list集合,里面都是由Emp对象组成,所以要获取单个属性值,应该是对象.属性名的形式(我是这么理解的)

上面代码的相关属性如下,可以知道separator=”,“是为了实现插入多个数值并隔开的效果,values(),(),(),()(不是单纯的在插入语句后加,因为最后还有会一个逗号存在

属性:
collection:设置要循环的数组或集合
item:表示集合或数组中的每一个数据
separator:设置循环体之间的分隔符
open:设置foreach标签中的内容的开始符
close:设置foreach标签中的内容的结束符

测试代码如下,

 public void testinsertMoreEmp(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Emp emp = new Emp(null, "小饿", 3, "男");
        Emp emp1 = new Emp(null, "紫紫", 7, "女");
        Emp emp2 = new Emp(null, "凹凸", 4, "女");
        List emps = Arrays.asList(emp,emp1,emp2);
        mapper.insertMoreEmp(emps);
    }
初识Mybatis(二)动态SQL、缓存和逆向工程_第3张图片

插入结果如图

初识Mybatis(二)动态SQL、缓存和逆向工程_第4张图片

(补充:mapper接口的方法中参数值为list的时候,mybatis都会把数据放在map中,以list为键,当前参数为值,如果是数组,则以array为键,当前参数为值

eg

初识Mybatis(二)动态SQL、缓存和逆向工程_第5张图片

如下为数组形式的测试方法:

public void testinsertMoreEmpArray(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Emp emp = new Emp(null, "小粉", 3, "女");
        Emp emp1 = new Emp(null, "小黑", 4, "女");
        Emp emp2 = new Emp(null, "三日兔", 7, "女");
        Emp[] emps = new Emp[]{emp,emp1,emp2};
        mapper.insertMoreEmpArray(emps);
    }

初识Mybatis(二)动态SQL、缓存和逆向工程_第6张图片

所以还是用注解好,直接写注解取的名字。

2、用foreach实现批量删除

 
    
        delete from t_emp where emp_id in
        (
            
                #{empId}
            
        )
    

其括号可以如下替换表示

初识Mybatis(二)动态SQL、缓存和逆向工程_第7张图片

或是

初识Mybatis(二)动态SQL、缓存和逆向工程_第8张图片

(seperator=or,其实在拼接sql语句时or前后自动由空格)

如下为测试方法,删除id为10和13的记录

 public void testdeleteMoreEmp(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Integer[] empIds = {10, 13};
        mapper.deleteMoreEmp(empIds);
    }

SQL片段

sql标签,将常用的sql片段进行记录,用include的标签在需要时引入。

 
        emp_id,emp_name,age,gender,dept_id