查询缓存&&逆向工程

1.查询缓存

  一级缓存:同一个SqlSession对象,MyBatis默认开启一级缓存

  如果用同样的SqlSession对象查询相同的数据,则只会在第一次查询时向数据库发送Sql语句并将查询的结果放入到SqlSession中(作为缓存存在),后续再次查询该对象即可(即省略了数据库的访问)

  

     // Connection - SqlSession操作Mybatis
        // conf.xml->reader
        Reader reader = Resources.getResourceAsReader("conf.xml");
        // reader->sqlSession

        // 可以通过build的第二参数 指定数据库环境
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader, "development");
        SqlSession session = sessionFactory.openSession();

        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        Student student = studentMapper.queryStudentByStuno(2);
        Student student2 = studentMapper.queryStudentByStuno(2);
        
        //增删改操作...
        session.commit();
        Student student3 = studentMapper.queryStudentByStuno(2);
        
        System.out.println(student.getStuName());
        System.out.println(student2.getStuName());
        System.out.println(student3.getStuName());
        session.close();




结果:
DEBUG [main] - ==>  Preparing: select * from student1 where stuno=2 
DEBUG [main] - ==> Parameters: 
DEBUG [main] - <==      Total: 1
DEBUG [main] - ==>  Preparing: select * from student1 where stuno=2 
DEBUG [main] - ==> Parameters: 
DEBUG [main] - <==      Total: 1
ls
ls
ls

  二级缓存:

      Mybatis自带二级缓存:同一个namespace生成的XxxMapper对象

      MyBatis默认关闭二级缓存,需要手工打开

回顾:namespace的值就是接口的全类名(包名、类名),通过接口可以产生代理对象(Mapper对象)

    -->namespace决定了Mapper对象的产生

  结论:只要产生的xxxMapper对象来自于同一个namespace,则这些对象共享二级缓存。

如果是同一个SqlSession对象进行多次相同的查询,则直接进入一级缓存查询

如果不是同一个SqlSession对象进行多次相同的查询(但是均来自于同一个namespace),则进入二级缓存查询

     // Connection - SqlSession操作Mybatis
        // conf.xml->reader
        Reader reader = Resources.getResourceAsReader("conf.xml");
        // reader->sqlSession

        // 可以通过build的第二参数 指定数据库环境
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader, "development");
        
        
        //第一次查询
        SqlSession session = sessionFactory.openSession();
        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        
        Student student = studentMapper.queryStudentByStuno(2);
        
        //第二次查询
        SqlSession session2 = sessionFactory.openSession();
        StudentMapper studentMapper2 = session2.getMapper(StudentMapper.class);
        
        Student student2 = studentMapper2.queryStudentByStuno(2);
        
        
        System.out.println(student.getStuName());
        System.out.println(student2.getStuName());
        session.close();
     session2.close(); 结果: DEBUG [main]
- Opening JDBC Connection DEBUG [main] - Created connection 481511146. DEBUG [main] - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@1cb346ea] DEBUG [main] - ==> Preparing: select * from student1 where stuno=2 DEBUG [main] - ==> Parameters: DEBUG [main] - <== Total: 1 DEBUG [main] - Opening JDBC Connection DEBUG [main] - Created connection 1060042118. DEBUG [main] - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@3f2ef586] DEBUG [main] - ==> Preparing: select * from student1 where stuno=2 DEBUG [main] - ==> Parameters: DEBUG [main] - <== Total: 1 ls ls 原因:未开启二级缓存

 

      手工开启二级缓存:

  a./MyBatisProject3/src/conf.xml


        "cacheEnabled" value="true"/>

 

  b.在具体的mapper.xml中声明开启

  /MyBatisProject3/src/org/myy/mapper/studentMapper.xml 


    

根据异常提示java.io.NotSerializableException: 可知,MyBatis缓存是将对象放入硬盘文件中

  ->准备缓存的对象,必须实现了序列化接口(如果开启的缓存namespace="org.myy.mapper.StudentMapper")

  可知序列化对象为Student,因此需要将Student序列化(序列化Student类,以及Student的级联属性和父类

public class Student implements Serializable
...

 

  序列化:内存->硬盘

  反序列化:硬盘->内存

触发将对象写入二级缓存的时机:SqlSession对象的close()方法

     // Connection - SqlSession操作Mybatis
        // conf.xml->reader
        Reader reader = Resources.getResourceAsReader("conf.xml");
        // reader->sqlSession

        // 可以通过build的第二参数 指定数据库环境
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader, "development");
        
        
        //第一次查询
        SqlSession session = sessionFactory.openSession();
        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        
        Student student = studentMapper.queryStudentByStuno(2);
        
        session.close();//触发将对象写入二级缓存的时机
        //第二次查询
        SqlSession session2 = sessionFactory.openSession();
        StudentMapper studentMapper2 = session2.getMapper(StudentMapper.class);
        
        Student student2 = studentMapper2.queryStudentByStuno(2);
        
        
        System.out.println(student.getStuName());
        System.out.println(student2.getStuName());
        
        
        
        
        session2.close();

结果:

