MyBatis学习之注解、XML、二级缓存

框架

框架(Framework)是整个或部分系统的可重用设计,简而言之,框架是软件开发中的一套解决方案,不同的框架解决不同的问题。框架内部封装了很多细节,使得开发者可以使用极简的方式来实现功能,大大提高开发效率。

其中,框架要解决的最重要的一个问题是技术整合的问题。


Mybatis

mybatis是持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement等繁杂的过程。 mybatis通过xml或注解的方式将要执行的各种statement配置起来,并通过java对象和 statement 中 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回

MyBatis是一个半自动化的持久化层框架,使得sql和java编码分开,功能边界清晰,一个专注业务、 一个专注数据。


基于XML

目录结构:

  • src.main.java
    • dao
      • IUserDao(接口)
    • entity
      • User
  • resources
    • dao
      • IUserDao.xml
    • SqlMapConfig.xml

第一步,创建Maven工程并导入依赖

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.15</version>
            <scope>runtime</scope>
        </dependency>
		......

第二步:创建实体类和dao层接口,例如User、IUserDao

public class User implements Serializable {
    
    
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    ...
}
public interface IUserDao {
    
    
    List<User> findAll();
}

第三步:创建MyBatis的全局配置文件:SqlMapConfig.xml

MyBatis 的全局配置文件包含了影响 MyBatis 行为甚深的设置(settings)和属性(properties)信息、如数据库连接池信息等。指导着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">
<!-- mybatis的主配置文件 -->
<configuration>
    <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源(连接池) -->
            <dataSource type="POOLED">
                <!-- 配置连接数据库的4个基本信息 -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai"/>
                <property name="username" value="root"/>
                <property name="password" value="931318132"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
    <mappers>
        <mapper resource="dao/IUserDao.xml"/>
    </mappers>
</configuration>

标签说明:

1、properties:使用properties标签可以引入外部properties的内容。

<!-- 使用properties标签可以引入外部properties的内容
    resource:引入类路径下的资源;url:引入网络路径或者磁盘路径下的资源-->
    <properties resource="druid.properties"/>

...
<property name="driver" value="${driverClassName}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>

2、settings:这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。

在这里插入图片描述

<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

3、typeAliases:别名处理器。类型别名是为 Java 类型设置一个短的名字,可以方便我们引用某个类。(别名不区分大小写)

  • tpye属性:类的全类名
  • alis属性:别名,默认是类名小写
<typeAliases>
    <typeAlias type="com.xingyu.entity.User" alias="user"/>
    <typeAlias type="com.xingyu.entity.Employee" alias="employee"/>
</typeAliases>

如果需要起别名的类比较多,则可以批量起别名:为当前包以及所有后代包的每一个类都起了一个默认别名(类名小写)

<typeAliases>
    <package name="com.xingyu.bean"></package>
</typeAliases>

也可以使用@Alias注解为其指定一个别名:

@Alias("user")
public class User implements Serializable {
    
    
    private Integer id;
    private String username;
    ...
}

3、typeHandlers:类型处理器。无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时,都会用类型处理器将获取的值以合适的方式转换成 Java 类型。(java数据类型和数据库数据类型的映射桥梁)

4、plugins:插件是MyBatis提供的一个非常强大的机制,可以通过插件来修改MyBatis的一些核心行为。插件通过动态代理机制,可以介入四大对象的任何一个方法的执行。

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed):执行器
  • ParameterHandler (getParameterObject, setParameters) :参数处理器
  • ResultSetHandler (handleResultSets, handleOutputParameters) :结果集处理器
  • StatementHandler (prepare, parameterize, batch, update, query):SQL处理器

5、environments:

