キャッシュ
MyBatisのキャッシングのサポートを提供しますが、デフォルトで設定されていない、それだけでキャッシュがSQLSESSION同じ条件に対してのみで、キャッシュを開きました。だから、SQLパラメータとまったく同じ状況で、私たちは同じSQLSESSIONマッパーオブジェクトが原因SelSessionを使用して、最初のクエリの後、多くの場合のみSQLたら、メソッドを呼び出して使用し、MyBatisのは、キャッシュ内に後でクエリをそれを置くだろう次回は、声明がない場合は更新する必要はなく、何のキャッシュのタイムアウト状況、SQLSESSIONは、現在のキャッシュされたデータを削除しますが、再度、SQLデータベースに送信されません。
なぜまたについての目安は言うまでもない、キャッシュを使用します。しかし、我々は注意を払う必要がありますいくつかの問題があります。
1、どのくらいのキャッシュのライフサイクル?
、MyBatisのは、データベース・セッションを開くときは、SQLSESSIONオブジェクトは新しいエグゼキュータオブジェクトを持つことになり、新しいSQLSESSIONオブジェクトを作成します。新しいPerpetualCacheオブジェクトを保持するために、エグゼキュータオブジェクト、セッションが終了すると、SQLSESSIONオブジェクトとそのエグゼキュータオブジェクトもPerpetualCacheも解放一緒に内部のオブジェクト。
SQLSESSIONはclose()メソッドを呼び出した場合、B、あなたはキャッシュPerpetualCacheオブジェクトキャッシュは使用できません解放することができます。
Cは、clearCache SQLSESSIONコール()ように、PerpetualCacheは、データオブジェクトを洗浄するが、オブジェクトはまだ使用することができます。
いずれか(、)(挿入、更新()、DELETE())の更新動作を行うD、SQLSESSION、データはPerpetualCacheオブジェクトがクリアされるが、オブジェクトが使用し続けることができ
2、クエリが正確に二度同じクエリであるかを判断するには?
次の条件が全く同じであれば二回のクエリのために、その後、彼らは二回まったく同じクエリであることを、ことMyBatisの。
2.1着信STATEMENTID
検索結果の2.2クエリ結果セットの要件
2.3。問い合わせは、最終的にはJDBCのjava.sql.PreparedStatementのSQL文の文字列に渡されるようになった(boundSql.getSql())
2.4 java.sql.Statementのを設定するには、渡されたパラメータ値を
二次キャッシュ:
MyBatisの二次キャッシュは、それが、データベースクエリの効率を向上させることができ、アプリケーションのパフォーマンスを改善するために、アプリケーションレベルのキャッシュです。
MyBatisのキャッシュ・メカニズムと二次キャッシュの動作モードの全体的なデザイン
デフォルトのレベルでSqlSessionFactory二次キャッシュがオンにされていない、オープン席の二次キャッシュを構成する必要が二次キャッシュを実装する場合、MyBatisのはPOJOの要件をシリアル化する必要があります返されました。これはSerializableインタフェースを実装する必要があり、設定は非常に簡単ですが、単にキャッシュを開くには、マッピングXMLファイルで設定することができます。<キャッシュ/>私たちは、二次キャッシュを設定した場合、意味:
- マップされたステートメントのファイルのすべてのselect文がキャッシュされます。
- 所望の挿入マッピングされた文ファイル、更新し、キャッシュをフラッシュします文を削除します。
- キャッシュは、立ち退きのために(最低使用LRU)最低使用デフォルトのアルゴリズムを使用しています。
- こうしたノーフラッシュ間隔、(CNFI間隔をリフレッシュしない)などのスケジュールによると、キャッシュがリフレッシュする時間の任意の並べ替えはできません。
- キャッシュは、1024参照のリストまたはオブジェクト(どんなクエリメソッドが返す)を格納します
- キャッシュが共有されていない取得したオブジェクトを意味し、リード/ライトキャッシュ(リード/ライト)として処理され、安全に発呼者によって変更することができ、発信者が作ら他の潜在的な変更またはスレッドを妨害しません。
実践:
まず、POJOビーンとシリアライズを作成
二次キャッシュデータが必ずしもメモリに格納されていないので、オブジェクト・キャッシュは、シリアル化を実行する必要があるので、その記憶媒体には、変化しました。メモリに格納されている場合(それはないシリアライズに見出すことができます。
package com.yihaomen.mybatis.model; import com.yihaomen.mybatis.enums.Gender; import java.io.Serializable; import java.util.List; /** * @ProjectName: springmvc-mybatis */ public class Student implements Serializable{ private static final long serialVersionUID = 735655488285535299L; private String id; private String name; private int age; private Gender gender; private List<Teacher> teachers; setters&getters()....; toString(); }
二、在映射文件中开启二级缓存
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.yihaomen.mybatis.dao.StudentMapper"> <!--开启本mapper的namespace下的二级缓存--> <!-- eviction:代表的是缓存回收策略,目前MyBatis提供以下策略。 (1) LRU,最近最少使用的,一处最长时间不用的对象 (2) FIFO,先进先出,按对象进入缓存的顺序来移除他们 (3) SOFT,软引用,移除基于垃圾回收器状态和软引用规则的对象 (4) WEAK,弱引用,更积极的移除基于垃圾收集器状态和弱引用规则的对象。这里采用的是LRU, 移除最长时间不用的对形象 flushInterval:刷新间隔时间,单位为毫秒,这里配置的是100秒刷新,如果你不配置它,那么当 SQL被执行的时候才会去刷新缓存。 size:引用数目,一个正整数,代表缓存最多可以存储多少个对象,不宜设置过大。设置过大会导致内存溢出。 这里配置的是1024个对象 readOnly:只读,意味着缓存数据只能读取而不能修改,这样设置的好处是我们可以快速读取缓存,缺点是我们没有 办法修改缓存,他的默认值是false,不允许我们修改 --> <cache eviction="LRU" flushInterval="100000" readOnly="true" size="1024"/> <resultMap id="studentMap" type="Student"> <id property="id" column="id" /> <result property="name" column="name" /> <result property="age" column="age" /> <result property="gender" column="gender" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler" /> </resultMap> <resultMap id="collectionMap" type="Student" extends="studentMap"> <collection property="teachers" ofType="Teacher"> <id property="id" column="teach_id" /> <result property="name" column="tname"/> <result property="gender" column="tgender" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/> <result property="subject" column="tsubject" typeHandler="org.apache.ibatis.type.EnumTypeHandler"/> <result property="degree" column="tdegree" javaType="string" jdbcType="VARCHAR"/> </collection> </resultMap> <select id="selectStudents" resultMap="collectionMap"> SELECT s.id, s.name, s.gender, t.id teach_id, t.name tname, t.gender tgender, t.subject tsubject, t.degree tdegree FROM student s LEFT JOIN stu_teach_rel str ON s.id = str.stu_id LEFT JOIN teacher t ON t.id = str.teach_id </select> <!--可以通过设置useCache来规定这个sql是否开启缓存,ture是开启,false是关闭--> <select id="selectAllStudents" resultMap="studentMap" useCache="true"> SELECT id, name, age FROM student </select> <!--刷新二级缓存 <select id="selectAllStudents" resultMap="studentMap" flushCache="true"> SELECT id, name, age FROM student </select> --> </mapper>
三、在 mybatis-config.xml中开启二级缓存
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <!--这个配置使全局的映射器(二级缓存)启用或禁用缓存--> <setting name="cacheEnabled" value="true" /> ..... </settings> .... </configuration>
四、测试
package com.yihaomen.service.student; import com.yihaomen.mybatis.dao.StudentMapper; import com.yihaomen.mybatis.model.Student; import com.yihaomen.mybatis.model.Teacher; import com.yihaomen.service.BaseTest; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import java.util.List; /** * * @ProjectName: springmvc-mybatis */ public class TestStudent extends BaseTest { public static void selectAllStudent() { SqlSessionFactory sqlSessionFactory = getSession(); SqlSession session = sqlSessionFactory.openSession(); StudentMapper mapper = session.getMapper(StudentMapper.class); List<Student> list = mapper.selectAllStudents(); System.out.println(list); System.out.println("第二次执行"); List<Student> list2 = mapper.selectAllStudents(); System.out.println(list2); session.commit(); System.out.println("二级缓存观测点"); SqlSession session2 = sqlSessionFactory.openSession(); StudentMapper mapper2 = session2.getMapper(StudentMapper.class); List<Student> list3 = mapper2.selectAllStudents(); System.out.println(list3); System.out.println("第二次执行"); List<Student> list4 = mapper2.selectAllStudents(); System.out.println(list4); session2.commit(); } public static void main(String[] args) { selectAllStudent(); } }