MyBatis---缓存以及整合第三方缓存

MyBatis自带的缓存(其实就是Map)流程:
       1、首先看二级缓存中是否有要查询的对象,如果没有就查看一级缓存中是否有要查询的对象,再没有就从数据库中查找。
       2、查到后就将数据放到一级缓存中。
       3、当SqlSession关闭或提交后,一级缓存中的数据放到二级缓存中。

注意:CUD执行后不仅会清空一级缓存,还会清空二级缓存。

此博客用log4j进行日志记录



一、一级缓存

       一级缓存是存在于一次数据库会话中的。MyBatis是默认开启一级缓存的。

正常情况:
	@Test
    public void test01() {
        String resource = "mybatis-config.xml";
        SqlSessionFactory sqlSessionFactory = null;
        SqlSession sqlSession = null;
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

            sqlSession = sqlSessionFactory.openSession(true);   //设置为自动提交
            StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
            Student student1 = studentDao.QueryById(8);
            System.out.println(student1);
            Student student2 = studentDao.QueryById(8);
            System.out.println(student2);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

       测试结果:
Alt
       只发了一次sql语句,说明被一级缓存截获了。


异常情况(一级缓存失效):

       1、开启另一个数据库会话,需要重新查询。

	@Test
    public void test01() {
        String resource = "mybatis-config.xml";
        SqlSessionFactory sqlSessionFactory = null;
        SqlSession sqlSession1 = null, sqlSession2 = null;
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

            sqlSession1 = sqlSessionFactory.openSession(true);   //设置为自动提交
            StudentDao studentDao1 = sqlSession1.getMapper(StudentDao.class);
            sqlSession2 = sqlSessionFactory.openSession(true);   //设置为自动提交
            StudentDao studentDao2 = sqlSession2.getMapper(StudentDao.class);
            Student student1 = studentDao1.QueryById(8);
            System.out.println(student1);
            Student student2 = studentDao2.QueryById(8);
            System.out.println(student2);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            sqlSession1.close();
            sqlSession2.close();
        }
    }

       测试结果:
Alt
       发了两次sql语句,说明一级缓存失效了。

       2、在一次会话中,两次查询中间穿插了增删改操作。

	@Test
    public void test01() {
        String resource = "mybatis-config.xml";
        SqlSessionFactory sqlSessionFactory = null;
        SqlSession sqlSession1 = null, sqlSession2 = null;
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

            sqlSession1 = sqlSessionFactory.openSession(true);   //设置为自动提交
            StudentDao studentDao1 = sqlSession1.getMapper(StudentDao.class);
            Student student1 = studentDao1.QueryById(8);
            System.out.println(student1);
            studentDao1.Add(new Student(null, "小花", "12345", 18));
            Student student2 = studentDao1.QueryById(8);
            System.out.println(student2);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            sqlSession1.close();
        }
    }

       测试结果:
Alt
       两次查询中间穿插了一次添加,一级缓存失效了。


       3、手动清空了缓存。

	@Test
    public void test01() {
        String resource = "mybatis-config.xml";
        SqlSessionFactory sqlSessionFactory = null;
        SqlSession sqlSession1 = null, sqlSession2 = null;
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

            sqlSession1 = sqlSessionFactory.openSession(true);   //设置为自动提交
            StudentDao studentDao1 = sqlSession1.getMapper(StudentDao.class);
            Student student1 = studentDao1.QueryById(8);
            System.out.println(student1);
            sqlSession1.clearCache();
            Student student2 = studentDao1.QueryById(8);
            System.out.println(student2);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            sqlSession1.close();
        }
    }

       测试结果:
Alt
       一级缓存被手动清空了。



二、二级缓存

       二级缓存是保存在全局作用域里面的,MyBatis需要手动开启二级缓存。二级缓存要求实体类必须经过序列化,且必须在SqlSession关闭或者提交之后才会起作用。


IDEA快捷生成序列化ID
       IDEA点击File- ->Settings- ->Editor- ->Inspections,输入Serializable class without serialVersionUID
Alt
       应用并重启IDE,双击选中需要序列ID的类再按下Alt+Enter。



       在全局配置文件中增加下面配置:

	<!--        开启二级缓存-->
    <setting name="cacheEnabled" value="true"/>

       在需要开启二级缓存的xml文件中添加cache标签。

	<mapper namespace="com.cj.dao.StudentDao">
	    <cache></cache>
	    ...
	</mapper>
	@Test
    public void test01() {
        String resource = "mybatis-config.xml";
        SqlSessionFactory sqlSessionFactory = null;
        SqlSession sqlSession1 = null, sqlSession2 = null;
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

            sqlSession1 = sqlSessionFactory.openSession(true);   //设置为自动提交
            StudentDao studentDao1 = sqlSession1.getMapper(StudentDao.class);
            sqlSession2 = sqlSessionFactory.openSession(true);   //设置为自动提交
            StudentDao studentDao2 = sqlSession2.getMapper(StudentDao.class);
            Student student1 = studentDao1.QueryById(8);
            System.out.println(student1);
            sqlSession1.close();    //手动关闭第一次会话
            Student student2 = studentDao2.QueryById(8);
            System.out.println(student2);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            sqlSession2.close();
        }
    }

       测试结果:
Alt

三、整合第三方缓存(Redis等等)

       1、导包。

       2、编写第三方缓存的配置文件。

       3、在需要用缓存技术相应Dao配置文件中的cache标签中指定使用的缓存种类。

发布了33 篇原创文章 · 获赞 5 · 访问量 2276

猜你喜欢

转载自blog.csdn.net/cj1561435010/article/details/104092206