MyBatis可以配置多种环境,比如开发、测试和生产环境需要有不同的配置。其中每种环境使用一个environment标签进行配置并指定唯一标识符,因此,可以通过environments标签中的default属性指定一个环境的标识符来快速的切换环境

  • id:指定当前环境的唯一标识 ;

  • transactionManager的type:JDBC | MANAGED | 自定义;

    • JDBC:使用了 JDBC 的提交和回滚设置,依赖于从数据源得到的连接来管理事务范围。 JdbcTransactionFactory
    • MANAGED:不提交或回滚一个连接、让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 ManagedTransactionFactory
    • 自定义:实现TransactionFactory接口,type=全类名/ 别名
  • dataSource的type属性,这个type属性标识了采取哪种连接池技术。其取值有POOLED、UNPOOLED、JNDI。

    • POOLED:采用传统的javax.sql.DataSource规范中的连接池,Mybatis中有针对规范的实现。
    • UNPOOLED:采用传统的取得连接的方式,没有使用连接池的思想。
    • JNDI:采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到的DataSource是不一样的。注意:不是web或maven的war工程,是不能用的。
    • 自定义:实现DataSourceFactory接口,定义数据源的获取方式。
<environments default="mysql">
    <!-- 配置mysql的环境-->
    <environment id="mysql">
        <!-- 配置事务的类型-->
        <transactionManager type="JDBC"/>
        <!-- 配置数据源(连接池) -->
        <dataSource type="POOLED">
            <!-- 配置连接数据库的4个基本信息 -->
            <property name="driver" value="${driverClassName}"/>
            <property name="url" value="${url}"/>
            <property name="username" value="${username}"/>
            <property name="password" value="${password}"/>
        </dataSource>
    </environment>
</environments>

6、databaseIdProvider

MyBatis 可以根据不同的数据库厂商执行不同的语句.

  • Type: DB_VENDOR – 使用MyBatis提供的VendorDatabaseIdProvider解析数据库厂商标识。也可以实现DatabaseIdProvider接口来自定义。
  • Property-name:数据库厂商标识
  • Property-value:为标识起一个别名,方便SQL语句使用 databaseId属性引用
<databaseIdProvider type="DB_VENDOR">
    <property name="MySQL" value="mysql"/>
    <property name="Oracle" value="oracle"/>
    <property name="SQL Server" value="sqlsever"/>
</databaseIdProvider>
<!-- 对应的SQL,用databaseId="别名"的方式来指定这个SQL在哪个数据库下执行 -->
<select id="" resultType="" databaseId="oracle">...</select>
<select id="" resultType="" databaseId="sqlserver">...</select>

7、mapper映射:指导着MyBatis如何进行数据库增删改查。

mapper逐个注册SQL映射文件:

 <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 
	resource:引入类路径下的资源;url:引入网络路径或者磁盘路径下的资源-->
<mappers>
    <mapper resource="dao/IUserMapp.xml"/>
</mappers>

mapper批量注册SQL映射文件(这种方式要求SQL映射文件名必须和接口名相同并且在同一目录下)

 <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
<mappers>
     <package name="com.xingyu.dao"/>
</mappers>

第四步:创建映射配置文件:IUserDao.xml

映射文件的作用就相当于是定义Dao接口的实现类如何 工作。这也是我们使用MyBatis时编写的最多的文件。

<?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="dao.IUserDao">
    <!-- 配置查询所有操作 -->
    <select id="findAll" resultType="entity.User">
        select * from user
    </select>
</mapper>

注意事项:

  • Mybatis的映射配置文件位置,必须与dao层接口的包结构相同。
  • 映射配置文件的IUserDao.xml的<mapper>标签中的namespace属性的取值必须是dao接口的全限定类名。
  • 映射配置文件IUserDao.xml的操作配置(select),id属性的取值必须是dao层接口对应操作的方法名。
  • 映射配置文件IUserDao.xml的操作配置(select),resultType属性的取值必须是entity层的实体类名。
  • 实现以上要求后,开发中不再需要写dao层接口的实现类,只需关注SQL本身。

基于注解

  • 移除IUserDao.xml配置文件
  • 在接口IUserDao的方法中添加注解
