• MyBatis的映射器语法


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

    4、mapper映射器


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

    
    DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="">
    
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

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

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

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

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

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

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

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

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

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

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

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

      动添加单引号

    4.1、sql

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

    
    <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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);
    
    • 1
    • 2
    <select id="selectByPrimaryKey" resultType="user" parameterType="java.lang.Integer">
         select <include refid="Base_Column_List"/>
         from `user` 
         where id=#{id}
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

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

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

    int selectByMap(Map<String,Object> district);
    
    • 1
    
    <select id="selectByMap" resultType="" parameterType="map">
        SELECT i<include refid="Base_Column_List"/>
        WHERE name LIKE CONCAT ('%',#{name},'%')
        AND url LIKE CONCAT ('%',#{url},'%')
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    Map<String,String> map = new HashMap();
    map.put("name","aaa");
    map.put("url","11111");
    districtMapper.insertDistrict(map);
    
    • 1
    • 2
    • 3
    • 4
    2、注解

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

    //接口设置方法
    List<User> selectByPrimaryKey(@Param("username")String username,@Param("note")String note);
    
    • 1
    • 2
    <select id="selectByPrimaryKey" resultType="user">			
         select
         <include refid="Base_Column_List">include>
         from user where username=#{username} and note=#{note}
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    3、JavaBean

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

    //接口设置方法
    List<User> selectByPrimaryKey(User user);
    
    • 1
    • 2
    <select id="selectByPrimaryKey" resultType="user" parameterType="user">
         select
         <include refid="Base_Column_List"/>
         from user where username=#{username} and sex=#{note}	
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    4.2.4、RowBounds

    RowBounds是用来处理分页的

    • mapper接口指定方法

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

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

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

    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);
    
    • 1
    <insert id="insertUser" parameterType="user">
        insert into user(username, password,sex) values (#{username},#{password},#{sex})
    insert>
    
    • 1
    • 2
    • 3
    2、主键回填

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

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

    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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    4.3.2、update

    update和delete的使用和insert类似

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

    4.4、resultMap

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

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

    不能和resultType共用。

    <resultMap id="" type="" >
        
        <constructor>	
            <idArg/>			
            <arg />
        constructor>
        
        <id />
        
        <result/>
    
        
        <association property=""/>
    
        
        <discriminator javaType="">
            
            <case value="">case>
        discriminator>
    
        
        <collection property=""/>
    resultMap>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    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>    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    	
    <resultMap id="userMap" type="user">	
        	
        <id column="字段名" jdbcType="INTEGER" property="属性名" />	
        	
        <result column="字段名" jdbcType="VARCHAR" property="属性名" />
        .......
    resultMap>
    
    
    <select id="selectByPrimaryKey" resultMap="userMap">		
       
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    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
      
      • 1
      • 2
      • 3
      • 4

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

      
      <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" />
          
          <association property="classes" javaType="com.yu.mybatis.entity.Classes" column="classes_id"
                       select="com.yu.mybatis.mapper.ClassesMapper.selectByPrimaryKey"/>
        resultMap>
      
      
      <select id="selectStudentAll" resultMap="BaseResultMap">
            select * from student
      select>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13

      classes实体对应的映射器

      
      <select id="selectClassesById" resultMap="BaseResultMap">
            select * from classes where c_id = #{id}
      select>
      
      • 1
      • 2
      • 3
      • 4

      执行了两次 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>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13

      只执行一次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;
      
      • 1
      • 2
      • 3
      • 4
      <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">				
                <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>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15

      这种查询是分了两步的,所以执行了两次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>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      这种方式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">
        
        select id,username,password,sex from user where 1=1
        
        <if test="id != null and id != ''">
        	and id=#{id};
        if>
        <if test=" name != null and name !=''">
            and username=#{name};
        if>
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    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>		
            
            <when test="username != null and username != ''">
                and user.username = #{username}   
            when>		
            
            <when test="password != null and password != ''">
                and user.password = #{password}
            when>
            
            <otherwise>	
                and user.sex = '男'
            otherwise>
        choose>
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    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>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    • 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>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    • trim:可以代替where和set

      • prefix :前缀,插入代码快最前面
      • prefixOverrides :前缀,去掉代码块第一个内容
      • suffix,后缀,插入代码块最后面
      • suffixOverrides:后缀去掉代码块的最后一个内容
      <trim prefix="where" prefixOverrides="and">  
      		where是前缀的时候,会去掉and
      trim>
      <trim prefix="set" suffixOverrides=",">  
      	set是前缀的时候,会去掉,
      trim>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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
    • 2
    • 3
    • 4
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    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包

    
    
    <dependency>
        <groupId>org.mybatis.cachesgroupId>
        <artifactId>mybatis-ehcacheartifactId>
        <version>1.2.1version>
    dependency>
    
    <dependency>
        <groupId>org.slf4jgroupId>
        <artifactId>slf4j-log4j12artifactId>
        <version>1.7.26version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

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

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

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

    <settings> 
    	<setting name="cacheEnabled" value="true"/>
    settings>
    
    • 1
    • 2
    • 3

    创建ehcache的配置文件

    
    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
        
        <diskStore path="D:\java\ehcache"/>
    
    
        
        
        
        
        
        
        
        
    
        <defaultCache
                maxElementsInMemory="1000"
                eternal="false"
                timeToIdleSeconds="120"
                timeToLiveSeconds="120"
                overflowToDisk="true"
                maxElementsOnDisk="10000000"
                diskPersistent="false"
                diskExpiryThreadIntervalSeconds="120"
                memoryStoreEvictionPolicy="LRU"
        />
    
    ehcache>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    可以直接运行测试:

    image-20230304182319432
  • 相关阅读:
    2023.9.3 三色标记、Shenandoah和ZGC收集器、Redis消息队列
    神经网络系列---权重初始化方法
    A - ASCII码排序
    计算机毕业设计django基于python图书馆借阅系统
    春眠不觉晓,Java数据类型知多少?基础牢不牢看完本文就有数了
    Java System.lineSeparator 方法
    复盘一个诡异的Bug
    10分钟Apache Kylin快速入门
    腾讯云服务器端口localhost可以访问,外部无法访问解决
    都2023年金九银十了,这三个项目你还没有?你简历上项目经验写啥
  • 原文地址:https://blog.csdn.net/yuandfeng/article/details/126921919