MyBatis --- 缓存、逆向工程、分页插件

一、MyBatis的缓存

1.1、MyBatis的一级缓存

一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问

使一级缓存失效的四种情况:

1、不同的SqlSession对应不同的一级缓存

2、同一个SqlSession但是查询条件不同

3、同一个SqlSession两次查询期间执行了任何一次增删改操作

4、同一个SqlSession两次查询期间调用 clearCache()方法 手动清空了缓存

    @Test
    public void testGetEmpById(){
        SqlSession sqlSession1 = SqlSessionUtil.getSqlSession();
        CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
        Emp emp1 = mapper1.getEmpById(1);
        System.out.println(emp1);

        sqlSession1.clearCache();//手动清空一级缓存
        //mapper1.insertEmp(new Emp(null, "小红", 25, "男"));

        Emp emp2 = mapper1.getEmpById(1);
        System.out.println(emp2);

        /*SqlSession sqlSession2 = SqlSessionUtil.getSqlSession();
        CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
        Emp emp3 = mapper2.getEmpById(1);
        System.out.println(emp3);*/
    }

 

1.2、MyBatis的二级缓存

二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取

二级缓存开启的条件:

1、在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置

2、在映射文件中设置  标签

3、二级缓存必须在SqlSession关闭或提交之后有效

4、查询的数据所转换的实体类类型必须实现序列化的接口 Serializable

使二级缓存失效的情况:

两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效

    @Test
    public void testCache() throws IOException {
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        
        SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
        CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
        Emp emp1 = mapper1.getEmpById(1);
        System.out.println(emp1);
        sqlSession1.close();
        
        SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
        CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
        Emp emp2 = mapper2.getEmpById(1);
        System.out.println(emp2);
        sqlSession2.close();
    }

 

1.3、二级缓存的相关配置

在mapper配置文件中添加的cache标签可以设置一些属性:

1、eviction属性:缓存回收策略,默认的是 LRU。

      LRU(Least Recently Used)– 最近最少使用的:移除最长时间不被使用的对象。

      FIFO(First in First out)– 先进先出:按对象进入缓存的顺序来移除它们。

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

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

2、flushInterval属性:刷新间隔,单位毫秒

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

3、size属性:引用数目,正整数

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

4、readOnly属性:只读, true / false

      true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。

      false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是 false。

 

1.4、MyBatis缓存查询的顺序

先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。

如果二级缓存没有命中,再查询一级缓存

如果一级缓存也没有命中,则查询数据库

SqlSession关闭之后,一级缓存中的数据会写入二级缓存

 

1.5、整合第三方缓存EHCache

1.5.1、添加依赖

        
        
            org.mybatis.caches
            mybatis-ehcache
            1.2.1
        
        
        
            ch.qos.logback
            logback-classic
            1.2.3
        

 

1.5.2、各jar包功能

MyBatis --- 缓存、逆向工程、分页插件_第1张图片

  

1.5.3、创建EHCache的配置文件ehcache.xml



    
    
    
    

 

1.5.4、设置二级缓存的类型


  

1.5.5、加入logback日志

存在SLF4J时,作为简易日志的log4j将失效,此时我们需要借助SLF4J的具体实现logback来打印日 志。 创建logback的配置文件logback.xml



    
    
        
            
            
            [%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger]
                [%msg]%n
        
    
    
    
    
        
        
    
    
    

 

1.5.6、EHCache配置文件说明

MyBatis --- 缓存、逆向工程、分页插件_第2张图片

  

 

二、MyBatis的逆向工程

正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。 Hibernate是支持正向工 程的。

 

逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:

  • Java实体类
  • Mapper接口
  • Mapper映射文件

 

2.1、创建逆向工程的步骤

①添加依赖和插件

    
    
        
        
            org.mybatis
            mybatis
            3.5.13
        
        
        
            junit
            junit
            4.12
            test
        
        
        
            mysql
            mysql-connector-java
            5.1.32
        
        
        
            log4j
            log4j
            1.2.17
        
    
    
    
    
        
            
            
                org.mybatis.generator
                mybatis-generator-maven-plugin
                1.3.0
                
                
                    
                    
                        org.mybatis.generator
                        mybatis-generator-core
                        1.3.2
                    
                    
                    
                        mysql
                        mysql-connector-java
                        5.1.32
                    
                
            
        
    

  