public interface IUserDao {
    
    
    @Select("select * from user")
    List<User> findAll();
}
  • 修改MyBatis的主配置文件SqlMapConfig.xml中的mapper标签,用class属性指定对应的dao层接口
    <!-- 使用注解的方式: -->
    <mappers>
        <mapper class="dao.IUserDao"/>
    </mappers>

注意:

  • 比较重要且复杂的Dao层接口用xml配置文件的方式。
  • 比较简单且不重要的Dao层接口用注解方式。
  • Mybatis 允许定义包装类、布尔型等返回类型,只需在Dao接口修改返回类型,无需在xml中规定。

使用方法

InputStream in = Resources.getResourceAsStream("SqlMapConfig");
//1.创建SqlSessionFactory的构建者对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//2.使用构建者创建SqlSessionFactory工厂对象
SqlSessionFactory factory = builder.build(in);
//3.使用SqlSessionFactory工厂生产SqlSession 对象
SqlSession session = factory.openSession();
//4.使用 SqlSession 创建 dao 接口的代理对象
IUserDao userDao = session.getMapper(IUserDao.class);
//5.使用代理对象执行查询所有方法
List<User> users = userDao.findAll();
for (User user : users) {
    
    
    System.out.println(user);
}
//6.释放资源
session.close();
in.close();

注意:

  • SqlSession 的实例不是线程安全的,因此是不能被共享的
  • SqlSession 每次使用完成后需要正确关闭,这个关闭操作是必须的
  • SqlSession可以直接调用方法的id进行数据库操作,但是我们一般还是推荐使用SqlSession获取到Dao接口的代理类,执行代理对象的方法,可以更安全的进行类型检查操作

获取自增主键的值

MySQL支持主键自增,可在insert标签内部通过useGeneratedKeys和keyProperty两个属性的设置来获取自增主键的值。

<insert id="addUser" parameterType="u" useGeneratedKeys="true" keyProperty="id">
    insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})</insert>

Oracle不支持自增主键。


单个/多个参数的处理

  • 单个参数:#{参数名}(单个参数的情况Mybatis不会做特殊处理)
  • 多个参数:多个参数会被封装成一个map,#{}会从map中获取指定的key的值(多个参数的情况Mybatis会做特殊处理)。
    • key:param1、param2…或者参数的索引
    • value:传入的参数值

多个参数处理方式一(使用param1、param2…):

List<User> findByIdAndName(Integer id, String username);
    

<select id="findByIdAndName" resultType="u">
    select * from user where id=#{
    
    param1} and username=#{
    
    param2};
</select>

多个参数处理方式二(推荐使用@Param(“”)命名参数,明确指定封装参数值map的key):

List<User> findByIdAndName(@Param("id") Integer id, @Param("username") String username);
    

<select id="findByIdAndName" resultType="u">
    select * from user where id=#{
    
    id} and username=#{
    
    username};
</select>

如果参数特别多的情况下,上述方式也有些繁琐:

  • 如果多个参数正好是业务逻辑的数据模型,则可以直接传入entity,此时相应地,#{属性名}就可以取出传入的entity的属性值。
  • 如果多个参数不是业务逻辑的数据模型,没有对应的entity,则可以传入map,相应地,#{key}就可以取出传入的对应值。
  • 在多个参数的情况下,如果是经常使用,则推荐编写一个TO(transfer object)。比如,分页时的Page等。
List<User> find(Map<String, Integer> map);
List<User> find(User user);
public class Page<T> {
    
    
    public static final Integer PAGE_SIZE = 4;
    // 当前页码
    private Integer pageNo;
    // 总页码
    private Integer pageTotal;
    // 当前页显示数量
    private Integer pageSize = PAGE_SIZE;
    // 总记录数
    private Integer pageTotalCount;
    // 当前页数据
    private List<T> items;
    // 分页条的请求地址
    private String url;
    
