zoukankan      html  css  js  c++  java
  • 查询缓存&&逆向工程

    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

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

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

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

    <!--声明此namespace开启二级缓存 -->
        <cache />

    根据异常提示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

    <?xml version="1.0" encoding="UTF-8"?>
    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
             updateCheck="false">
        <!--
           diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:
           user.home – 用户主目录
           user.dir  – 用户当前工作目录
           java.io.tmpdir – 默认临时文件路径
           当二级缓存的对象超过内存限制时(缓存对象的个数>maxElementsInMemory),存放入的硬盘文件
         -->
        <diskStore path="D:	estEhcache"/>
        <!--
           defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
         -->
        <!--
          name:缓存名称。
          maxElementsInMemory:设置在内存中缓存对象的最大个数
          maxElementsOnDisk:社渚在硬盘中最大缓存个数。
          eternal:设置缓存是否永远过期,一但设置了,timeout将不起作用。
          overflowToDisk:当内存中缓存的对象个数超过maxElementsInMemory的时候,是否转移到硬盘中
          timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
          timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.也就是对象存活时间无穷大。
          diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
          diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
          diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
          memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
          clearOnFlush:内存数量最大时是否清除。
          memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
          FIFO,first in first out,这个是大家最熟的,先进先出。
          LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
          LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
       -->
    <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"/>
     
    </ehcache>
     

      c.开启EhCache二级缓存

    /MyBatisProject3/src/Ehcache.xml

    <cache type="org.mybatis.caches.ehcache.EhcacheCache">
        <!--通过property覆盖Ehcache.xml中的值  -->
            <property name="maxElementsInMemory" value="1000"/>
        </cache>

    2.逆向工程

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

      表->其他三个

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

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

    /MyBatisgenerator/src/generator.xml

    <?xml version="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">
    <generatorConfiguration>
       <context id="DB2Tables" targetRuntime="MyBatis3">
       <commentGenerator>
       <!--
                suppressAllComments属性值:
                    true:自动生成实体类、SQL映射文件时没有注释
                    true:自动生成实体类、SQL映射文件,并附有注释
              -->
      <property name="suppressAllComments" value="true" />
     </commentGenerator>
     
     
     <!-- 数据库连接信息 -->
      <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
       connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:mldn" 
       userId="scott"  password="tiger">
      </jdbcConnection>
      <!-- 
                forceBigDecimals属性值: 
                    true:把数据表中的DECIMAL和NUMERIC类型,
    解析为JAVA代码中的java.math.BigDecimal类型 
                    false(默认):把数据表中的DECIMAL和NUMERIC类型,
    解析为解析为JAVA代码中的Integer类型 
            -->
     <javaTypeResolver>
          <property name="forceBigDecimals" value="false" />
     </javaTypeResolver>
     <!-- 
            targetProject属性值:实体类的生成位置  
            targetPackage属性值:实体类所在包的路径
        -->
     <javaModelGenerator targetPackage="org.myy.entity"
                                targetProject=".src">
      <!-- trimStrings属性值:
                true:对数据库的查询结果进行trim操作
                false(默认):不进行trim操作       
              -->
      <property name="trimStrings" value="true" />
     </javaModelGenerator>
     <!-- 
            targetProject属性值:SQL映射文件的生成位置  
            targetPackage属性值:SQL映射文件所在包的路径
        -->
      <sqlMapGenerator targetPackage="org.myy.mapper" 
                targetProject=".src">
      </sqlMapGenerator>
      <!-- 生成动态代理的接口  -->
     <javaClientGenerator type="XMLMAPPER" targetPackage="org.myy.mapper" targetProject=".src">
     </javaClientGenerator>
     
     <!-- 指定数据库表  -->
      <table tableName="Student1"> </table>
      <table tableName="studentCard"> </table>
      <table tableName="studentClass"> </table>
     </context>
    </generatorConfiguration>

    /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<String> warnings=new ArrayList<String>();
            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);
        }
    }
  • 相关阅读:
    html的转码玉反转码
    获取url据对路径写法
    CSS 外边距合并
    页面禁制选中元素的 背景变蓝的通用写法
    centos7.3上安装oracle11.2.4RAC
    通过ansible检查所有服务器根目录磁盘使用情况
    解决es集群启动完成后报master_not_discovered_exception(hostname有错误)
    tidb4.0执行大型sql报没有tmp目录错处理(ERROR 1105 (HY000): open /tmp/1000_tidb/MC4wLjAuMDo0MDAwLzAuMC4wLjA6MTAwODA)
    aix磁盘创建pv、lv
    aix6.1安装oracle
  • 原文地址:https://www.cnblogs.com/mayouyou/p/13234591.html
Copyright © 2011-2022 走看看