MyBatis的 Mapper.xml 映射器语法

Java知识点总结:想看的可以从这里进入

4、mapper映射器


映射器是MyBatis的核心组件,由一个接口和对应的XML文件组成。在映射器中可以配置参数、SQL语句、存储过程、缓存、级联等内容,可以通过映射规则映射到相应的实体对象上,相对于JDBC,节省了大量的底层代码。

<?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="">

</mapper>

映射器内部常见的配置元素如下:

  • select:查询语句,返回结果集

  • insert:插入语句,返回受影响条数

  • update:更新语句,返回受影响条数

  • delete:删除语句,返回受影响条数

  • sql:定义一部分的sql,然后在其他语句引用。比方说定义数据库的字段,在语句中使用 include 引用

  • resultMap:描述如何从数据库结果集中加载对象

  • cache:该命名空间的缓存配置。

  • cache-ref: 引用其它命名空间的缓存配置。

在mapper映射器中有两种获取值的方法:

  • ${}:本质是字符串拼接,使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号

  • #{}:本质是占位符赋值。使用占位符赋值的方式拼接sql,为字符串类型或日期类型的字段进行赋值时,可以自

    动添加单引号

4.1、sql

sql元素时可以定义一条sql语句的一部分,方便后续的sql引用,最常用的就是设置一套数据库字段名的sql。

<!--设置数据字段,以后使用直接使用include引入即可 -->
<sql id="Base_Column_List">
    user_id, username, `password`, deleted
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select <include refid="Base_Column_List" />
    from `user`
    where user_id = #{userId,jdbcType=INTEGER}
</select>

4.2、select

4.2.1、常用的元素

查询语句是使用最多的语句,它内部常用配置如下:

元素说明备注
id和 mapper 的 namespace 组合使用,用来对应接口中的方法名需要唯一,否则会出现异常
parameterTypesql 语句接受的参数类型。支持基本数据类型和 JavaBean、Map 等复杂数据类型
resultTypesql 语句返回的结果类型(字段名和属性名完全一致时使用)如果是全表返回对应的实体类,如果是单独一条字段返回对应的数据类型
resultMapsql 语句返回的结果类型(当数据库的字段和类的属性不同时,使用其设置,将其进行转换)和resultType之间只能同时使用一个,是最复杂的元素,需要配置映射规则、级联等等
flushCache将其设置为 true 后,在调用SQL后,清空本地缓存和二级缓存默认值:false。
useCache启动二级缓存,将本此结果缓存起来默认值: true。
timeout超时参数,超时抛出异常单位 s,默认JDBC设置的秒数
fetchSize获取记录的总条数设置
statementType告诉MyBatis使用那个JDBC的Statement工作STATEMENT:对应Statement
PREPARED(默认) :对应PreparedStatement
CALLABLE:对应CallableStatement
resultSetType对JDBC的resultSet而言,FORWARD_ONLY(只允许向前访问)
SCROLL_SENSITIVE(双向滚动,但不及时更新)
SCROLLJNSENSITIVE(双向滚动,及时更新)
databaseId配合配置文件中databaseIdProvider使用,配置所使用的的数据库
4.2.2、简单映射
//接口的方法
User selectByPrimaryKey(int id);
<select id="selectByPrimaryKey" resultType="user" parameterType="java.lang.Integer">
     select <include refid="Base_Column_List"/>
     from `user` 
     where id=#{id}
</select>

MyBatis的自动映射是默认开启的,只要实体类名和属性与数据库名和字段对应就会形成自动映射。这个设置在xml配置文件的settings中,autoMappingBehavior 是自动映射,mapUnderscoreToCamelCase 是驼峰式命名。

4.2.3、多参数传递
1、使用map接口

使用的不多,在sql语句中传递参数时,需要知道map 的键才能传递参数。