    ......
}

特别注意:如果传入参数的Collection类型或者是数组,Mybatis也会进行特殊处理,会把传入的Collection封装在map中,此时,key分别是collection、list、array


参数值的获取

#{}:可以获取map中的值或者entity对象属性的值。

${}:也可以获取map中的值或者entity对象属性的值。

区别:#{}是以预编译的形式将参数设置到SQL语句中,可以防止SQL注入(PreparedStatement);而${}取出的值直接拼装正在SQL语句中。

<select id="findByIdAndName" resultType="u">
    select * from user where id=${id} and username=#{username};
</select>

输出SQL语句:
select * from user where id = 1 and username =  ?

大多数情况下,会使用#{}。但是在特殊情况下,原生jdbc不支持占位符的地方,就可以使用${}。比如有两张表分别是2016_salary和2017_salary,分别表示2016年和2017年的薪资情况,这时需要查这两张表,可以用:select * from ${year}_salary where XXX; 或者排序操作:select * from user order by ${username} ${DESC};

#{} 更丰富的用法:

#{} 中参数位置支持的属性 有javaType、jdbcType、mode(存储过程)、numericScale(保留小数)、 resultMap(结果类型)、typeHandle(类型处理器)r、jdbcTypeName、expression。实际上通常被设置的是: 可能为空的列名指定 jdbcType,因为某些数据库不能识别mybatis对null1的默认处理。


select元素

Select元素来定义查询操作。

  • Id:唯一标识符。 – 用来引用这条语句,需要和接口的方法名一致
  • parameterType:参数类型。 – 可以不传,MyBatis会根据TypeHandler自动推断
  • resultType:返回值类型。 – 别名或者全类名
    • 如果返回的是集合,定义集合中元素的类型。不能和resultMap同时使用。
    • 如果返回的是map<String, Integer>,定义为map
    • 如果返回的是map<Integer, User>,即key是返回对象的主键值,value是返回对象。定义集合中元素的类,且在Dao方法上加注解@MapKey(“id”),来指定map的key是哪个属性。
  • resultMap:实现高级结果集映射。

自动映射的方式:

  • 全局setting设置,可以设置autoMappingBehavior开启自动映射。或者开启自动驼峰命名规则映射功能,即maUnderscoreTocamelCase=true。
  • 自定义resultMap,实现高级结果集映射。

动态SQL

MyBatis 采用功能强大的基于 OGNL 的表达式来简化操作,极大的简化我们拼装 SQL的操作

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

1、if:判断

List<User> findIFTest(User user);

<select id="findIFTest" resultType="u">
    select * from user
    <where>
    <if test="id!=null">and id=#{id}</if>
    <if test="username!=null and username!=''">and username like #{username}</if>
    <if test="sex!=null and sex!=''">and sex=#{sex}</if>
    <if test="address!=null and address!=''">and address=#{address}</if>
    </where>
</select>

上述方式在特定情况下会报错,所以使用trim(),有四个参数:

  • prefix:前缀,trim标签体中是整个字符串拼串后的结果,prefix就是给这个结果加个前缀
  • prefixOverride:前缀覆盖,去掉整个字符串前面多余的字符
  • suffix:后缀,给结果加后缀
  • suffixOverride:后缀覆盖,去掉整个字符串后面多余的字符
<select id="findIFTest" resultType="u">
    select * from user
    <trim prefix="where" prefixOverrides="" suffix="" suffixOverrides="and">
    <if test="id!=null">id=#{id} and </if>
    <if test="username!=null and username!=''">username like #{username} and </if>
    <if test="sex!=null and sex!=''">sex=#{sex} and </if>
    <if test="address!=null and address!=''">address=#{address} and </if>
    </trim>
</select>

2、choose(when, otherwise) :分支选择

有id则用id查,无id有username就用username查,都没有的话就查询所有。(只选择其中一个条件)

