mybatis基础之二->Mybatis SQL映射文件详解

在之前我们学习了mybatis的全局配置文件,下面我们开始学习mybatis的映射文件,在映射文件中,可以编写以下的顶级元素标签:

cache – 该命名空间的缓存配置。
cache-ref – 引用其它命名空间的缓存配置。
resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
parameterMap – 老式风格的参数映射。此元素已被废弃,并可能在将来被移除!请使用行内参数映射。文档中不会介绍此元素。
sql – 可被其它语句引用的可重用语句块。
insert – 映射插入语句。
update – 映射更新语句。
delete – 映射删除语句。
select – 映射查询语句。

​ 在每个顶级元素标签中可以添加很多个属性,下面我们开始详细了解下具体的配置。

1、insert、update、delete元素

属性 描述
id 在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType 将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
parameterMap 用于引用外部 parameterMap 的属性,目前已被废弃。请使用行内参数映射和 parameterType 属性。
flushCache 将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:(对 insert、update 和 delete 语句)true。
timeout 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。
statementType 可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
useGeneratedKeys (仅适用于 insert 和 update)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),默认值:false。
keyProperty (仅适用于 insert 和 update)指定能够唯一识别对象的属性,MyBatis 会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值,默认值:未设置(unset)。如果生成列不止一个,可以用逗号分隔多个属性名称。
keyColumn (仅适用于 insert 和 update)设置生成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列不是表中的第一列的时候,是必须设置的。如果生成列不止一个,可以用逗号分隔多个属性名称。
databaseId 如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有不带 databaseId 或匹配当前 databaseId 的语句;如果带和不带的语句都有,则不带的会被忽略。
    
    
        insert into user(user_name) values(#{userName})
    
    
    
        
            select max(id)+1 from user
        
        insert into user(id,user_name) values(#{id},#{userName})
    

2、select元素

1、select的参数传递

    

    
2、参数的取值方式

​ 在xml文件中编写sql语句的时候有两种取值的方式,分别是#{}和${},下面来看一下他们之间的区别:

 
    
3、处理集合返回结果

EmpDao.xml


    

    

    
    

UserDao.java

package com.mashibing.dao;

import com.mashibing.bean.Emp;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

public interface EmpDao {

    public Emp findEmpByEmpno(Integer empno);

    public int updateEmp(Emp emp);

    public int deleteEmp(Integer empno);

    public int insertEmp(Emp emp);

    Emp selectEmpByNoAndName(@Param("empno") Integer empno, @Param("ename") String ename,@Param("t") String tablename);
    Emp selectEmpByNoAndName2(Map map);

    List selectAllEmp();

    Map selectEmpByEmpReturnMap(Integer empno);

    @MapKey("empno")
    Map getAllEmpReturnMap();
}
4、自定义结果集---resultMap

Dog.java

package com.mashibing.bean;

public class Dog {
    private Integer id;
    private String name;
    private Integer age;
    private String gender;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}

dog.sql

/*
Navicat MySQL Data Transfer

Source Server         : node01
Source Server Version : 50729
Source Host           : 192.168.85.111:3306
Source Database       : demo

Target Server Type    : MYSQL
Target Server Version : 50729
File Encoding         : 65001

Date: 2020-03-24 23:54:22
*/

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `dog`
-- ----------------------------
DROP TABLE IF EXISTS `dog`;
CREATE TABLE `dog` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `dname` varchar(255) DEFAULT NULL,
  `dage` int(11) DEFAULT NULL,
  `dgender` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of dog
-- ----------------------------
INSERT INTO dog VALUES ('1', '大黄', '1', '雄');
INSERT INTO dog VALUES ('2', '二黄', '2', '雌');
INSERT INTO dog VALUES ('3', '三黄', '3', '雄');

DogDao.java

package com.mashibing.dao;

import com.mashibing.bean.Dog;

public interface DogDao {

    public Dog selectDogById(Integer id);
}

DogDao.xml




   
   
   

   
   
      
      
      
      
      
      
   
   
 

   
  
5、联合查询

emp.java

package com.mashibing.bean;

import java.util.Date;

public class Emp {

    private Integer empno;
    private String ename;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Double sal;
    private Double common;
    private Dept dept;

    public Emp() {
    }

    public Emp(Integer empno, String ename) {
        this.empno = empno;
        this.ename = ename;
    }

    public Emp(Integer empno, String ename, String job, Integer mgr, Date hiredate, Double sal, Double common, Dept dept) {
        this.empno = empno;
        this.ename = ename;
        this.job = job;
        this.mgr = mgr;
        this.hiredate = hiredate;
        this.sal = sal;
        this.common = common;
        this.dept = dept;
    }

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public Integer getMgr() {
        return mgr;
    }

    public void setMgr(Integer mgr) {
        this.mgr = mgr;
    }

    public Date getHiredate() {
        return hiredate;
    }

    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }

    public Double getSal() {
        return sal;
    }

    public void setSal(Double sal) {
        this.sal = sal;
    }

    public Double getCommon() {
        return common;
    }

    public void setCommon(Double common) {
        this.common = common;
    }

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "empno=" + empno +
                ", ename='" + ename + '\'' +
                ", job='" + job + '\'' +
                ", mgr=" + mgr +
                ", hiredate=" + hiredate +
                ", sal=" + sal +
                ", common=" + common +
                ", dept=" + dept +
                '}';
    }
}