②创建MyBatis的核心配置文件

  

③创建逆向工程的配置文件

文件名必须是:generatorConfig.xml




    
    
        
        
        
        
        
            
            
        
        
        
            
        
        
        
            
        
        
        
        
        

 

④执行MBG插件的generate目标

MyBatis --- 缓存、逆向工程、分页插件_第3张图片

  

⑤效果

MyBatis --- 缓存、逆向工程、分页插件_第4张图片

  

2.2、QBC查询

    @Test
    public void testMBG(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);

        //根据id查询数据
        /*Emp emp = mapper.selectByPrimaryKey(1);
        System.out.println(emp);*/

        //查询所有数据
        /*List list = mapper.selectByExample(null);
        list.forEach(System.out::println);*/

        //根据条件查询数据
        /*EmpExample example = new EmpExample();
        example.createCriteria().andEmpNameEqualTo("张三").andAgeGreaterThanOrEqualTo(20);
        example.or().andGenderEqualTo("男");
        List list = mapper.selectByExample(example);
        list.forEach(System.out::println);*/

        Emp emp = new Emp(1, "小黑", null, "女");
        //测试普通修改功能
        //mapper.updateByPrimaryKey(emp);
        //测试选择性修改
        mapper.updateByPrimaryKeySelective(emp);
    }

 

 

三、分页插件

3.1、分页插件的使用步骤

①添加依赖


    com.github.pagehelper
    pagehelper
    5.2.0

②配置分页插件

在MyBatis的核心配置文件中配置插件


    
    

 

3.2、分页插件的使用

1、在查询功能之前使用 PageHelper.startPage(int pageNum, int pageSize) 开启分页功能

      pageNum:当前页的页码

      pageSize:每页显示的条数

2、在查询获取list集合之后,使用 PageInfo pageInfo = new PageInfo<>(List list, int navigatePages) 获取分页相关数据

      list:分页之后的数据

      navigatePages:导航分页的页码数

3、分页相关数据

public class PageTest {

    /**
     * PageInfo{
     * pageNum=1, pageSize=4, size=4,
     * startRow=1, endRow=4, total=30,
     * pages=8,
     * list=Page{count=true, pageNum=1, pageSize=4, startRow=0, endRow=4, total=30, pages=8, reasonable=false, pageSizeZero=false}[Emp{empId=1, empName='aaa', age=null, gender='null', deptId=null}, Emp{empId=2, empName='a', age=null, gender='null', deptId=null}, Emp{empId=3, empName='a', age=null, gender='null', deptId=null}, Emp{empId=4, empName='a', age=null, gender='null', deptId=null}],
     * prePage=0, nextPage=2, isFirstPage=true,
     * isLastPage=false, hasPreviousPage=false,
     * hasNextPage=true, navigatePages=5,
     * navigateFirstPage=1, navigateLastPage=5, navigatepageNums=[1, 2, 3, 4, 5]}
     */

    @Test
    public void testPage(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        //查询功能之前开启分页功能
        Page page = PageHelper.startPage(1, 4);
        List list = mapper.selectByExample(null);

        //查询功能之后可以获取分页相关的所有数据
        PageInfo pageInfo = new PageInfo<>(list, 5);
        list.forEach(System.out::println);
        System.out.println(pageInfo);
    }
} 
  

pageNum:当前页的页码

pageSize:每页显示的条数

size:当前页显示的真实条数

total:总记录数

pages:总页数

prePage:上一页的页码

nextPage:下一页的页码

isFirstPage/isLastPage:是否为第一页/最后一页

hasPreviousPage/hasNextPage:是否存在上一页/下一页

navigatePages:导航分页的页码数

navigatepageNums:导航分页的页码,[1,2,3,4,5]

你可能感兴趣的:(SSM框架,mybatis,缓存,java)