1. 程式人生 > 其它 >Thinkphp 6.0 layout公共模板使用

Thinkphp 6.0 layout公共模板使用

Mybatis

官網:https://mybatis.org/mybatis-3/

1. 簡介

MyBatis 是一款優秀的持久層框架,它支援自定義 SQL、儲存過程以及高階對映。MyBatis 免除了幾乎所有的 JDBC 程式碼以及設定引數和獲取結果集的工作。MyBatis 可以通過簡單的 XML 或註解來配置和對映原始型別、介面和 Java POJO(Plain Old Java Objects,普通老式 Java 物件)為資料庫中的記錄。

依賴jar包

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>

2. 持久化

持久化就是將程式的資料在持久狀態和瞬時狀態下的轉換

對應生活的例子

​ 罐頭,冷藏

3. 為什麼使用Mybatis

  • 方便
  • 簡化jdbc程式碼
  • 幫助程式設計師將資料存到資料庫中
  • 簡單易學:本身就很小且簡單。沒有任何第三方依賴,最簡單安裝只要兩個jar檔案+配置幾個sql對映檔案易於學習,易於使用,通過文件和原始碼,可以比較完全的掌握它的設計思路和實現。
  • 靈活:mybatis不會對應用程式或者資料庫的現有設計強加任何影響。 sql寫在xml裡,便於統一管理和優化。通過sql語句可以滿足操作資料庫的所有需求。
  • 解除sql與程式程式碼的耦合:通過提供DAO層,將業務邏輯和資料訪問邏輯分離,使系統的設計更清晰,更易維護,更易單元測試。sql和程式碼的分離,提高了可維護性。
  • 提供對映標籤,支援物件與資料庫的orm欄位關係對映
  • 提供物件關係對映標籤,支援物件關係組建維護
  • 提供xml標籤,支援編寫動態sq

4. 第一個Mybatis程式

配置mybatis配置檔案

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=true&amp;serverTimezone=Asia/Shanghai"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

編寫工具類

public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static{
       try {
           String resource = "mybatis-config.xml";
           InputStream inputStream = Resources.getResourceAsStream(resource);
           sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
       } catch (IOException e) {
           e.printStackTrace();
       }
   }


   //獲取openSession
   public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

編寫測試環境

dao UserMapper

pojo User

編寫 UserMapper.xml

<?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.immortal.dao.UserMapper">
<!-- 查詢語句-->
    <select id="getUserList" resultType="com.immortal.pojo.User">
        select * from mybatis.user
  </select>
</mapper>

注意點

org.apache.ibatis.binding.BindingException: Type interface com.immortal.dao.UserMapper is not known to the MapperRegistry

沒有註冊到mapper的註冊中心裡面區 ,就是mybatis的核心配置檔案

解決:

重新測試

初始化異常 失敗

Cause: java.io.IOException: Could not find resource com.immortal.dao.UserMapper.xml

沒有找到這個UserMapper.xml maven的靜態資源過濾問題

解決:

  <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

junit 測試

public class Test {

@org.junit.Test
public void TestSelect(){
    //獲得SqlSession
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    //獲取Mapper
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    //呼叫介面的方法
    List<User> userList = userMapper.getUserList();
    //遍歷
    for (User user : userList) {
        System.out.println(user);
    }
    //關閉連線
    sqlSession.close();
}

5. CRUD

mamespace中的包名要和介面名字一致

Select

  • id 就是對應的方法名
  • resultType sql語句執行的返回值
  • paramterType 引數的型別