<select id="findChooseTest" resultType="u">
    select * from user
    <where>
        <choose>
            <when test="id!=null">
                id = #{id}
            </when>
            <when test="username!=null">
                username like #{username}
            </when>
            <otherwise>
                1=1
            </otherwise>
        </choose>
    </where>
</select>

3、trim (where, set)

where用于包裹where子条件,set用于包裹set修改条件,trim操作前缀后缀。

4、for-each

批量查询:

假设Collections作为参数,比如查询id属于某一集合的用户:select * from user where id in (1,2,3,4,5);

List<User> findListTest(ArrayList<Integer>());

<select id="xx" resultType="u">
    select * from user where id in
    <foreach collection="ids" item="u_item" separator="," open="(" close=")">
        #{u_item}
    </foreach>
</select>

批量插入:

<insert id="xx">
    insert into user(id,username,birthday,sex,address) values
    <foreach collection="embs" item="emb" separator=",">
        (#{emb.id},#{emb.username},#{emb.birthday},#{emb.sex},#{emb.address})
    </foreach>
</insert>

两个内置参数

_parameter:代表整个参数。单个参数时_parameter就代表这个参数,多个参数时代表map。

_databaseId:如果配置了databaseProvider标签,就代表数据库别名。


bind

bind可以将OGNL表达式的值绑定在一个变量中,方便后来引用这个值。

举例,模糊查询用户名,可以将其用bind标签赋值给一个变量_username,之后就可以直接使用_username。

<bind name="_username" value="'%'+username+'%'"/>

sql

sql标签可以用来抽取可重用的sql语句片段。

与之相应的是include标签可以引用sql标签抽取出的片段。

<sql id="insertSome">
    id,username,birthday,sex,address
</sql>
<!-- 查询所有 -->
<select id="findAll" resultType="u">
    select
    <include refid="insertSome"/>
    from user
</select>

MyBatis缓存

MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制,缓存可以极大的提升查询效率

一级缓存和二级缓存

  • 默认情况下,只有一级缓存(SqlSession级别的缓存, 也称为本地缓存)开启
  • 二级缓存需要手动开启和配置,他是基于namespace级 别的缓存
  • 为了提高扩展性。MyBatis定义了缓存接口Cache。可以通过实现Cache接口来自定义二级缓存

一级缓存

一级缓存(local cache),即本地缓存,作用域默认为SqlSession。当 Session flush 或 close 后, 该 Session 中的所有 Cache 将被清空。

  • 本地缓存不能被关闭, 但可以调用 clearCache() 来清空本地缓存,或者改变缓存的作用域
  • 在 mybatis3.1 之后, 可以配置本地缓存的作用域。在 mybatis.xml 中配置
  • 增删改操作可能对当前数据有影响,所以会导致一级缓存失效
  • 查询条件不同也会导致一级缓存失效

二级缓存

二级缓存(second level cache),全局作用域缓存,基于namespace级别,每个namespace对应一个xml文件。

  • 二级缓存默认不开启,需要手动配置
  • MyBatis提供二级缓存的接口以及实现,缓存实现要求 POJO实现Serializable接口
  • 二级缓存在 SqlSession 关闭或提交之后才会生效

工作机制:

  1. 一个会话,查询一条数据,这个数据就会被放在当前会话的一级缓存中;
  2. 如果会话关闭,一级缓存数据会被保存到二级缓存中;新的查询会话就可以参考二级缓存的内容;
  3. 不同namespace查出的数据会放在自己对应的二级缓存(map)中;

使用步骤:

  • 全局配置文件中开启二级缓存 <setting name=“cacheEnabled” value=“true”/>
  • 需要使用二级缓存的映射文件处,即*.xml处使用cache配置缓存 <cache />
  • 注意:相关实体需要实现Serializable接口
<cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"></cache>

相关参数:

1、eviction=“FIFO”:缓存回收策略

  • LRU – 最近最少使用:移除最长时间不被使用的对象
  • FIFO – 先进先出:按对象进入缓存的顺序来移除它们
  • SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象
  • WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象
  • 默认的是 LRU

2、flushInterval:刷新间隔,单位毫秒。默认情况是不设置,缓存仅仅调用语句时刷新

3、size:引用数目,正整数。代表缓存最多可以存储多少个对象,太大容易导致内存溢出

4、readOnly:只读。true/false

  • true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。
  • false:读写缓存;会返回缓存对象的拷贝(通过序列化和反序列化)。这会慢一些, 但是安全,因此默认是 false。

缓存有关设置:

  • 全局setting的cacheEnable: – 配置二级缓存的开关。一级缓存一直是打开的。
  • select标签的useCache属性: – 配置这个select是否使用二级缓存。一级缓存一直是使用的
  • sql标签的flushCache属性: – 增删改默认flushCache=true。sql执行以后,会同时清空一级和二级缓存。 查询默认flushCache=false。
  • sqlSession.clearCache(): – 只是用来清除一级缓存。
  • 当在某一个作用域 (一级缓存Session/二级缓存 Namespaces) 进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被clear。

EhCache第三方缓存

EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。

MyBatis定义了Cache接口方便我们进行自定义扩展。步骤:

  • 导入ehcache包,以及整合包,日志包 ehcache-core-2.6.8.jar、mybatis-ehcache-1.0.3.jar、slf4j-api-1.6.1.jar、slf4j-log4j12-1.6.2.jar
  • 编写ehcache.xml配置文件
  • 配置cache标签 : <cache type= “org.mybatis.caches.ehcache.EhcacheCache”></cache>

当执行一条SQL查询语句时,先去二级缓存查找,然后再去一级缓存查找,最后执行JDBC查询。当JDBC查询完毕后,保存至一级缓存,当SqlSeesion失效,保存至二级缓存,二级缓存的实现就可以由第三方缓存实现。

Ehcache 和 Redis的区别有:前者操作简单易使用,存取速度快,效率更高但是不适合大型的分布式集群部署。而后者更适合用于大数据缓存,数据恢复等。

使用方式:

  • 导入第三包jar(Maven依赖):
<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.1.0</version>
</dependency>
  • 配置Ehcache,在src/main/resources目录下新增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">
    <!-- 磁盘保存路径 -->
    <diskStore path="E:\ehcache"/>

    <defaultCache
            maxElementsInMemory="10000"
            maxElementsOnDisk="10000000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
    </defaultCache>
</ehcache>

        <!--
        属性说明:
        l diskStore:指定数据在磁盘中的存储位置。
        l defaultCache:当借助CacheManager.add("demoCache")创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略

        以下属性是必须的:
        l maxElementsInMemory - 在内存中缓存的element的最大数目
        l maxElementsOnDisk - 在磁盘上缓存的element的最大数目,若是0表示无穷大
        l eternal - 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断
        l overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上

        以下属性是可选的:
        l timeToIdleSeconds - 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时,这些数据便会删除,默认值是0,也就是可闲置时间无穷大
        l timeToLiveSeconds - 缓存element的有效生命期,默认是0.,也就是element存活时间无穷大
         diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区.
        l diskPersistent - 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false。
        l diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔,默认是120秒。每个120s,相应的线程会进行一次EhCache中数据的清理工作
        l memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)
         -->
  • 在UserMapper.xml文件中添加cache字段:
<!-- ehcache配置项 -->
<cache type="org.mybatis.caches.ehcache.EhcacheCache" >
    <property name="timeToIdleSeconds" value="3600"/><!--1 hour-->
    <property name="timeToLiveSeconds" value="3600"/><!--1 hour-->
    <property name="maxEntriesLocalHeap" value="1000"/>
    <property name="maxEntriesLocalDisk" value="10000000"/>
    <property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>

猜你喜欢

转载自blog.csdn.net/qq_40585800/article/details/106675041
今日推荐