Dept.java

package com.mashibing.bean;

public class Dept {
    private Integer deptno;
    private String dname;
    private String loc;

    public Dept() {
    }

    public Dept(Integer deptno, String dname, String loc) {
        this.deptno = deptno;
        this.dname = dname;
        this.loc = loc;
    }

    public Integer getDeptno() {
        return deptno;
    }

    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }

    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    public String getLoc() {
        return loc;
    }

    public void setLoc(String loc) {
        this.loc = loc;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "deptno=" + deptno +
                ", dname='" + dname + '\'' +
                ", loc='" + loc + '\'' +
                '}';
    }
}

EmpDao.xml






    
    
    
        
        
        
        
        
        
        
        
        
        
    
    
    
        
        
        
        
        
        
        
        
            
            
            
        
    

Test

    @Test
    public void test08() {

        // 获取数据库的会话
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmpDao mapper = sqlSession.getMapper(EmpDao.class);
            Emp emp = mapper.selectEmpAndDept(7369);
            System.out.println(emp);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }
6、获取集合元素

Dept.java

package com.mashibing.bean;

import java.util.List;

public class Dept {
    private Integer deptno;
    private String dname;
    private String loc;

    private List emps;

    public Dept() {
    }

    public Dept(Integer deptno, String dname, String loc) {
        this.deptno = deptno;
        this.dname = dname;
        this.loc = loc;
    }

    public Integer getDeptno() {
        return deptno;
    }

    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }

    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    public String getLoc() {
        return loc;
    }

    public void setLoc(String loc) {
        this.loc = loc;
    }

    public List getEmps() {
        return emps;
    }

    public void setEmps(List emps) {
        this.emps = emps;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "deptno=" + deptno +
                ", dname='" + dname + '\'' +
                ", loc='" + loc + '\'' +
                ", emps=" + emps +
                '}';
    }
}

DeptDao.java

package com.mashibing.dao;

import com.mashibing.bean.Dept;
import com.mashibing.bean.Emp;

import java.util.List;

public interface DeptDao {

    public Dept getDeptAndEmps(Integer deptno);
}

DeptDao.xml




    
    
    
        
        
        
        
        
            
            
            
            
            
            
            
        
    

Test

    @Test
    public void test09() {

        // 获取数据库的会话
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            DeptDao mapper = sqlSession.getMapper(DeptDao.class);
            Dept deptAndEmps = mapper.getDeptAndEmps(10);
            System.out.println(deptAndEmps);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }
7、分步查询

​ 在上述逻辑的查询中,是由我们自己来完成sql语句的关联查询的,那么,我们能让mybatis帮我们实现自动的关联查询吗?
关联查询的分步