  <select id="getUserList" resultType="com.immortal.pojo.User">
      select * from mybatis.user
</select>

Insert

<insert id="addUser" parameterType="com.immortal.pojo.User">
    insert into mybatis.user (`id`,`name`,`pwd`) values(#{id},#{name},#{pwd})
</insert>

Update

<update id="updateUser" parameterType="com.immortal.pojo.User">
    update mybatis.user set `name`=#{name},`pwd`=#{pwd} where `id`=#{id}
</update>

Delete

<delete id="deleteUser">
    delete from mybatis.user where `id`=#{id}
</delete>

6. 萬能的Map

假設,我們的實體類或者資料庫中的表字段或者引數過多,我們應當考慮使用map

Map傳遞引數,直接在sql中取出key即可

7. 模糊查詢

java程式碼執行的時候,傳遞萬用字元 %李%

@org.junit.Test
public void getUserLike(){
    //獲得SqlSession
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    //獲取Mapper
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    //呼叫介面的方法
    List<User> userList = userMapper.getUserLike("%杜%");
    //遍歷
    for (User user : userList) {
        System.out.println(user);
    }
    //關閉連線
    sqlSession.close();
}
<select id="getUserLike" resultType="com.immortal.pojo.User">
      select * from mybatis.user where `name` like #{value}
</select>

8. 配置解析

MyBatis 的配置檔案包含了會深深影響 MyBatis 行為的設定和屬性資訊。 配置文件的頂層結構如下:

環境配置(environments)

MyBatis 可以配置成適應多種環境,這種機制有助於將 SQL 對映應用於多種資料庫之中, 現實情況下有多種理由需要這麼做。例如,開發、測試和生產環境需要有不同的配置;或者想在具有相同 Schema 的多個生產資料庫中使用相同的 SQL 對映。還有許多類似的使用場景。

不過要記住:儘管可以配置多個環境,但每個 SqlSessionFactory 例項只能選擇一種環境。

mybatis的預設事務管理器是jdbc它支援事務提交回滾操作 連線池是POOLED的

還有一種是MANAGED – 這個配置幾乎沒做什麼。它從不提交或回滾一個連線,而是讓容器來管理事務的整個生命週期(比如 JEE 應用伺服器的上下文)。 預設情況下它會關閉連線。然而一些容器並不希望連線被關閉,因此需要將 closeConnection 屬性設定為 false 來阻止預設的關閉行為。例如:

官方文件 寫的很清楚

屬性(properties)

db.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
username=root
password=123456

mybatis-config

<?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>
<!--    匯入外部配置檔案-->
    <properties resource="db.properties"/>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/immortal/dao/UserMapper.xml"/>
    </mappers>
</configuration>

優先使用外部配置檔案

類型別名(typeAliases)

類型別名可為 Java 型別設定一個縮寫名字。 它僅用於 XML 配置,意在降低冗餘的全限定類名書寫。例如:

<typeAliases>
    <typeAlias type="com.immortal.pojo.User" alias="User"/>
</typeAliases>

在其他地方可以使用User這個別名代表com.immortal.pojo.User

<typeAliases>
  <package name="com.immortal.pojo"/>
</typeAliases>

每一個在包 domain.blog 中的 Java Bean,在沒有註解的情況下,會使用 Bean 的首字母小寫的非限定類名來作為它的別名。 比如 domain.blog.Author 的別名為 author;若有註解,則別名為其註解值。見下面的例子:

@Alias("author")
public class Author {
    ...
}

下面是一些為常見的 Java 型別內建的類型別名。它們都是不區分大小寫的,注意,為了應對原始型別的命名重複,採取了特殊的命名風格。

別名 對映的型別
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator

設定(settings)

這是 MyBatis 中極為重要的調整設定,它們會改變 MyBatis 的執行時行為。 下表描述了設定中各項設定的含義、預設值等。

對映器(mappers)

既然 MyBatis 的行為已經由上述元素配置完了,我們現在就要來定義 SQL 對映語句了。 但首先,我們需要告訴 MyBatis 到哪裡去找到這些語句。 在自動查詢資源方面,Java 並沒有提供一個很好的解決方案,所以最好的辦法是直接告訴 MyBatis 到哪裡去找對映檔案。 你可以使用相對於類路徑的資源引用,或完全限定資源定位符(包括 file:/// 形式的 URL),或類名和包名等。例如:

<!-- 使用相對於類路徑的資源引用 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用完全限定資源定位符(URL) -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<!-- 使用對映器介面實現類的完全限定類名 -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!-- 將包內的對映器介面實現全部註冊為對映器 -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

這些配置會告訴 MyBatis 去哪裡找對映檔案,剩下的細節就應該是每個 SQL 對映檔案了,也就是接下來我們要討論的。

mapperRegister若如果沒有註冊的話,就區mybatis-config.xml配置

生命週期於作用域

生命週期於作用域是至關重要的,因為錯誤使用會導致嚴重的併發問題

SqlSessionFactoryBuilder

  • 建造者模式
  • 一旦建立了SqlSessionFactory,就不再需要了
  • 區域性變數

SqlSessionFactory

  • 工廠模式
  • 可以想象為資料庫連線池
  • SqlSessionFactory 一旦被建立就應該在應用的執行期間一直存在,沒有任何理由丟棄它或重新建立另一個例項。 使用 SqlSessionFactory 的最佳實踐是在應用執行期間不要重複建立多次,多次重建 SqlSessionFactory 被視為一種程式碼“壞習慣”。因此 SqlSessionFactory 的最佳作用域是application作用域。 有很多方法可以做到,最簡單的就是使用單例模式或者靜態單例模式。

SqlSession

  • 連線到連線池的一個請求

  • 每個執行緒都應該有它自己的 SqlSession 例項。SqlSession 的例項不是執行緒安全的,因此是不能被共享的,所以它的最佳的作用域是請求或方法作用域。

  • 連線完畢後需要趕緊關閉,否則會佔用資源!

9. 解決屬性名和欄位不一致

如果資料庫的欄位名與pojo的屬性沒有不一致的話,無法進行賦值到屬性上,導致空值

ResultMap

可以通過 ResultMap這個標籤將資料庫的欄位名與JavaBean的屬性名進行關聯進行賦值

UserMapper..xml

<?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.immortal.dao.UserMapper">
    <resultMap id="userMap" type="com.immortal.pojo.User">
        <result column="pwd" property="password"/>
    </resultMap>

    <select id="getUserById" resultMap="userMap">
        select * from  mybatis.user where id = #{id}
    </select>
</mapper>

賦值到屬性上面了

10. 日誌

日誌工廠

  • STDOUT_LOGGING簡單,加上就可以用

  • <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    

    控制檯輸出

LOG4J

  • Log4j是Apache的一個開源專案,通過使用Log4j,我們可以控制日誌資訊輸送的目的地是控制檯、檔案、GUI元件,甚至是套介面伺服器、NT的事件記錄器、UNIX Syslog守護程序等;
  • 我們也可以控制每一條日誌的輸出格式
  • 通過定義每一條日誌資訊的級別
  • 最令人感興趣的就是,這些可以通過一個配置檔案來靈活地進行配置,而不需要修改應用的程式碼。
  • 匯入jar包
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

編寫配置檔案

將mybatis的日誌實現換成log4j的 就可以了

11. 分頁

為什麼要分頁

  • 減少資料的處理量

語法

select * from user limit startIndex,pageSize;
select * from user limit 0,5;

基於Map實現,不正規,爽

<select id="getListUserLimit" parameterType="map" resultMap="userMap">
      select * from mybatis.user limit #{startIndex},#{pageSize}
</select>

RowBounds

<select id="getListUserRowBounds" resultMap="userMap">
    select * from mybatis.user
</select>
@org.junit.Test
public void getListUserRowBounds(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();

    RowBounds rowBounds = new RowBounds(0,5);

    List<User> userList = sqlSession.selectList("com.immortal.dao.UserMapper.getListUserRowBounds", null, rowBounds);

    for (User user : userList) {
        System.out.println(user);
    }

    sqlSession.close();
}

分頁外掛

按照文件一步一步操作就行 easy

12. 使用註解開發

關於介面的理解 解耦

介面更深的理解就是定義實現分離

介面本事反應了系統設計人員對系統的抽象理解

介面有兩類

  • 第一種是對一個個體的抽象,它對應一個抽象體
  • 第二種是對一個個體莫一方面的抽象,既成為一個抽象面

官網上很具體了 !!! 複雜的sql不建議使用

13. Mybatis執行流程

  1. Resources物件獲取載入全域性配置檔案
  2. 例項化SqlSessionFactoryBuilder構造器
  3. 解析配置檔案流XMLConfigBuilder
  4. 返回Configuration所有的配置資訊
  5. sqlSessionFactory例項化
  6. 事務管理器transaction
  7. 建立執行器executor
  8. 建立sqlSession
  9. 實現crud
  10. 是否執行成功 失敗回滾

14. 多對一,一對多

多個學生關聯一個老師 【多對一】

對於老師而言就是 【一對多】

如果java實體類中包含其他java類 需要進行結果集對映

<?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.immortal.dao.StudentMapper">

    <select id="getStudentList" resultMap="StudentTeacher">
        select * from mybatis.student;
    </select>
    <!--這裡將結果集通過association 進行對映 用子查詢將結果對映到屬性上-->
    <resultMap id="StudentTeacher" type="com.immortal.pojo.Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <association property="teacher" column="tid" javaType="com.immortal.pojo.Teacher" select="getTeacher"/>
    </resultMap>

    <select id="getTeacher" resultType="com.immortal.pojo.Teacher">
        select * from mybatis.teacher where id = #{tid}
    </select>
</mapper>

還可以向將資料查詢出來 在將資料對映到具體的屬性上

    <select id="getStudentList" resultMap="StudentTeacher">
        select student.id as sid,student.name as sname,teacher.name as tname,teacher.id as tid
        from mybatis.student,mybatis.teacher
        where student.tid = teacher.id
    </select>
<!--對映查詢的資料-->
    <resultMap id="StudentTeacher" type="com.immortal.pojo.Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <association property="teacher" javaType="com.immortal.pojo.Teacher">
            <result property="id" column="tid"/>
            <result property="name" column="tname"/>
        </association>
    </resultMap>

其實我們在解決我問題就是 javaBean欄位與資料庫欄位無法對映的問題

提供對映關係

15. 動態SQL

根據不同的條件生成不同的sql

動態 SQL 是 MyBatis 的強大特性之一。如果你使用過 JDBC 或其它類似的框架,你應該能理解根據不同條件拼接 SQL 語句有多痛苦,例如拼接時要確保不能忘記新增必要的空格,還要注意去掉列表最後一個列名的逗號。利用動態 SQL,可以徹底擺脫這種痛苦。

使用動態 SQL 並非一件易事,但藉助可用於任何 SQL 對映語句中的強大的動態 SQL 語言,MyBatis 顯著地提升了這一特性的易用性。

如果你之前用過 JSTL 或任何基於類 XML 語言的文字處理器,你對動態 SQL 元素可能會感覺似曾相識。在 MyBatis 之前的版本中,需要花時間瞭解大量的元素。藉助功能強大的基於 OGNL 的表示式,MyBatis 3 替換了之前的大部分元素,大大精簡了元素種類,現在要學習的元素種類比原來的一半還要少。

  • if

    •   <select id="selectBlogIF" resultType="com.immortal.pojo.Blog" parameterType="map">
              select * from Blog
              <where>
                  <if test="title != null">
                      title = #{title}
                  </if>
                  <if test="author != null">
                      and author = #{author}
                  </if>
              </where>
        </select>
      
  • choose (when, otherwise)

    • <select id="findActiveBlogLike"
           resultType="Blog">
        SELECT * FROM BLOG WHERE state = ‘ACTIVE’
        <choose>
          <when test="title != null">
            AND title like #{title}
          </when>
          <when test="author != null and author.name != null">
            AND author_name like #{author.name}
          </when>
          <otherwise>
            AND featured = 1
          </otherwise>
        </choose>
      </select>
      
  • trim (where, set)

  • foreach

    • 動態 SQL 的另一個常見使用場景是對集合進行遍歷(尤其是在構建 IN 條件語句的時候)。比如:

    • <select id="selectPostIn" resultType="domain.blog.Post">
        SELECT *
        FROM POST P
        WHERE ID in
        <foreach item="item" index="index" collection="list"
            open="(" separator="," close=")">
              #{item}
        </foreach>
      </select>
      

報錯

org.apache.ibatis.binding.BindingException: Mapper method 'com.immortal.dao.BlogMapper.addBlog attempted to return null from a method with a primitive return type (int).

這裡腦子問題將select 標籤寫錯了 導致這個問題 將改成insert標籤就可以了

https://mybatis.org/mybatis-3/zh/dynamic-sql.html 官網 上面寫的很好

SQL片段

我們有的時候可能會將一些公共的部分抽取出來

<sql id="if-title-author">
    <if test="title != null">
        title = #{title}
    </if>
    <if test="author != null">
        and author = #{author}
    </if>
</sql>


<select id="selectBlogIF" resultType="com.immortal.pojo.Blog" parameterType="map">
    select * from Blog
    <where>
        <include refid="if-title-author"/>
    </where>
</select>

16. 快取

  1. 什麼是快取?
    • 記憶體中儲存的臨時資料,
    • 將使用者經常查詢的資料放在快取中,使用者區查詢資料就不用次磁碟上查詢,從快取上查詢會大大提高效率,提高效能
  2. 為什麼使用快取
    • 減少與資料庫的互動,減小系統的開銷,提高系統的效率
  3. 什麼資料能使用快取
    • 經常查詢,不變的資料

Mybatis快取

MyBatis 內建了一個強大的事務性查詢快取機制,它可以非常方便地配置和定製。 為了使它更加強大而且易於配置

  • Mybatis系統預設定義兩種快取,一級快取二級快取
    • 預設情況下,只有一級快取(sqlSession基本的快取,也稱為本地快取)
    • 二級快取需要手動配置和開啟,它是基於namespace級別的
    • 為了提高擴充套件性,Mybatis定義了快取介面Cache,我們可以通過實現介面,自定義二級快取
  • 可用的清除策略有:
    • LRU – 最近最少使用:移除最長時間不被使用的物件。
    • FIFO – 先進先出:按物件進入快取的順序來移除它們。
    • SOFT – 軟引用:基於垃圾回收器狀態和軟引用規則移除物件。
    • WEAK – 弱引用:更積極地基於垃圾收集器狀態和弱引用規則移除物件。

一級快取

這個簡單語句的效果如下:

  • 對映語句檔案中的所有 select 語句的結果將會被快取。
  • 對映語句檔案中的所有 insert、update 和 delete 語句會重新整理快取。
  • 快取會使用最近最少使用演算法(LRU, Least Recently Used)演算法來清除不需要的快取。
  • 快取不會定時進行重新整理(也就是說,沒有重新整理間隔)。

開啟日誌

測試在一個session中查詢兩次記錄

 @org.junit.Test
    public void selectBlogIF(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        Map<String, Object> map = new HashMap<String, Object>();

        map.put("author","james");

        List<Blog> blogs = mapper.selectBlogIF(map);

        List<Blog> blogs1 = mapper.selectBlogIF(map);

        System.out.println(blogs == blogs1);

        sqlSession.close();

檢視日誌輸出

快取失效的情況:

  • 增刪改 可能會改變原來的資料,所有必定會重新整理快取!
  • 查詢不同的東西
  • 查詢不同的mapper.xml
  • 手動清除

二級快取

二級快取也稱全域性快取,一級的作用域太低了

基於namespace級別的快取,一個名稱空間,對應一個二級快取

工作機制

  • 一個會話查詢一條資料,這個資料會儲存在當前會話的一級快取中
  • 如果當前會話關閉了,這個對話的一級快取就沒有了,但是我們想要的是會話關閉了,一級快取的資料就會被儲存在二級快取中
  • 新的會話查詢資訊,就可以在二級快取中獲取資訊
  • 不同的mapperhu查出的資料,會放在自己對應的快取中

步驟

  • 需要在setting中中顯示開啟二級快取

  • 設定名 描述 有效值 預設值
    cacheEnabled 全域性性地開啟或關閉所有對映器配置檔案中已配置的任何快取。 true | false true
  • 在mapper中 配置二級快取

  • 加上

  • <cache
      eviction="FIFO"   //快取策略
      flushInterval="60000"  //重新整理實現
      size="512"			//快取大小
      readOnly="true"/>    //只讀
    

快取原理