int selectByMap(Map<String,Object> district);
<!-- 根据name和url模糊查询 -->
<select id="selectByMap" resultType="" parameterType="map">
    SELECT i<include refid="Base_Column_List"/>
    WHERE name LIKE CONCAT ('%',#{name},'%')
    AND url LIKE CONCAT ('%',#{url},'%')
</select>
Map<String,String> map = new HashMap();
map.put("name","aaa");
map.put("url","11111");
districtMapper.insertDistrict(map);
2、注解

使用 @Param注解去定义映射器的参数名称,可以提高阅读性,当参数少时建议使用。

//接口设置方法
List<User> selectByPrimaryKey(@Param("username")String username,@Param("note")String note);
<select id="selectByPrimaryKey" resultType="user">			<!--user是通过typeAliases配置-->
     select
     <include refid="Base_Column_List"></include>
     from user where username=#{username} and note=#{note}
</select>
3、JavaBean

通过传递实体类,映射器可以识别属性,当参数多时,建议使用

//接口设置方法
List<User> selectByPrimaryKey(User user);
<select id="selectByPrimaryKey" resultType="user" parameterType="user">
     select
     <include refid="Base_Column_List"/>
     from user where username=#{username} and sex=#{note}	<!--#{属性}-->
</select>
4.2.4、RowBounds

RowBounds是用来处理分页的

  • mapper接口指定方法

    List<User> selectByRowBounds(RowBounds rowBounds);
    
  • xml映射文件,RowBounds是MyBatis自动识别的,所以在映射文件中不需要配置这块的内容

    <select id="selectByRowBounds" resultType="user">
        select <include refid="Base_Column_List"/> from `user`		
    </select>
    
  • test测试:前五条数据

    RowBounds rowBounds = new RowBounds(0,5);		(起始,每页数量)
    List<User> list = userMapper.findByRowBounds(rowBounds);
    System.out.println(list);
    

4.3、增删改

insert(增)、update(改)、delete(删)三者很接近,主要有以下属性

元素说明备注
id和 mapper 的 namespace 组合使用,用来对应接口中的方法名需要唯一,负责会出现异常
parameterTypesql 语句接受的参数类型。
flushCache将其设置为 true 后,在调用SQL后,清空本地缓存和二级缓存默认值:false。
timeout超时参数,超时抛出异常单位 s,默认JDBC设置的秒数
statementType告诉MyBatis使用那个JDBC的Statement工作STATEMENT:对应Statement PREPARED(默认) :对应PreparedStatement CALLABLE:对应CallableStatement
useGeneratedKeys是否使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键,默认false
keyProperty=“id字段名”在新增、修改的时候可以获得修改的那条数据的 主键(insert 和 update)
keyColumn设置生成键值在表中的列名,当主键列不是表中的第一列的时候,是必须设置的( insert 和 update)
4.3.1、insert
1、简单语句
void insertUser(User user);
<insert id="insertUser" parameterType="user">
    insert into user(username, password,sex) values (#{username},#{password},#{sex})
</insert>
2、主键回填

我们在新增时并没有插入主键,因为主键采用了自增主键,所以mysql会自动生成主键,但是很多时候我们需要获取到这条主键以进行其他的操作,这个就是主键回填

<insert id="insertUser" parameterType="user" useGeneratedKeys="true" keyProperty="id">
   insert into user(username, password,sex)
   values (#{username},#{password},#{sex})
</insert>
userMapper.insert(user);
sqlSession.commit();
System.out.println(user.toString());

image-20210720180559100

3、自定义主键

在使用自增主键时不需要去管主键,但是如果主键的规则是我们自己设定的,比如初始为1,每次自增2。

这时可以使用selectKey标签

<insert id="insertUser" parameterType="user">
	<selectKey keyProperty="id" resultType="long" order="BEFORE">
    	select if(max(id)=null,1,max(id)+2) from `user` 
    </selectKey>
    insert into user(id,username, password,sex) 
    values (#{id},#{username},#{password},#{sex})
</insert>
4.3.2、update

update和delete的使用和insert类似

 <update id="updataById">
    update user set user.usernam=#{username},user.password=#{password} where id=#{id}
</update>
4.3.3、delete
  <delete id="deleteById" parameterType="user">
    	delete from user where id=#{id}
  </delete>

4.4、resultMap

它是用来定义映射规则、级联、类型转化等等,是最复杂的一块。比如:A表中有B表的id字段,在建实体类时属性会创建b的对象,而不是只是一个id属性,这就需要resultMap来定义映射的规则。

MyBatis在association、collection关联集合对象时支持延迟加载,即在需要使用数据时才进行加载,不用数据时就不进行加载。(一对多,多对多采用延迟加载。一对一、多对一采用立即加载)

不能和resultType共用。

<resultMap id="" type="" >
    <!-- 用来注入结果到构造方法 -->
    <constructor>	
        <idArg/>			<!-- 用于表示哪个列是主键 -->
        <arg />
    </constructor>
    <!-- 用于表示哪个列是主键 -->
    <id />
    <!-- 注入到字段或JavaBean属性的普通结果 -->
    <result/>

    <!-- 用于一对一关联 -->
    <association property=""/>

    <!-- 使用结果值来决定使用哪个结果映射 -->
    <discriminator javaType="">
        <!-- 某些值的结果映射 -->
        <case value=""></case>
    </discriminator>

    <!-- 用于一对多、多对多关联 -->
    <collection property=""/>
</resultMap>
4.4.1、简单结果集

使用 id、result 配置映射关系,数据库的字段和属性值的类型能对应上,可以只是名字上的不同,没有复杂的级联关系。

<resultMap id="userMap" type="user">	
    <!-- 对应主键-->
    <id column="字段" property="属性" javaType="java类型" jdbcType="数据库类型"  typeHandler="类型转换器"/>
    <!--其他字段-->
    <result column="字段" property="属性" javaType="java类型" jdbcType="数据库类型" typeHandler="类型转换器"/>
</resultMap>    
<!-- id是resultMap的标识,type是映射的实体类-->	
<resultMap id="userMap" type="user">	
    <!--id是主键,property是属性名,column是对应数据表的字段名 -->	
    <id column="字段名" jdbcType="INTEGER" property="属性名" />	
    <!--实体类的username属性对用的是数据库的name字段-->	
    <result column="字段名" jdbcType="VARCHAR" property="属性名" />
    .......
</resultMap>

<!--resiltMap的值是设定好的resultMap的id-->
<select id="selectByPrimaryKey" resultMap="userMap">		
   
</select>
4.4.2、association

association 和 collection 主要是用来处理级联关系的映射,有 3 种级联关系:

  1. 一对一级联:一个学生只对应一个班级
  2. 一对多级联以:一个班级对应多个学生
  3. 多对多级联:一个角色可以对应多个用户,但是一个用户可以兼任多个角色

在数据中表A保存了表B的id,这是其对应的实体类的属性,必须是B的实体类,所以简单的映射无法满足,需要使用association进行配置,它配置的是一个对象,用来表示一对一的映射关系。

属性说明
property指定映射到实体类的对象属性。
column指定表中对应的字段
javaType指定映射到实体对象属性的类型。
select指定引入嵌套查询的子 SQL 语句,用于关联映射中的嵌套查询。
  • association 分步查询

    Student的实体类

    //学生表中有班级id。实体类中创建班级的实体属性
    private Integer sId;
    private String name;
    private Classes classes;	//数据中保存的是班级id
    

    Student实体类对应的xml映射器,它是分两部,先通过select语句查出Student的信息后,再通过association设置的select方法差相关的班级,再将班级的值添到对应的属性上

    <!--resultMap设置映射规则-->
    <resultMap id="BaseResultMap" type="com.yu.mybatis.entity.Student">
        <id column="s_id" jdbcType="INTEGER" property="sId" />
        <result column="student_name" jdbcType="VARCHAR" property="name" />
        <!--property属性名,javaType对应的实体,select对应的查找classes的映射方法(会根据数据库中管理的班级id自动查找并返回班级) -->
        <association property="classes" javaType="com.yu.mybatis.entity.Classes" column="classes_id"
                     select="com.yu.mybatis.mapper.ClassesMapper.selectByPrimaryKey"/>
      </resultMap>
    
    <!--返回student的语句,设置resultMap -->
    <select id="selectStudentAll" resultMap="BaseResultMap">
          select * from student
    </select>
    

    classes实体对应的映射器

    <!--这个是Student相关的xml映射器中 association标签的select属性对应的方法 -->
    <select id="selectClassesById" resultMap="BaseResultMap">
          select * from classes where c_id = #{id}
    </select>
    

    执行了两次 sql

    image-20230304172025209

  • 也可以在 association 的内部定义:这种定义时通过一个SQL直接查询出来的数据,不需要第二次再去查询了

    <resultMap id="BaseResultMap2" type="com.yu.mybatis.entity.Student">
        <id column="s_id" jdbcType="INTEGER" property="sId" />
        <result column="student_name" jdbcType="VARCHAR" property="studentName" />
        <association  property="classes" javaType="com.yu.mybatis.entity.Classes">
          <result column="c_id" property="CId"/>		<!--内部嵌套-->
          <result column="classes_name" property="classesName"/>
        </association>
      </resultMap>
    
    <select id="selectByClassesId" parameterType="java.lang.Integer" resultMap="BaseResultMap2">
          SELECT * FROM student,classes
           WHERE student.classes_id = classes.c_id AND student.s_id = #{sId,jdbcType=INTEGER}
    </select>
    

    只执行一次sql

    image-20230304172531234

4.4.3、collection

一对多的映射关系使用collection处理,collection 可以将关联查询的多条记录映射到一个 list 集合属性中。和association使用方式类似

属性介绍
property指定映射到实体类的对象属性。
column指定表中对应的字段
select指定引入嵌套查询的子 SQL 语句
javaType指定映射到实体对象属性的类型
  1. 分步查询:这种查询是先根据select的方法查询出数据后,再次根据resultMap中设置的对应select方法查询

    //班级内很多学生
    private Integer cId;
    private String name;
    private List<Student> studentList;
    
    <resultMap id="BaseResultMap2" type="classes">
        <id column="c_id" jdbcType="INTEGER" property="cId"/>
        <result column="name" jdbcType="VARCHAR" property="name"/>
        <collection property="studentList" ofType="student">	<!--ofType和javaType类似-->			
              <result column="s_id" property="SId"/>
              <result column="s_name" property="name"/>
         </collection>
    </resultMap>
    
    <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap2">
      select
      <include refid="Base_Column_List" />
      from classes
      where c_id = #{cId,jdbcType=INTEGER}
    </select>
    

    这种查询是分了两步的,所以执行了两次SQL语句

    image-20230304171713387

  2. 内部定义

    <resultMap id="BaseResultMap3" type="com.yu.mybatis.entity.Classes">
      <id column="c_id" jdbcType="INTEGER" property="cId" />
      <result column="classes_name" jdbcType="VARCHAR" property="classesName" />
      <collection property="students" ofType="com.yu.mybatis.entity.Student">
        <result column="s_id" property="SId"/>
        <result column="student_name" property="studentName"/>
      </collection>
    </resultMap>
    
    <select id="selectClassesAndStudent" parameterType="java.lang.Integer" resultMap="BaseResultMap3">
      select  <include refid="Base_Column_List" />,s_id,student_name
      from student,classes
      where student.classes_id = classes.c_id AND classes.c_id = #{CId,jdbcType=INTEGER}
    </select>
    

    这种方式SQL语句只执行了一次

    image-20230304171611617

4.5、动态SQL

动态SQL是对sql语句进行动态的组装, 是 MyBatis 的强大特性之一。它可以通过判断自动选择要添加的sql语句,主要有以下元素:

  • if:判断语句
  • choose(when,otherwise):相当于switch,case语句
  • trim(where,set):用于处理sql拼装问题,
  • foreach:循环语句
4.5.1、if

类似于 Java 中的 if 语句,是 MyBatis 中最常用的判断语句。使用 if 标签可以节省许多拼接 SQL 的工作,把精力集中在 XML 的维护上。

if 语句使用方法简单,常常与 test 属性联合使用

<select id="" parameterType="string">
    <!--这里需要加1=1防止出错-->
    select id,username,password,sex from user where 1=1
    <!--如果传递的参数不为空,则内部的sql生效,否则不生效-->
    <if test="id != null and id != ''">
    	and id=#{id};
    </if>
    <if test=" name != null and name !=''">
        and username=#{name};
    </if>
</select>
4.5.2、choose

choose、when、otherwise类似于java中的Switch、case、default的功能

<select id="" parameterType="string">
    select id,username,password,sex from user where 1=1
    <choose>		
        <!--username不为空则只用username查询-->
        <when test="username != null and username != ''">
            and user.username = #{username}   
        </when>		
        <!--password不为空根据password查询-->
        <when test="password != null and password != ''">
            and user.password = #{password}
        </when>
        <!--都为空查询性别为男的-->
        <otherwise>	
            and user.sex = '男'
        </otherwise>
    </choose>
</select>
4.5.3、辅助元素

上面的几种情况可能会出现where后面没有条件的情况,所以在where后加了一句 1=1,来保证sql语句的正确性,但是我们期望的是where关键字根据条件而自己决定出现不出现,所以就有了,trim、where、set元素

  • where:至少有一个子元素成立,才会添加where元素,并且第一个条件的and、or元素会自动去除

    <select id="" parameterType="string">
        select id,username,password,sex from user
        <where>
             <if test="usernae != null and usernae != ''">
                user.username = #{username}
            </if>
            <if test="password != null and password != ''">
                and user.password = #{password}
            </if>
        </where>
    
    </select>
    
  • set:用于动态设置update语句中的set条件,可以删除无关的 “,”

    <update id="">
        update user 
        <set>
            <if test="usernae != null and usernae != ''">
                user.username = #{username},
            </if>    
            <if test="sex != null and sex != ''">
                user.sex = #{sex},
            </if>    
        </set>
        where id=#{id}
    </update>
    
  • trim:可以代替where和set

    • prefix :前缀,插入代码快最前面
    • prefixOverrides :前缀,去掉代码块第一个内容
    • suffix,后缀,插入代码块最后面
    • suffixOverrides:后缀去掉代码块的最后一个内容
    <trim prefix="where" prefixOverrides="and">  
    		where是前缀的时候,会去掉and
    </trim>
    <trim prefix="set" suffixOverrides=",">  
    	set是前缀的时候,会去掉,
    </trim>
    
4.5.4、foreach

循环遍历,可以很好的支持数组、list、set集合。用于sql语句的 in 关键字。

  • collection:传递的参数
  • item:当前循环的元素
  • index:当前元素在集合位置的下标
  • open、close:以什么符号将元素包装起来
  • separator:元素的间隔符
<select id="" resultType="">
  SELECT * from role where id in
  <foreach item="id" index="index" collection="list" open="(" separator="," close=")">
        #{id}
  </foreach>
</select>

4.6、缓存

对一些常用的且不经常改动的数据进行缓存,能有效的避免频繁的连接数据库,一定程度上解决高并发情况下的系统性能问题。

MyBatis允许使用缓存, 内部定义了两级缓存,和一个缓存接口:

  • 一级缓存:默认开启,SqlSession级别缓存,为本地缓存
  • 二级缓存:需要手动配置开启,是 namespace 级别的缓存。
  • 缓存接口:Cache,通过实现接口可以自定义二级缓存。
4.6.1、一级缓存

一级缓存是默认开启的,作用域为SqlSession,当一个SqlSession对象执行同一条SQL语句时,第一次是在会去查询数据库,并将其写在缓存中,后续的就直接在缓存中加载。(每次查询时现在缓存中找,缓存中没有就去数据库中查询,并将数据卸载缓存中)

当两次SQL查询时,发生了增删改的操作时,缓存会清空。

SqlSession的缓存使用 HashMap,key为hashCode+statementId+sql语句,value为映射的结果集。

一级缓存从获取一个SqlSession到close方法关闭之间有效,默认开启,无法关闭。

image-20210728152213197

缓存失效:

  • 清理缓存:sqlSession.clearCache();
  • 不同的查询语句
  • 增删改的语句
  • 不同的SqlSession
4.6.2、二级缓存

二级缓存是 SqlSession 级别的,对应一个Mapper映射文件,需要在映射文件中自行设置开启,所以二级缓存存在于所在的整个映射文件中。

第一次调用Mapper内的SQL查询时,数据会存放到对应的二级缓存区。第二次调用namespace下的mapper映射文件,向的sql会去对应的二级缓存区查找。

开启方法:

在mybatis-config.xml 文件中的settings中打开全局缓存
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>
1、在所需要的mapper.xml文件中开启二级缓存
    <cache/>		默认的
    <cache eviction = "FIFO" flushInterval = "60000" size = "512" readOnly = "true" />  自定义的
		eviction:缓存回收策略
			LRU – 最近最少使用:删除最长时间未使用的对象。
    		FIFO – 先进先出:按照对象进入缓存的顺序删除对象。
    		SOFT – 软引用:根据垃圾收集器状态和软引用规则删除对象。
    		WEAK – 弱引用:根据垃圾收集器状态和弱引用规则更积极地删除对象。
		flushInterval属性:刷新间隔,单位毫秒
		size属性:引用数目,正整数,代表缓存最多可以存储多少个对象
		readOnly属性:只读,true/false
			true:只读缓存;会给所有调用者返回缓存对象的相同实例,效能最高。
			false:读写缓存;会返回缓存对象的拷贝(通过序列化)。效率稍慢但是安全,默认是false。

2、在mapper接口上添加注解
	@CacheNamespace(blocking = true) 
  1. 如果使用默认的配置,readOnly 默认为false,所以这个时候MyBatis会序列化和反序列化实体类,所以实体类需要实现Serializable接口。否则将会抛出异常

    image-20210728171401497
  2. 二级缓存必须在SqlSession关闭或提交之后有效

    image-20210728175143446 image-20210728175219685

一级缓存和二级缓存的顺序:先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。如果二级缓存没有命中,再查询一级缓存,如果一级缓存也没有命中,则查询数据库,SqlSession关闭之后,一级缓存中的数据会写入二级缓存。

4.6.3、EHCache

Mybitis 除了内置了缓存外,还可以引入第三方的缓存,而EHCache 就是实现 mybatis 二级缓存的产品之一。它是一种广泛使用的开源Java分布式缓存,具有快速、简单、多种缓存策略,缓存数据有内存和硬盘的特点。

使用ehcache需要注意的是,ehcache的依赖 slf4j 这个日志的jar包,会和log4j的jar冲突,导致日志不能显示,所以需要整合他们,导入联合jar包

<!-- 第三方缓存EHCache-->
<!-- Mybatis EHCache整合包 -->
<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.2.1</version>
</dependency>
<!-- slf4j和log4j整合包 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.26</version>
</dependency>

然后在sql映射文件中的mapper标签下配置开启ehcace缓存

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

在mybatis-config.xml 文件中的settings中打开全局缓存

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

创建ehcache的配置文件

<?xml version="1.0" encoding="utf-8" ?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    <!-- 磁盘保存路径 -->
    <diskStore path="D:\java\ehcache"/>


    <!--maxElementsInMemory缓存最大数目-->
    <!-- maxElementsOnDisk硬盘最大缓存个数 -->
    <!--eternal设定elements是否永远不过期。true,始终有效,false,需要根据timeToIdleSeconds、timeToLiveSeconds判断-->
    <!-- overflowToDisk当系统宕机时是否保存到磁盘-->
    <!--timeToIdleSeconds当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds时,数据便会删除-->
    <!--timeToLiveSeconds缓存element的有效生命期-->
    <!--diskExpiryThreadIntervalSeconds磁盘缓存的清理线程运行间隔,默认是120秒。每120s,相应的线程会进行一次EhCache中数据的清理工作-->
    <!--memoryStoreEvictionPolicy当内存缓存达到最大,有新的element加入时,移除缓存中element的策略。
    默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)-->

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

</ehcache>

可以直接运行测试:

image-20230304182319432
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辰 羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值