MyBatis的一级缓存

一级缓存:(本地缓存),sqlSession级别的缓存,一级缓存是一直开启的,就是SqlSession级别的一个Map。与数据库的同一个会话期间查询到的数据会放到本地缓存中,以后查询相同的数据,直接从缓存中读取,不用在查询数据库,减少数据库的交互,作用域同一个会话。测试如下代码:

查询不同的一条数据代码如下

  /***
     * 查询一条sql 传不同的参数
     * @throws IOException
     */
    @Test
    public void testCache() throws IOException {
        // 读取类路径 config目录下的 mybatis-config.xml 配置文件 获取mybatis 全局配置  数据库连接 等信息
        String resource = "config/mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 获取一个 SqlSession
        SqlSession openSession =new SqlSessionFactoryBuilder().build(inputStream).openSession();
        try {
            //  获取一个映射器
            DeptMapper mapper=  openSession.getMapper(DeptMapper.class);
            // 查询ID为3的部门的信息
            mapper.selectDeptById(2);
            mapper.selectDeptById(3);
        } finally {
            // 关闭Session
            openSession.close();
        }
    }

控制台输出 sql语句发送两次

Created connection 55331187.
Returned connection 55331187 to pool.
Opening JDBC Connection
Checked out connection 55331187 from pool.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
==>  Preparing: select * from tbl_dept where id = ? 
==> Parameters: 2(Integer)
<==    Columns: id, dept_name
<==        Row: 2, 蜀国
<==      Total: 1
==>  Preparing: select * from tbl_dept where id = ? 
==> Parameters: 3(Integer)
<==    Columns: id, dept_name
<==        Row: 3, 吴国
<==      Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
Returned connection 55331187 to pool.

Process finished with exit code 0

查询相同的一条数据代码如下

  /***
     * 查询一条sql 传相同的参数
     * @throws IOException
     */
    @Test
    public void testCache() throws IOException {
        // 读取类路径 config目录下的 mybatis-config.xml 配置文件 获取mybatis 全局配置  数据库连接 等信息
        String resource = "config/mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 获取一个 SqlSession
        SqlSession openSession =new SqlSessionFactoryBuilder().build(inputStream).openSession();
        try {
            //  获取一个映射器
            DeptMapper mapper=  openSession.getMapper(DeptMapper.class);
            // 查询ID为3的部门的信息
            mapper.selectDeptById(2);
            mapper.selectDeptById(2);
        } finally {
            // 关闭Session
            openSession.close();
        }
    }

控制台输出 sql语句发送一次

Opening JDBC Connection
Checked out connection 55331187 from pool.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
==>  Preparing: select * from tbl_dept where id = ? 
==> Parameters: 2(Integer)
<==    Columns: id, dept_name
<==        Row: 2, 蜀国
<==      Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
Returned connection 55331187 to pool.

Process finished with exit code 0

一级缓存失效的情况

  • SqlSession不同
  • SqlSession相同,查询条件不同(如上述代码)
  • SqlSession相同,两次查询之间执行了增删改操作
  • SqlSession相同,手动清除了一级缓存

####

 /***
     * 一级缓存
     * @throws IOException
     */
    @Test
        public void testCache() throws IOException {
        // 读取类路径 config目录下的 mybatis-config.xml 配置文件 获取mybatis 全局配置  数据库连接 等信息
        String resource = "config/mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
        // 获取一个 SqlSession
        SqlSession sqlSession =sqlSessionFactory.openSession();
        // 获取一个 SqlSession2
        SqlSession sqlSession2 =sqlSessionFactory.openSession();
        try {
            //  获取一个映射器
            DeptMapper mapper=  sqlSession.getMapper(DeptMapper.class);
            //  查询ID为3的部门的信息
            mapper.selectDeptById(3);

            DeptMapper mapper2=  sqlSession2.getMapper(DeptMapper.class);

            //  再次查询ID为3的部门的信息
            mapper2.selectDeptById(3);
        } finally {
            // 关闭Session
            sqlSession.close();
            sqlSession2.close();
        }
    }

