1. SqlSessionFactoryBuilder負責構建SqlSessionFactory,而且提供了多個build()方法的重載。也就是說:此對象能夠從xml配置文件,或從Configuration對象來構建SqlSessionFactory。
2. SqlSessionFactory就是建立SqlSession實例的工廠。經過openSession方法來獲取SqlSession對象。並且,SqlSessionFactory一旦被建立,那麼在整個應用程序期間都存在。
3. SqlSession是一個面向程序員的接口,它提供了面向數據庫執行sql命令所需的全部方法。SqlSession對應一次數據庫會話,它是線程不安全的。html
MyBatis開發DAO層有兩種方式:java
按照JDBC課程中封裝dao層的方式,咱們能夠先封裝一個 Util 工具類,在此工具類中封裝一個獲取SqlSessionFactory的方法。而後建立dao接口和實現類。
SqlSessionFactory工具類:程序員
package com.neusoft.util; import java.io.IOException; import java.io.Reader; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class Util { public static SqlSessionFactory sqlSessionFactory = null; public static SqlSessionFactory getSqlSessionFactory() { if(sqlSessionFactory==null){ String resource = "mybatis/SqlMapConfig.xml"; try { Reader reader = Resources.getResourceAsReader(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); } catch (IOException e) { e.printStackTrace(); } } return sqlSessionFactory; } }
dao接口:web
package com.neusoft.dao; import java.util.List; import com.neusoft.po.Emp; public interface EmpDao { public Emp getEmpById(int empno); public List<Emp> listEmp(); }
dao的實現類:sql
package com.neusoft.dao.impl; import java.util.List; import org.apache.ibatis.session.SqlSession; import com.neusoft.dao.EmpDao; import com.neusoft.po.Emp; import com.neusoft.util.Util; public class EmpDaoImpl implements EmpDao{ @Override public Emp getEmpById(int empno){ SqlSession sqlSession = Util.getSqlSessionFactory().openSession(); Emp emp = sqlSession.selectOne("emp.getEmpById",empno); sqlSession.close(); return emp; } @Override public List<Emp> listEmp(){ SqlSession sqlSession = Util.getSqlSessionFactory().openSession(); List<Emp> list = sqlSession.selectList("emp.listEmp"); sqlSession.close(); return list; } }
測試:數據庫
EmpDao dao = new EmpDaoImpl(); Emp emp = dao.getEmpById(7369); System.out.println(emp); List<Emp> list = dao.listEmp(); for(Emp emp : list) { System.out.println(emp); }
從上面代碼中能夠發現,使用原始dao方式存在不少問題:apache
只須要mapper接口和mapper.xml映射文件,Mybatis能夠自動生成mapper接口實現類代理對象。編mapper接口須要遵循4個一致數組
- Mapper映射文件的名字和mapper接口的名字一致
- Mapper映射文件中statementId的值,與mapper接口中對應的方法名一致
- Mapper映射文件中statement的輸入參數parameterType的類型,與mapper接口中對應方法的參數類型一致。
- Mapper映射文件中statement的輸出參數resultType的類型,與mapper接口中對應方法的返回值類型一致
解釋一下:緩存
第一個一致:
並且前面學習提到過,xml映射文件的namespace屬性的取值問題,當使用原始dao開發時,能夠隨意取值;使用mapper代理開發時,取值爲mapper接口的全路徑
安全
第二個一致:方法名一致
第三個一致:輸入類型一致
第四個一致:輸出類型一致
還要記得在SqLMapConfig中註冊映射文件
優化:
若是映射文件與mapper接口名稱一致,且處在同一個文件夾內,那麼就可使用接口來批量加載映射文件。
注意一個是「/」,一個是「.」
在第四個一致中,xml文件中的輸出類型寫的很長,也能夠進行簡化,一樣在SqlMapConfig中
代碼:
<?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"> <!-- namespace屬性: 如今能夠隨意給值 ,但當使用mapper代理方式開發時,有特色的取值。即爲mapper接口的全路徑--> <!-- 1. Mapper映射文件的名字和mapper接口的名字一致--> <!-- 2. Mapper映射文件中statementId的值,與mapper接口中對應的方法名一致--> <!-- 3. Mapper映射文件中statement的輸入參數parameterType的類型,與mapper接口中對應方法的參數類型一致。--> <!-- 4. Mapper映射文件中statement的輸出參數resultType的類型,與mapper接口中對應方法的返回值類型一致--> <mapper namespace="com.neuedu.mapper.EmpMapper"> <!-- 按id查詢員工 --> <select id="findEmpById" parameterType="int" resultType="Employee"> <!-- id就是這條語句的惟一標識,parameterType是員工id的屬性,resultType是返回類型,要把實體類的路徑寫完整 --> select * from tb_emp where id = #{value} <!-- 佔位符要使用#{} parameterType的類型若是爲 簡單類型(基本類型和String),#{}中的值任意。--> </select> <!-- 按名稱模糊查詢,當查詢結果有多個時,resultType的類型爲pojo--> <select id="findEmpByName" parameterType="string" resultType="Employee"> <!-- 不使用拼接,要在test中加% --> SELECT * FROM tb_emp WHERE NAME LIKE #{value} <!-- 字符串拼接的方法。注意:慎用,會產生sql注入。--> <!-- SELECT * FROM tb_emp WHERE NAME LIKE '%${value}%'--> </select> <!-- 刪除員工 --> <delete id="deleteEmp" parameterType="int"> delete from tb_emp where id=#{value} </delete> <!-- 更新員工--> <!-- 若是輸入參數爲pojo類型,#{pojo對象的屬性名} --> <update id="editEmp" parameterType="com.neuedu.pojo.Employee"> update tb_emp set loginName=#{loginName},name=#{name},email=#{email}, status=#{status},deptId=#{deptId},photoPath=#{photoPath} where id=#{id} </update> <!-- 插入員工 --> <insert id="saveEmp" parameterType="com.neuedu.pojo.Employee"> INSERT INTO tb_emp (loginname,PASSWORD,NAME,hiredate,email,photopath,deptId) VALUES (#{loginName},#{password},#{name},#{hiredate},#{email},#{photoPath},#{deptId}) <!-- order: 執行時機 keyColumn:表中自動名稱 keyProperty:映射的pojo屬性名稱 --> <selectKey order="AFTER" resultType="int" keyColumn="id" keyProperty="id"> SELECT LAST_INSERT_ID() </selectKey> </insert> </mapper>
package com.neuedu.mapper; import java.util.List; import com.neuedu.pojo.Employee; public interface EmpMapper { /** * 登陸方法 * @param loginName 登陸名 * @param password 密碼 * @return 登陸員工的信息 */ Employee login(String loginName, String password); /** * 添加員工 * @param emp 插入信息 */ void saveEmp(Employee emp); /** * 刪除員工 * @param id 員工id */ void deleteEmp(Integer id); /** * 修改員工 * @param emp 員工信息 */ void updateEmp(Employee emp); /** * 按id查詢 * @param id 員工id * @return 員工信息 */ Employee findEmpById(Integer id); /** * 按照name查詢 * @param name 員工姓名 * @return 員工列表 */ Employee findEmpByName(String name); }
package com.neuedu.test; import com.neuedu.mapper.EmpMapper; import com.neuedu.pojo.Employee; import com.neuedu.utils.DBUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; public class TestMyMapper { @Test public void testFindById() { SqlSession session = DBUtils.getSession(); EmpMapper empMapper = session.getMapper(EmpMapper.class); Employee emp = empMapper.findEmpById(2); System.out.println(emp.getName()); session.close(); } }
parameterType 屬性:表示執行sql語句時,須要使用的數據。
在statement語句中#{}
的值能夠任意
輸入參數爲pojo類型,#{}
中的值爲pojo對象的屬性名
需求查找員工所在的部門名稱
問題提出:員工表emp中沒有部門名的字段,須要聯合到部門表dept;即Employee實體類沒法知足需求
解決方法:
在包裝POJO類中,關聯多個POJO對象,好比按照上例能夠把emp和dept聯合起來組成EmpDept類;
sql語句
寫sql語句時輸入類型也能夠直接用:
注意#{}裏面的值,empdept裏沒有name屬性只有emp與dept,可是能夠用emp與dept來訪問他們的name
測試
寫測試的時候會複雜一點
在接口中加入方法
若是resultType爲簡單類型,查詢結果必須爲一個值。一行一列。
四個一致:在接口中定義方法
測試方法
若是select語句使用投影查詢時。即查詢列表只定義表中部分字段。
此時結果中只會封裝查詢列表中有的字段,查詢列表中沒有的字段,輸出參數pojo屬性值爲默認值
Employee中的全部屬性
寫一個投影查詢
能夠看出查詢語句並無把全部的屬性都查出來
接口定義方法:
在Employee.java實體類中加入一個tostring方法,只選取部分數據庫中的字段:
測試:
輸出結果:
一樣能映射成功。
思考:此時用的是表中字段的名字與屬性映射仍是用的查詢列表的名字與屬性映射?
驗證:
在查詢列表中起別名再測試
結果:
email爲空。
說明輸出參數進行映射時,是使用的查詢列表的別名和pojo屬性名進行映射,若是字段別名和pojo屬性名不對應,則會映射失敗
把全部的都起別名,只剩下id能對應上
結果:
結論:即便只有一個屬性能對應,也會建立pojo對象
若是全部的都對應不上呢?
結果:
不報錯,輸出爲空。
結論:全部屬性都對應不上則不會建立pojo對象
若是必需要起別名來查詢,怎麼解決?
能夠利用resultMap
在statement語句中把resultType的位置寫爲resultMap
- resultMap是一個標籤,每個statement語句都會根據標籤的id去找他的映射類型,上例中的類型就是Employee,有不一樣的對應不上的本身定義。
<id>
普通屬性映射用<result>
再次測試:
email映射成功
可是resultMap的主要做用是實現關聯映射,在後續會學到
運用:條件查詢
在前幾天j學習aveweb時用servlet寫條件查詢時,寫了一個"1=1",再鏈接其餘的條件
測試
優化:放在<where>
標籤裏面,<if>
語句會加上and
測試能成功,可是發現sql語句中沒有了and
解釋:where標籤會爲sql語句添加where字句,同時會去掉第一個條件前面的and,因此放心的加and,無論哪條語句是第一個條件都會自動去掉前面的and。
把全部條件去掉
測試:
全部條件都不知足where天然也就不起做用了
第二個sql語句:
在接口類中定義:
測試:
結果:
都沒什麼問題。
重點是兩個語句的where標籤中的語句是如出一轍的,就是說這段代碼能夠複用,那就能夠封裝起來。
把重複代碼寫在<sql>
標籤內
在statement中用<include>
來包含<sql>
語句
注意:
改進:把sql片斷的where刪除
在<include>
前加上<where>
,
用於批量刪除。
輸入參數中,應該包含一個數組(List)類型的數據,該數據包含要刪除的全部id。
此時輸入參數爲pojo,即Employee。須要擴展屬性,添加一個int[] ids屬性
刪除語句
測試
結果
對比着理解sql的書寫:
參數的含義:
tem表示集合中每個元素進行迭代時的別名
index指定一個名字,用於表示在迭代過程當中,每次迭代到的位置
open表示該語句以什麼開始
separator表示在每次進行迭代之間以什麼符號做爲分隔符
close表示以什麼結束
第二條的書寫
遇到and與or時,and的優先級更高,因此能夠在or的語句外加一個"()"
sql語句中,除了上面用到的幾個子標籤,還有其餘的
choose:多條件判斷,按順序判斷其內部when標籤中的test條件出否成立,若是有一個成立,則 choose 結束。
當 choose 中全部 when 的條件都不滿則時,則執行 otherwise 中的sql。
相似於Java 的 switch 語句,choose 爲 switch,when 爲 case,otherwise 則爲 default。
trim:插入數據,動態拼接insert語句.主要功能是能夠在本身包含的內容前加上某些前綴,也能夠在其後加上某些後綴,與之對應的屬性是prefix和suffix
能夠把包含內容的首部某些內容覆蓋,即忽略,也能夠把尾部的某些內容覆蓋,對應的屬性是prefixOverrides和suffixOverrides;
幫助咱們去除末尾的「,」並填上「()」。
(當前階段只是瞭解)
Mybatis提供了一個項目,能夠經過數據庫中的表自動導出對應的pojo、mapper.xml、mapper.java。逆向工程只適合單表操做。
如下圖的電商業務爲例,查詢名叫張三的人買過哪些東西,就須要多表查詢
數據庫表詳情:
需求:查詢訂單關聯的用戶
測試
結果
沒什麼問題,可是當業務需求愈來愈多,須要的包裝的pojo就會愈來愈多,與數據庫無關的實體類愈來愈多,致使系統維護起來很麻煩
準備工做:在pojo的order類中加入user,即定義關聯字段並提供get與set
查詢語句
resultMap進行映射
- resultMap的type屬性即爲select語句的輸出類型,即爲order(進行了打包,完整路徑爲com.nenedu.pojo.Order)
- 先對order類中自己有的屬性進行映射,主鍵用
<id>
,普通屬性用<result>
- 再對order類中加入的User進行映射,一對一映射用
<association>
,其中的JavaType表示關聯屬性的類型,即爲User(com.neuedu.pojo.User)- 細心,一個屬性一個屬性的來。
接口方法
測試
結果與resultTyoe相同。
注意其結構類型:
需求:查詢用戶及其關聯的全部訂單
要在User類中關聯訂單order的類型,訂單有不少,採用list
查詢語句
resultMap進行映射
- 先映射User自己的屬性,再映射關聯屬性
- 一對多的關聯屬性用collection,使用ofType屬性,他表示集合中存放的對象的類型(泛型屬性)
- JavaType表示的是關聯屬性的類型,但在user中關聯的是list,咱們須要的是list內部的對象的屬性
接口方法:
測試:
結果:
需求:查詢劉備的信息及其購買過的商品信息
sql語句:
關聯了4個表,主表爲User
在以前例子的基礎上再往order表中關聯訂單明細OrderDetail,一個訂單有多個明細用list;訂單明細表OrderDetail中關聯商品Item,一個明細只針對一個商品.
關聯環爲:User->Order->OrderDetail->Item
查詢語句
接口方法:
叫劉備的可能有不少,用list裝起來。
resultMap進行映射
<resultMap type="user" id="findUserAndItemMap"> <!-- user表 --> <id column="uid" property="id"/> <result column="uname" property="name"/> <!-- 一對多 <list>order表 --> <collection property="orderList" ofType="Order"> <id column="oid" property="id"/> <result column="orderNum" property="orderNum"/> <result column="uid" property="userId"/> <!-- 一對多 <list>orderdetail表 --> <collection property="detailList" ofType="orderDetail"> <id column="oid" property="orderId"/> <id column="iid" property="itemId"/> <result column="count" property="count"/> <!-- 一對一 item表 --> <association property="item" javaType="item"> <id column="iid" property="id"/> <result column="iname" property="name"/> </association> </collection> </collection> </resultMap>
每一個表看清楚映射的單個(association)仍是多個(collection),找好每一個表的屬性,一步一步來就不容易錯
測試:
結果:
使用resultMap實現關聯映射時:
- 使用association標籤完成多對一或一對一映射。
a. association標籤:將關聯查詢信息映射到一個po對象中。
b. association標籤中的javaType屬性:表示該po對象的類型。
c. association標籤中的select屬性:表示應用哪個關聯查詢。
d. association標籤中的column屬性:表示應用關聯查詢的條件。- 使用collection標籤完成一對多,多對多映射。
a. collection標籤:將關聯查詢信息映射到一個list集合中。
b. collection標籤的ofType屬性:表示該集合中的元素對象的類型。
c. collection標籤中的select屬性:表示應用哪個關聯查詢。
d. collection標籤中的column屬性:表示應用關聯查詢的條件。
延遲加載:執行查詢時,關聯查詢不會當即加載。只有在使用關聯數據時纔會加載。
1. 優勢:按需加載,提升效率。
2. 具備關聯關係的對象纔會存在延遲加載
3. 例如:查詢訂單關聯用戶。默認當查詢訂單信息時,會當即加載關聯的用戶信息。若是程序中只須要使用訂單信息,而不須要使用關聯的用戶信息,則當即加載關聯的用戶信息就沒有必要。能夠對訂單關聯的用戶信息實現延遲加載,即便用到用戶信息是再加載,不用就不加載,提供系統的執行效率。
4. 在mybatis中,只有association、collection標籤具備延遲加載的功能。
注意: 要使用關聯查詢的延遲加載,就必需要使用單獨查詢形式。而且,須要先啓用MyBatis的延遲加載配置(須要配置兩項):
<!-- 若是aggressiveLazyLoading爲true,那麼lazyLoadingEnabled即便爲true也無效。 --> <settings> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings>
查詢語句
在UserMapper.xml
中有語句:
<select id="findUserById" parameterType="int" resultType="user"> select id,name from users where id=#{value} </select>
在OrderMapper.xml
有語句:
<!-- 查詢訂單關聯用戶lazy --> <resultMap type="Order" id="findOrderAndUserLazyMap"> <id column="id" property="id"/> <result column="orderNum" property="orderNum"/> <result column="userId" property="userId"/> <!-- 映射關聯屬性 --> <!-- select 屬性 調用已經存在的statement --> <association property="user" select="com.neuedu.mapper.UserMapper.findUserById" column="userId"></association> </resultMap> <select id="findOrderAndUserLazy" parameterType="string" resultMap="findOrderAndUserLazyMap"> SELECT id,orderNum,userId FROM orders WHERE orderNum = #{orderNum } </select>
調用了在另外一個xml文件的查詢語句,用到的時候才執行。
進行斷點測試:
- 第一條語句執行的時候,user的值爲空,第二條語句沒有加載執行;
- 執行到session.commit();發送了數據,user中也有值
註釋掉一條語句測試:
結果:只發送了一條數據,也只執行了一條語句
可是在配置文件中將lazyLoadingEnabled
的true改成false,即便註釋了語句也仍是會加載
確認了mybatis默認是當即加載的。
在上面的開發過程當中咱們用的都是映射文件開發,就是把查詢語句寫在xml文件當中,而後在接口類中調用。
MyBatis也支持使用註解來配置映射語句。直接把語句寫在接口類中。
記得把文件改一下,已經沒有Employee.xml文件了。
主要有四種註解來實現增刪改查:@Select、@Insert、@Update、@Delete
基礎的書寫以下
package com.neuedu.mapper; import java.util.List; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Select; import com.neuedu.pojo.Employee; public interface EmpMapper { @Select(value="select * from tb_emp where id=#{value}") Employee findEmpById(Integer id); @Select(value="select * from tb_emp where name like '%${value}%'") List<Employee> findEmpByName(String name); void saveEmp(Employee emp); @Delete(value="delete from tb_emp where id=#{value}") void deleteEmp(Integer id); void editEmp(Employee emp); }
測試類:
@Test public void testFindById() throws Exception{ SqlSession session = sf.openSession(); EmpMapper mapper = session.getMapper(EmpMapper.class); mapper.findEmpById(3); session.commit(); session.close(); }
測試一個:
成功。
其餘的如用註解實現動態sql、懶加載等等在這個裏面寫的很是詳細了
參考文檔:mybatis註解開發
Mybatis的一級緩存是SqlSession級別的緩存,每一個SqlSession使用獨立的一級緩存空間。
當執行Mapper接口中方法時,得到一個sqlSession的對象。sqlSession對象線程不安全
每次操做都會使用獨立的sqlSession對象。
當sqlSession對象被建立時,sqlSession對象的內部會開闢一個緩存區域(HashMap)
當經過同一個SqlSession對象進行查詢操做時。一級緩存會起做用。
Mybatis默認是開啓一級緩存的,並且不能關閉一級緩存。
當一個sqlSession對象發起了一次查詢操做時,首先會到一級緩存中查找是否存在該對象
若是在緩存中沒有找到對應的對象,則發生sql語句到數據庫中進行查詢。並把查詢到的對象保存到一級緩存中一份
當經過同一個sqlSession對象發起第二次查詢操做時,首先會到一級緩存中查找,若是找到對應的對象,則不會在發送sql語句到數據庫。這樣,能夠提升查詢效率。
在兩次查詢的中間,若是執行了commit操做(update、insert、delete),會清除緩存中的全部數據。
測試
@Test public void testFindUserCache() { SqlSession session = sf.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); //第一次查詢 User u1 = userMapper.findUserById(1);//發送sql u1.setName("tom"); userMapper.modifyUser(u1); session.commit();//清空一級緩存 //第二次查詢 User u2 = userMapper.findUserById(1);//不會發送,使用緩存中的對象 session.close(); SqlSession session2 = sf.openSession(); UserMapper userMapper2 = session2.getMapper(UserMapper.class); User u3 = userMapper2.findUserById(1);//發送sql,新的sqlSession對象,使用新的一級緩存 session2.close(); }
二級緩存就是,Mapper級別的緩存,當不一樣的sqlSession對象訪問同一個Mapper接口中的方法時,會使用到二級緩存。
當使用一個sqlSession對象進行查詢操做時,到二級緩存中查找,若是沒有找到,則發送sql語句到數據庫中查詢,並把查詢結果保存到二級緩存
在兩次查詢過程當中,若是執行了commit操做,則清空二級緩存。
當使用另一個sqlSession對象進行查詢操做時,到二級緩存中查找,若是找到,則不發送sql語句查詢數據庫。
默認mybatis是開啓二級緩存的,但能夠在sqlMapConfig.xml文件中配置二級緩存。
要在須要被緩存的xxxMapper.xml文件中配置,該Mapper使用二級緩存。
測試
第一次查詢時,到二級緩存中查找是否存在對象
緩存命中率。 在緩存中查找對象的命中率。
第二次查詢時,二級緩存中存在對象,則命中率爲0.5
使用二級緩存要注意: 一些異常
被二級緩存緩存的對象,有可能會被執行序列化或反序列化操做,因此 被緩存的對象所屬的類必須支持序列化, 要實現Sericlizable接口。
需求:分佈式系統,系統存在兩個子系統,在一個系統中登陸,在另一個系統上是否也可以使用登陸信息?
引入jar包
<dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.10.3</version> </dependency> <dependency> <groupId>org.mybatis.caches</groupId> <artifactId>mybatis-ehcache</artifactId> <version>1.1.0</version> </dependency>
假日ehcache 實現類
在系統中加入ehcache的配置文件
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <!-- 磁盤的緩存路徑 --> <diskStore path="d:\\ehcache\temp"/> <defaultCache maxElementsInMemory="100" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="1200" maxElementsOnDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> </defaultCache> <!-- Cache配置 · name:Cache的惟一標識 · maxElementsInMemory:內存中最大緩存對象數。 · maxElementsOnDisk:磁盤中最大緩存對象數,如果0表示無窮大。 · eternal:Element是否永久有效,一但設置了,timeout將不起做用。 · overflowToDisk:配置此屬性,當內存中Element數量達到maxElementsInMemory時,Ehcache將會Element寫到磁盤中。 · timeToIdleSeconds:設置Element在失效前的容許閒置時間。僅當element不是永久有效時使用,可選屬性,默認值是0,也就是可閒置時間無窮大。 · timeToLiveSeconds:設置Element在失效前容許存活時間。最大時間介於建立時間和失效時間之間。僅當element不是永久有效時使用,默認是0.,也就是element存活時間無窮大。 · diskPersistent:是否緩存虛擬機重啓期數據。(這個虛擬機是指什麼虛擬機一直沒看明白是什麼,有高人還但願能指點一二)。 · diskExpiryThreadIntervalSeconds:磁盤失效線程運行時間間隔,默認是120秒。 · diskSpoolBufferSizeMB:這個參數設置DiskStore(磁盤緩存)的緩存區大小。默認是30MB。每一個Cache都應該有本身的一個緩衝區。 · memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理內存。默認策略是LRU(最近最少使用)。你能夠設置爲FIFO(先進先出)或是LFU(較少使用)。 --> </ehcache>
應用場景:常常被訪問,但不多被修改。適合進行緩存。 電商系統中的商品信息不適合mybatis緩存。