DeptDao.java

package com.mashibing.dao;

import com.mashibing.bean.Dept;
import com.mashibing.bean.Emp;

import java.util.List;

public interface DeptDao {

    public Dept getDeptAndEmps(Integer deptno);

    public Dept getDeptAndEmpsBySimple(Integer deptno);
}

EmpDao.java

package com.mashibing.dao;

import com.mashibing.bean.Emp;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

public interface EmpDao {

    Emp selectEmpAndDept(Integer empno);
    Emp selectEmpAndDeptBySimple(Integer empno);
}

DeptDao.xml




    

EmpDao.xml





    
    
        
        
        
        
        
        
        
        
        
    

Test

@Test
    public void test08() {

        // 获取数据库的会话
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmpDao mapper = sqlSession.getMapper(EmpDao.class);
//            Emp emp = mapper.selectEmpAndDept(7369);
            Emp emp = mapper.selectEmpAndDeptBySimple(7369);
            System.out.println(emp);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

集合的分步查询

EmpDao.java

package com.mashibing.dao;

import com.mashibing.bean.Emp;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

public interface EmpDao {
    Emp selectEmpAndDeptBySimple(Integer empno);
    Emp selectEmpByStep(Integer empno);
}

DeptDao.java

package com.mashibing.dao;

import com.mashibing.bean.Dept;
import com.mashibing.bean.Emp;

import java.util.List;

public interface DeptDao {

    public Dept getDeptAndEmps(Integer deptno);

    public Dept getDeptAndEmpsBySimple(Integer deptno);

    public Dept getDeptAndEmpsByStep(Integer deptno);
}

EmpDao.xml





    

DeptDao.xml





    
    
        
        
        
        
        
        
    

Test

    @Test
    public void test09() {

        // 获取数据库的会话
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            DeptDao mapper = sqlSession.getMapper(DeptDao.class);
//            Dept deptAndEmps = mapper.getDeptAndEmps(10);
            Dept deptAndEmpsByStep = mapper.getDeptAndEmpsByStep(10);
            System.out.println(deptAndEmpsByStep);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }
8、延迟查询

​ 当我们在进行表关联的时候,有可能在查询结果的时候不需要关联对象的属性值,那么此时可以通过延迟加载来实现功能。在全局配置文件中添加如下属性

mybatis-config.xml

 
        
        
    

如果设置了全局加载,但是希望在某一个sql语句查询的时候不适用延时策略,可以添加如下属性:

        

3、动态sql

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

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

​ 如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

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

EmpDao.xml

EmpDao.java

public List getEmpByCondition(Emp emp);

Test.java

 @Test
    public void test10() {

        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmpDao mapper = sqlSession.getMapper(EmpDao.class);
            Emp emp = new Emp();
            emp.setEmpno(6500);
            emp.setEname("%E%");
            emp.setSal(500.0);
            List empByCondition = mapper.getEmpByCondition(emp);
            for (Emp emp1 : empByCondition) {
                System.out.println(emp1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

​ 看起来测试是比较正常的,但是大家需要注意的是如果我们传入的参数值有缺失会怎么呢?这个时候拼接的sql语句就会变得有问题,例如不传参数或者丢失最后一个参数,那么语句中就会多一个where或者and的关键字,因此在mybatis中也给出了具体的解决方案:

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

​ 现在看起来没有什么问题了,但是我们的条件添加到了拼接sql语句的前后,那么我们该如何处理呢?

 
    
2、foreach

​ 动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。


    
3、choose

​ 有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

4、set

​ 用于动态更新语句的类似解决方案叫做 setset 元素可以用于动态包含需要更新的列,忽略其它不更新的列。


    update emp
    
        
            empno=#{empno},
        
        
            ename = #{ename},
        
        
            sal = #{sal}
        
    
    
        empno = #{empno}
    

4、缓存

​ MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。 为了使它更加强大而且易于配置,我们对 MyBatis 3 中的缓存实现进行了许多改进。

​ 默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:

当添加上该标签之后,会有如下效果:

  • 映射语句文件中的所有 select 语句的结果将会被缓存。
  • 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
  • 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
  • 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
  • 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
  • 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

在进行配置的时候还会分为一级缓存和二级缓存:

一级缓存:线程级别的缓存,是本地缓存,sqlSession级别的缓存

二级缓存:全局范围的缓存,不止局限于当前会话

1、一级缓存的使用

​ 一级缓存是sqlsession级别的缓存,默认是存在的。在下面的案例中,大家发现我发送了两个相同的请求,但是sql语句仅仅执行了一次,那么就意味着第一次查询的时候已经将结果进行了缓存。

 @Test
    public void test01() {

        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmpDao mapper = sqlSession.getMapper(EmpDao.class);
            List list = mapper.selectAllEmp();
            for (Emp emp : list) {
                System.out.println(emp);
            }
            System.out.println("--------------------------------");
            List list2 = mapper.selectAllEmp();
            for (Emp emp : list2) {
                System.out.println(emp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

​ 在大部分的情况下一级缓存是可以的,但是有几种特殊的情况会造成一级缓存失效:

1、一级缓存是sqlSession级别的缓存,如果在应用程序中只有开启了多个sqlsession,那么会造成缓存失效

@Test
    public void test02(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpDao mapper = sqlSession.getMapper(EmpDao.class);
        List list = mapper.selectAllEmp();
        for (Emp emp : list) {
            System.out.println(emp);
        }
        System.out.println("================================");
        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        EmpDao mapper2 = sqlSession2.getMapper(EmpDao.class);
        List list2 = mapper2.selectAllEmp();
        for (Emp emp : list2) {
            System.out.println(emp);
        }
        sqlSession.close();
        sqlSession2.close();
    }

2、在编写查询的sql语句的时候,一定要注意传递的参数,如果参数不一致,那么也不会缓存结果

3、如果在发送过程中发生了数据的修改,那么结果就不会缓存

 @Test
    public void test03(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpDao mapper = sqlSession.getMapper(EmpDao.class);
        Emp empByEmpno = mapper.findEmpByEmpno(1111);
        System.out.println(empByEmpno);
        System.out.println("================================");
        empByEmpno.setEname("zhangsan");
        int i = mapper.updateEmp(empByEmpno);
        System.out.println(i);
        System.out.println("================================");
        Emp empByEmpno1 = mapper.findEmpByEmpno(1111);
        System.out.println(empByEmpno1);
        sqlSession.close();
    }

4、在两次查询期间,手动去清空缓存,也会让缓存失效

@Test
    public void test03(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpDao mapper = sqlSession.getMapper(EmpDao.class);
        Emp empByEmpno = mapper.findEmpByEmpno(1111);
        System.out.println(empByEmpno);
        System.out.println("================================");
        System.out.println("手动清空缓存");
        sqlSession.clearCache();
        System.out.println("================================");
        Emp empByEmpno1 = mapper.findEmpByEmpno(1111);
        System.out.println(empByEmpno1);
        sqlSession.close();
    }
2、二级缓存

​ 二级缓存是全局作用域缓存,默认是不开启的,需要手动进行配置。

​ Mybatis提供二级缓存的接口以及实现,缓存实现的时候要求实体类实现Serializable接口,二级缓存在sqlSession关闭或提交之后才会生效。

1、缓存的使用

​ 步骤:

​ 1、全局配置文件中添加如下配置:

 

​ 2、需要在使用二级缓存的映射文件出使用标签标注

​ 3、实体类必须要实现Serializable接口

@Test
    public void test04(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        EmpDao mapper = sqlSession.getMapper(EmpDao.class);
        EmpDao mapper2 = sqlSession2.getMapper(EmpDao.class);
        Emp empByEmpno = mapper.findEmpByEmpno(1111);
        System.out.println(empByEmpno);
        sqlSession.close();

        Emp empByEmpno1 = mapper2.findEmpByEmpno(1111);
        System.out.println(empByEmpno1);
        sqlSession2.close();
    }
2、缓存的属性

​ eviction:表示缓存回收策略,默认是LRU

​ LRU:最近最少使用的,移除最长时间不被使用的对象

​ FIFO:先进先出,按照对象进入缓存的顺序来移除

​ SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象

​ WEAK:弱引用,更积极地移除基于垃圾收集器状态和弱引用规则的对象

​ flushInternal:刷新间隔,单位毫秒

​ 默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新

​ size:引用数目,正整数

​ 代表缓存最多可以存储多少个对象,太大容易导致内存溢出

​ readonly:只读,true/false

​ true:只读缓存,会给所有调用这返回缓存对象的相同实例,因此这些对象不能被修改。

​ false:读写缓存,会返回缓存对象的拷贝(序列化实现),这种方式比较安全,默认值

    //可以看到会去二级缓存中查找数据,而且二级缓存跟一级缓存中不会同时存在数据,因为二级缓存中的数据是在sqlsession 关闭之后才生效的
    @Test
    public void test05(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpDao mapper = sqlSession.getMapper(EmpDao.class);
        Emp empByEmpno = mapper.findEmpByEmpno(1111);
        System.out.println(empByEmpno);
        sqlSession.close();

        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        EmpDao mapper2 = sqlSession2.getMapper(EmpDao.class);
        Emp empByEmpno2 = mapper2.findEmpByEmpno(1111);
        System.out.println(empByEmpno2);
        Emp empByEmpno3 = mapper2.findEmpByEmpno(1111);
        System.out.println(empByEmpno3);
        sqlSession2.close();
    }

    // 缓存查询的顺序是先查询二级缓存再查询一级缓存
     @Test
    public void test05(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpDao mapper = sqlSession.getMapper(EmpDao.class);
        Emp empByEmpno = mapper.findEmpByEmpno(1111);
        System.out.println(empByEmpno);
        sqlSession.close();

        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        EmpDao mapper2 = sqlSession2.getMapper(EmpDao.class);
        Emp empByEmpno2 = mapper2.findEmpByEmpno(1111);
        System.out.println(empByEmpno2);
        Emp empByEmpno3 = mapper2.findEmpByEmpno(1111);
        System.out.println(empByEmpno3);

        Emp empByEmpno4 = mapper2.findEmpByEmpno(7369);
        System.out.println(empByEmpno4);
        Emp empByEmpno5 = mapper2.findEmpByEmpno(7369);
        System.out.println(empByEmpno5);
        sqlSession2.close();
    }

3、二级缓存的作用范围:

​ 如果设置了全局的二级缓存配置,那么在使用的时候需要注意,在每一个单独的select语句中,可以设置将查询缓存关闭,以完成特殊的设置

​ 1、在setting中设置,是配置二级缓存开启,一级缓存默认一直开启

 

​ 2、select标签的useCache属性:

​ 在每一个select的查询中可以设置当前查询是否要使用二级缓存,只对二级缓存有效

​ 3、sql标签的flushCache属性

​ 增删改操作默认值为true,sql执行之后会清空一级缓存和二级缓存,而查询操作默认是false

​ 4、sqlSession.clearCache()

​ 只是用来清楚一级缓存

3、整合第三方缓存

​ 在某些情况下我们也可以自定义实现缓存,或为其他第三方缓存方案创建适配器,来完全覆盖缓存行为。

​ 1、导入对应的maven依赖

 
        
            org.ehcache
            ehcache
            3.8.1
        
        
        
            org.mybatis.caches
            mybatis-ehcache
            1.2.0
        
        
        
            org.slf4j
            slf4j-api
            2.0.0-alpha1
        
        
        
            org.slf4j
            slf4j-log4j12
            2.0.0-alpha1
            test
        

​ 2、导入ehcache配置文件



 
 
 
 
 

 

​ 3、在mapper文件中添加自定义缓存

  

你可能感兴趣的:(mybatis)