DEBUG [main] - Cache Hit Ratio [org.myy.mapper.StudentMapper]: 0.0
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 997850486.
DEBUG [main] - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@3b79fd76]
DEBUG [main] - ==> Preparing: select * from student1 where stuno=2
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 1
DEBUG [main] - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@3b79fd76]
DEBUG [main] - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@3b79fd76]
DEBUG [main] - Returned connection 997850486 to pool.
DEBUG [main] - Cache Hit Ratio [org.myy.mapper.StudentMapper]: 0.5
ls
ls

 

 注意:二级缓存的范围是同一个namespace,如果有多个xxMapper.xml的namespace值相同,则通过这些xxxMapper.xml产生的xxMapper对象仍然共享二级缓存

  禁用:select标签中useCache="false"

<select id="queryStudentByStuno" parameterType="int" resultMap="studentMapping" useCache="false">
        select * from student1 where stuno=${value}
    select>

 

  清理:a.与清理一级缓存的方法相同

      commit();(一般执行增删改时,会清理掉缓存,设计的原因:是为了防止脏数据)

      在二级缓存中,commit()不能时查询自身的commit。

      commit会清理一级和二级缓存,但是清理二级缓存时,不能是查询自身的commit();

     b.在select标签中增加属性flushCache="true"

<select id="queryStudentByStuno" parameterType="int" resultMap="studentMapping" useCache="true" flushCache="true">
        select * from student1 where stuno=${value}
    select>

 

  命中率:1:0.0

      2:0.5

      3:0.6666666

      4.0.75  

DEBUG [main] - Cache Hit Ratio [org.myy.mapper.StudentMapper]: 0.0
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 997850486.
DEBUG [main] - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@3b79fd76]
DEBUG [main] - ==>  Preparing: select * from student1 where stuno=2 
DEBUG [main] - ==> Parameters: 
DEBUG [main] - <==      Total: 1
DEBUG [main] - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@3b79fd76]
DEBUG [main] - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@3b79fd76]
DEBUG [main] - Returned connection 997850486 to pool.
DEBUG [main] - Cache Hit Ratio [org.myy.mapper.StudentMapper]: 0.5
ls
ls
DEBUG [main] - Cache Hit Ratio [org.myy.mapper.StudentMapper]: 0.6666666666666666
DEBUG [main] - Cache Hit Ratio [org.myy.mapper.StudentMapper]: 0.75

 

 

  三方提供的二级缓存

    ehcache、mecache

    想要整合三方提供的二级缓存(或者自定义二级缓存),必须实现org.apache.ibatis.cache.Cache接口,该接口的默认实现类是PerpetCache

    整合ehcache二级缓存:

    a.添加jar包

    Ehcache-core.jar

    mybatis-Ehcache.jar

    slf4j-api.jar

    b.编写ehcache配置文件 Ehcache.xml

"1.0" encoding="UTF-8"?>
"http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">
    
    "D:\test\Ehcache"/>
    
    
<defaultCache
        
        maxElementsInMemory="10000"
        maxElementsOnDisk="1000000"
        eternal="false"
        overflowToDisk="false"
        timeToIdleSeconds="100"
        timeToLiveSeconds="100"
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU"/>

<cache
        name="cloud_user"
        eternal="false"
        maxElementsInMemory="5000"
        overflowToDisk="false"
        diskPersistent="false"
        timeToIdleSeconds="1800"
        timeToLiveSeconds="1800"
        memoryStoreEvictionPolicy="LRU"/>
 

 

  c.开启EhCache二级缓存

/MyBatisProject3/src/Ehcache.xml

"org.mybatis.caches.ehcache.EhcacheCache">
    
        "maxElementsInMemory" value="1000"/>
    

 

2.逆向工程

  表、类、接口、mapper.xml四者密切相关,因此当知道一个的时候,其他三个应该可以自动生成。

  表->其他三个

  a.mybatis-generaotr-core.jar、mybatis.jar、ojdbc.jarS

  b.逆向工程的配置文件generator.xml

/MyBatisgenerator/src/generator.xml

"1.0" encoding="UTF-8"?>
DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

   "DB2Tables" targetRuntime="MyBatis3">
   
   
  "suppressAllComments" value="true" />
 
 
 
 
  "oracle.jdbc.OracleDriver"
   connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:mldn" 
   userId="scott"  password="tiger">
  
  
 
      "forceBigDecimals" value="false" />
 
 
 "org.myy.entity"
                            targetProject=".\src">
  
  "trimStrings" value="true" />
 
 
  "org.myy.mapper" 
            targetProject=".\src">
  
  
 "XMLMAPPER" targetPackage="org.myy.mapper" targetProject=".\src">
 
 
 
  "Student1"> 
"studentCard">
"studentClass">

/MyBatisgenerator/src/org/myy/test/Test.java

package org.myy.test;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;


public class Test {
    public static void main(String[] args) throws Exception, XMLParserException {
        
        File file=new File("src/generator.xml");//配置文件
        
        List warnings=new ArrayList();
        ConfigurationParser cp=new ConfigurationParser(warnings);
        
        Configuration config=cp.parseConfiguration(file);
        
        DefaultShellCallback callback=new DefaultShellCallback(true);
        
        //逆向工程的核心类
        MyBatisGenerator generator=new MyBatisGenerator(config,callback,warnings);
        generator.generate(null);
    }
}

 

你可能感兴趣的:(查询缓存&&逆向工程)