控制台日志:发送两次sql语句,缓存失效了

Created connection 824208363.
Returned connection 824208363 to pool.
Opening JDBC Connection
Checked out connection 55331187 from pool.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
==>  Preparing: select * from tbl_dept where id = ? 
==> Parameters: 3(Integer)
<==    Columns: id, dept_name
<==        Row: 3, 吴国
<==      Total: 1
Opening JDBC Connection
Checked out connection 824208363 from pool.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@31206beb]
==>  Preparing: select * from tbl_dept where id = ? 
==> Parameters: 3(Integer)
<==    Columns: id, dept_name
<==        Row: 3, 吴国
<==      Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
Returned connection 55331187 to pool.
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@31206beb]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@31206beb]
Returned connection 824208363 to pool.

Process finished with exit code 0

SqlSession相同,两次查询之间执行了增删改操作

 /***
     * 查询一条sql 传相同的参数 两次查询之间有添加操作
     * 一级缓存
     * @throws IOException
     */
    @Test
    public void testCache() throws IOException {
        // 读取类路径 config目录下的 mybatis-config.xml 配置文件 获取mybatis 全局配置  数据库连接 等信息
        String resource = "config/mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 获取一个 SqlSession
        SqlSession openSession =new SqlSessionFactoryBuilder().build(inputStream).openSession();
        try {
            //  获取一个映射器
            DeptMapper mapper=  openSession.getMapper(DeptMapper.class);
            //  查询ID为3的部门的信息
            mapper.selectDeptById(2);
            //  添加一个部门
            boolean flag= mapper.insertDept(new Dept(4,"大汉"));
            System.out.println("flag:"+flag);
            //  再次查询ID为3的部门的信息
            mapper.selectDeptById(3);
        } finally {
            // 关闭Session
            openSession.close();
        }
    }

控制台日志:发送两次sql语句,缓存失效了

Opening JDBC Connection
Checked out connection 55331187 from pool.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
==>  Preparing: select * from tbl_dept where id = ? 
==> Parameters: 2(Integer)
<==    Columns: id, dept_name
<==        Row: 2, 蜀国
<==      Total: 1
==>  Preparing: insert into tbl_dept(dept_name) values ( ? ) 
==> Parameters: 大汉(String)
<==    Updates: 1
flag:true
==>  Preparing: select * from tbl_dept where id = ? 
==> Parameters: 2(Integer)
<==    Columns: id, dept_name
<==        Row: 2, 蜀国
<==      Total: 1
Rolling back JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
Returned connection 55331187 to pool.
PooledDataSource forcefully closed/removed all connections.

手动清除了一级缓存

  /***
     * 一级缓存
     * @throws IOException
     */
    @Test
    public void testCache() throws IOException {
        // 读取类路径 config目录下的 mybatis-config.xml 配置文件 获取mybatis 全局配置  数据库连接 等信息
        String resource = "config/mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 获取一个 SqlSession
        SqlSession openSession =new SqlSessionFactoryBuilder().build(inputStream).openSession();
        try {
            //  获取一个映射器
            DeptMapper mapper=  openSession.getMapper(DeptMapper.class);
            //  查询ID为3的部门的信息
            mapper.selectDeptById(3);
            //  清除缓存
            openSession.clearCache();
            //  再次查询ID为3的部门的信息
            mapper.selectDeptById(3);
        } finally {
            // 关闭Session
            openSession.close();
        }
    }

控制台日志:发送两次sql语句,缓存失效了

Created connection 55331187.
Returned connection 55331187 to pool.
Opening JDBC Connection
Checked out connection 55331187 from pool.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
==>  Preparing: select * from tbl_dept where id = ? 
==> Parameters: 3(Integer)
<==    Columns: id, dept_name
<==        Row: 3, 吴国
<==      Total: 1
==>  Preparing: select * from tbl_dept where id = ? 
==> Parameters: 3(Integer)
<==    Columns: id, dept_name
<==        Row: 3, 吴国
<==      Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@34c4973]
Returned connection 55331187 to pool.

Process finished with exit code 0