mybatis总结

mybatis总结

3.5.5

导言:

学习mybatis的最优解是官方文档.

https://mybatis.org/mybatis-3/zh/index.html

1.简介

  • MyBatis 是一款优秀的持久层框架
  • 它支持定制化 SQL、存储过程以及高级映射。
  • MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
  • MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

2.使用

环境

  • JDK1.8
  • Mysql 5.7
  • maven 3.3.3
  • IDEA

导入Mybatis.

2.1 建一个Maven项目的基本步骤:

  1. 创建数据库

    create database school;
    
    use school;
    
    create table student(
      `id` INT(20) NOT NULL PRIMARY KEY,
      `name` VARCHAR(30) DEFAULT NULL,
      `score` INT(20) DEFAULT NULL
    )ENGINE=INNODB DEFAULT CHARSET=utf8;
    
    INSERT INTO student(`id`,`name`,`pwd`) VALUES 
    (1,'guo',88),
    (2,'张三',70),
    (3,'李四',56)
    
  2. pom.xml导入依赖

    • mysql驱动

    • Mybatis

    • Junit

      <!--导入依赖-->
      <dependencies>
      
          <!--mysql驱动-->
          <dependency>
              <groupId>mysql</groupId>
              <artifactId>mysql-connector-java</artifactId>
              <version>5.1.21</version>
          </dependency>
      
          <!--mybatis-->
          <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
          <dependency>
              <groupId>org.mybatis</groupId>
              <artifactId>mybatis</artifactId>
              <version>3.2.7</version>
          </dependency>
      
          <!--junit-->
          <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
              <version>4.12</version>
          </dependency>
      
      </dependencies>
      
  3. 创建工具类com.guo.utils---->获取sqlSessionFactory对象

    • 需要一个配置文件mybatis-config.xml

      //sqlSessionFactory --> sqlSession
      public class MybatisUtils {
          
          private static SqlSessionFactory sqlSessionFactory;
      
          static{
              try {
                  //使用Mybatis第一步:获取sqlSessionFactory对象
                  String resource = "mybatis-config.xml";
                  InputStream inputStream = Resources.getResourceAsStream(resource);
                  sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
          //既然有了 SqlSessionFactory,顾名思义,我们就可以从中获得 SqlSession 的实例了。
          // SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法。
          // true 可以帮我们自动提交事务.省略了提交事务sqlSession.commit()步骤;
          public static SqlSession getSqlSession(){
              return sqlSessionFactory.openSession(true);
          }
          
      }
      
  4. 创建一个mybatis-config.xml核心配置文件

    • 核心配置文件在获取sqlSessionFactory对象是用到.

      <!--configuration核心配置文件-->
      <configuration>
      
          <environments default="development">
              <environment id="development">
                  <transactionManager type="JDBC"/>
                  <dataSource type="POOLED">
                      <property name="driver" value="com.mysql.jdbc.Driver"/>
                      <property name="url" value="jdbc:mysql://localhost:3306/school?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                      <property name="username" value="root"/>
                      <property name="password" value="123456"/>
                  </dataSource>
              </environment>
          </environments>
      
      </configuration>
      

      这样写,没有层次感.优化一下,引入外部配置文件.

      •   //db.properties
          driver=com.mysql.jdbc.Driver
          url=jdbc:mysql://localhost:3306/school?useSSL=true&useUnicode=true&characterEncoding=UTF-8
          username=root
          password=123456
        
      •   <!--configuration核心配置文件-->
          <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>
          
          </configuration>
        
  5. 写pojo(实体类)

    • 可以选择使用lombok.降低代码重复.

      <!--导入依赖-->
      <dependencies>
          <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
      	<dependency>
         	 	<groupId>org.projectlombok</groupId>
          	<artifactId>lombok</artifactId>
          	<version>1.18.4</version>
          </dependency>
      </dependencies>
      
    @Data
    public class Student {
    
        private int id;
        private String name;
        private int score;
    
    }
    
  6. 写接口和实现类(用Mapper.xml代替)

    • 接口和实现类尽量在同一个包下.方便Mapper.xml文件注册.
    • 如果不在一个包下,也尽量取相同的路径名.
    • mapper.xml中要绑定接口.
    public interface StudentMapper {
    
        //查询全部学生
        List<Student> getStudentList();
    
        //根据id查询学生
        Student getStuByID(int id);
    
        //insert一个用户
        int addStu(Student stu);
    
        //delete一个用户
        int deleteStu(int id);
    
        //编辑一个用户
        int updateStu(Student stu);
    
    }
    
    <?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.guo.dao.StudentMapper">
    
        <!--select查询语句-->
        <select id="getStudentList" resultType="Student">
           select * from school.student;
       </select>
    
        <select id="getStuByID" parameterType="int" resultType="Student">
            select * from school.student where id = #{id};
        </select>
    
        <insert id="addStu" parameterType="Student">
            insert into school.student (id, name, score) values (#{id}, #{name}, #{score});
        </insert>
    
        <delete id="deleteStu" parameterType="int">
            delete from school.student where id=#{id};
        </delete>
    
        <update id="updateStu" parameterType="Student">
          update school.student set name=#{name} , score=#{score} where id=#{id};
        </update>
    </mapper>
    <!--#{id}中的id就是@Param("id")里的值-->
    

    可以使用别名的方式简略代码,避免重复的工作.

    • 在mybatis-config.xml中配置.

    •   <!--给实体类区别名-->
        <typeAliases>       
            <typeAlias type="com.guo.pojo.Student" alias="Student"/>   
        </typeAliases>
        <!--各配置间有顺序,报错查看改正就好-->
      
  7. 写test

    •   public class StudentDaoTest {
        	//查询所有student
            @Test
            public void test() {
                //第一步:获得SqlSession对象
                SqlSession sqlSession = MybatisUtils.getSqlSession();
        
                //方式一:getMapper
                StudentMapper studentDao = sqlSession.getMapper(StudentMapper.class);
                List<Student> studentList = studentDao.getStudentList();
        
                for (Student student : studentList) {
                    System.out.println(student);
                }
        
                //关闭SqlSession
                sqlSession.close();
            }
        	//根据id查询student
            @Test
            public void getStuByID() {
                SqlSession sqlSession = MybatisUtils.getSqlSession();
                StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
                Student stu = mapper.getStuByID(2);
                System.out.println(stu);
                sqlSession.close();
            }
        	//添加
            @Test
            public void addStu() {
                SqlSession sqlSession = MybatisUtils.getSqlSession();
                Object mapper = sqlSession.getMapper(StudentMapper.class);
                //增删改需要提交事务
                int res = ((StudentMapper) mapper).addStu(new Student(4, "卡萨", 99));
                if (res > 0) {
                    System.out.println("添加成功");
                }
                //提交事务
                //sqlSession.commit();
                sqlSession.close();
            }
        	//改
            @Test
            public void updateStu() {
                SqlSession sqlSession = MybatisUtils.getSqlSession();
                Object mapper = sqlSession.getMapper(StudentMapper.class);
                int stu = ((StudentMapper) mapper).updateStu(new Student(2, "诺诺", 88));
                if (stu > 0) {
                    System.out.println("编辑成功");
                }
                //'改'要提交事务
                //sqlSession.commit();
                sqlSession.close();
            }
        	//删
            @Test
            public void deleteStu() {
                SqlSession sqlSession = MybatisUtils.getSqlSession();
                StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
                int i = mapper.deleteStu(3);
                if (i > 0) {
                    System.out.println("删除成功");
                }
                //"删"要提交事务
                //sqlSession.commit();
                sqlSession.close();
            }
        }
      
  8. 在核心配置文件中配置mapper resource

    • 每一个Mapper.xml文件都需要在Mybatis核心配置文件中注册

    • MapperRegistry:注册绑定我们的Mapper文件;

    •   <!--每一个Mapper.xml文件都需要在Mybatis核心配置文件中注册-->
        <mappers>
            <mapper resource="com/guo/dao/StudentMapper.xml"/>
        </mappers>
      
    • 方式二:使用class文件绑定注册

      <!--每一个Mapper.XML都需要在Mybatis核心配置文件中注册!-->
      <mappers>
          <mapper class="com.kuang.dao.UserMapper"/>
      </mappers>
      

      方式三:使用扫描包进行注入绑定

      <!--每一个Mapper.XML都需要在Mybatis核心配置文件中注册!-->
      <mappers>
          <package name="com.kuang.dao"/>
      </mappers>
      

      注意点:

      • 接口和他的Mapper配置文件必须同名!
      • 接口和他的Mapper配置文件必须在同一个包下!
  9. 在pom文件中配置resources

    • 在build中配置resources,来防止我们资源导出失败的问题

    •   <!--在build中配置resources,来防止我们资源导出失败的问题-->
        <build>
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>
            </resources>
        </build>
      

3.resultMap

结果集映射

id   name   score
id   name   grade
<!--结果集映射-->
<resultMap id="StudentMap" type="student">
    <!--column数据库中的字段,property:实体集中的属性-->
    <result column="id" property="id"/>
    <result column="name" property="name"/>
    <result column="score" property="grade"/>
</resultMap>

<!--select查询语句-->
<select id="getStuByID" parameterType="int" resultMap="StudentMap">
    select  * from school.student where id = #{id};
</select>
  • resultMap 元素是 MyBatis 中最重要最强大的元素
  • ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。
  • ResultMap 最优秀的地方在于,虽然你已经对它相当了解了,但是根本就不需要显式地用到他们。

4.日志工厂

  • SLF4J

  • LOG4J 【掌握】

  • LOG4J2

  • JDK_LOGGING

  • COMMONS_LOGGING

  • STDOUT_LOGGING 【掌握】

  • NO_LOGGING

4.1 STDOUT_LOGGING标准日志输出

在mybatis核心配置文件中,配置我们的日志!

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

4.2 Log4j

  1. 先导入log4j的包

    <!-- https://mvnrepository.com/artifact/log4j/log4j -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    
  2. log4j.properties

    #将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
    log4j.rootLogger=DEBUG,console,file
    
    #控制台输出的相关设置
    log4j.appender.console = org.apache.log4j.ConsoleAppender
    log4j.appender.console.Target = System.out
    log4j.appender.console.Threshold=DEBUG
    log4j.appender.console.layout = org.apache.log4j.PatternLayout
    log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
    
    #文件输出的相关设置
    log4j.appender.file = org.apache.log4j.RollingFileAppender
    log4j.appender.file.File=./log/kuang.log
    log4j.appender.file.MaxFileSize=10mb
    log4j.appender.file.Threshold=DEBUG
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
    
    #日志输出级别
    log4j.logger.org.mybatis=DEBUG
    log4j.logger.java.sql=DEBUG
    log4j.logger.java.sql.Statement=DEBUG
    log4j.logger.java.sql.ResultSet=DEBUG
    log4j.logger.java.sql.PreparedStatement=DEBUG
    
  3. 配置log4j为日志的实现

    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    
  4. Log4j测试运行.

5.分页

5.1 使用Limit分页

使用Mybatis实现分页,核心SQL

  1. 接口

    //分页
    List<Student> getStuByLimit(Map<String, Integer> map);
    
  2. Mapper.xml

    <!--分页-->
    <select id="getStuByLimit" parameterType="map" resultMap="StudentMap">
        select * from school.student limit #{startIndex},#{pageSize}
    </select>
    
  3. 测试

    @Test
    public void getStuByLimit() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
    
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    
        HashMap<String, Integer> map = new HashMap<String, Integer>();
    
        map.put("startIndex",1);
        map.put("pageSize",3);
    
        List<Student> stuList = mapper.getStuByLimit(map);
    
        for (Student student : stuList) {
            System.out.println(student);
    
        }
    
        sqlSession.close();
    }
    

5.2 RowBounds分页

5.3 分页插件

MyBatis 分页插件PageHelper

6.使用注解开发

  1. 注解在接口上实现

        //使用注解开发
        @Select("select * from student")
        List<Student> getStudent();
    
        @Insert("insert into student(id,name,score) values (#{id},#{name},#{score})")
        int addStu(Student student);
    
        @Delete("delete from student where id = #{id}")
        int dropStu(@Param("id") int id);
    
        @Update("update student set name = #{name},score = #{score} where id = #{id}")
        int updateStu(Student student);
    
        @Select("select * from student where id = #{id}")
        Student selectById(@Param("id") int id);
    
  2. 需要再核心配置文件中绑定接口!

    <!--每一个Mapper.xml文件都需要在Mybatis核心配置文件中注册-->
    <mappers>
        <mapper resource="com/guo/dao/StudentMapper.xml"/>
    </mappers>
    
  3. 测试

关于@Param() 注解

  • 基本类型的参数或者String类型,需要加上
  • 引用类型不需要加
  • 如果只有一个基本类型的话,可以忽略,但是建议大家都加上!
  • 我们在SQL中引用的就是我们这里的 @Param() 中设定的属性名!

7.Lombok

Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java.
Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.
  • java library
  • plugs
  • build tools
  • with one annotation your class

使用步骤:

  1. 在IDEA中安装Lombok插件!

  2. 在项目中导入lombok的jar包

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>
    
  3. 在实体类上加注解即可!

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    
@Getter and @Setter
@FieldNameConstants
@ToString
@EqualsAndHashCode
@AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor
@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger
@Data
@Builder
@Singular
@Delegate
@Value
@Accessors
@Wither
@SneakyThrows

说明:

@Data:无参构造,get、set、tostring、hashcode,equals
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@ToString
@Getter

8.多对一,一对多处理

例:

  • 多个学生,对应一个老师
  • 对于学生这边而言, 关联 (association).. 多个学生,关联一个老师 【多对一】
  • 对于老师而言, 集合 (collection), 一个老师,有很多学生 【一对多】

多对一:

按照结果嵌套处理

<!--
    思路:
        1. 查询所有的学生信息
        2. 根据查询出来的学生的tid,寻找对应的老师!  子查询
    -->
<!--按照结果嵌套处理-->
<select id="getStudent" resultMap="StudentTeacher">
    select s.id sid,s.name sname,t.name tname
    from student s,teacher t
    where s.tid = t.id;
</select>

<resultMap id="StudentTeacher" type="Student">
    <result property="id" column="sid"/>
    <result property="name" column="sname"/>
    <association property="teacher" javaType="Teacher">
        <result property="name" column="tname"/>
    </association>
</resultMap>

一对多:

按照结果嵌套处理

<!--按结果嵌套查询-->
<select id="getTeacher" resultMap="TeacherStudent">
    select s.id sid, s.name sname, t.name tname,t.id tid
    from student s,teacher t
    where s.tid = t.id and t.id = #{tid}
</select>

<resultMap id="TeacherStudent" type="Teacher">
    <result property="id" column="tid"/>
    <result property="name" column="tname"/>
    <!--复杂的属性,我们需要单独处理 对象: association 集合: collection
        javaType="" 指定属性的类型!
        集合中的泛型信息,我们使用ofType获取
        -->
    <collection property="students" ofType="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="tid" column="tid"/>
    </collection>
</resultMap>

多对多

假设有三个表: sys_user, sys_role, sys_permission

新建两个中间表: sys_user_role, sys_role_permission

/*==============================================================*/
/* DBMS name:      MySQL 5.0                                    */
/* Created on:     2020/09/29 8:46:08                           */
/*==============================================================*/
 
 
drop table if exists sys_permission;
 
drop table if exists sys_role;
 
drop table if exists sys_role_permission;
 
drop table if exists sys_user;
 
drop table if exists sys_user_role;
 
/*==============================================================*/
/* Table: sys_permission                                        */
/*==============================================================*/
create table sys_permission
(
   id                   int(10) not null,
   permName             varchar(50),
   permTag              varchar(50),
   primary key (id)
);
 
/*==============================================================*/
/* Table: sys_role                                              */
/*==============================================================*/
create table sys_role
(
   id                   int(10) not null,
   roleName             varchar(50),
   roleDesc             varchar(50),
   primary key (id)
);
 
/*==============================================================*/
/* Table: sys_role_permission                                   */
/*==============================================================*/
create table sys_role_permission
(
   role_id              int(10),
   perm_id              int(10)
);
 
/*==============================================================*/
/* Table: sys_user                                              */
/*==============================================================*/
create table sys_user
(
   id                   int(10) not null,
   username             varchar(50),
   realname             varchar(50),
   password             varchar(100),
   createDate           date,
   lastLoginTime        date,
   enabled              int(1) default 1,
   accountNonExpired    int(1) default 1,
   accountNonLocked     int(1) default 1,
   credentialsNonExpired int(1) default 1,
   primary key (id)
);
 
/*==============================================================*/
/* Table: sys_user_role                                         */
/*==============================================================*/
create table sys_user_role
(
   user_id              int(10),
   role_id              int(10)
);
 
alter table sys_role_permission add constraint FK_Reference_3 foreign key (role_id)
      references sys_role (id) on delete restrict on update restrict;
 
alter table sys_role_permission add constraint FK_Reference_4 foreign key (perm_id)
      references sys_permission (id) on delete restrict on update restrict;
 
alter table sys_user_role add constraint FK_Reference_1 foreign key (user_id)
      references sys_user (id) on delete restrict on update restrict;
 
alter table sys_user_role add constraint FK_Reference_2 foreign key (role_id)
      references sys_role (id) on delete restrict on update restrict;
//根据用户的名字查询所具有的权限.
select p.id, p.permName, p.permTag
from sys_user u
left join sys_user_role ur.id = u,id
left join sys_role r.id = ur.id
left join sys_role_permission rp.id = r.id
left join sys_permission p.id = rp.id
where u.username = #{username}

9.动态 SQL

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

IF

choose (when, otherwise)

<select id="queryBlogChoose" parameterType="map" resultType="blog">
    select * from mybatis.blog
    <where>
        <choose>
            <when test="title != null">
                title = #{title}
            </when>
            <when test="author != null">
                and author = #{author}
            </when>
            <otherwise>
                and views = #{views}
            </otherwise>
        </choose>
    </where>
</select>

trim (where,set)

select * from mybatis.blog
<where>
    <if test="title != null">
        title = #{title}
    </if>
    <if test="author != null">
        and author = #{author}
    </if>
</where>
<update id="updateBlog" parameterType="map">
    update mybatis.blog
    <set>
        <if test="title != null">
            title = #{title},
        </if>
        <if test="author != null">
            author = #{author}
        </if>
    </set>
    where id = #{id}
</update>

所谓的动态SQL,本质还是SQL语句 , 只是我们可以在SQL层面,去执行一个逻辑代码

SQL片段

有的时候,我们可能会将一些功能的部分抽取出来,方便复用!

  1. 使用SQL标签抽取公共的部分

    <sql id="if-title-author">
        <if test="title != null">
            title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
    </sql>
    
  2. 在需要使用的地方使用Include标签引用即可

    <select id="queryBlogIF" parameterType="map" resultType="blog">
        select * from mybatis.blog
        <where>
            <include refid="if-title-author"></include>
        </where>
    </select>
    

注意事项:

  • 最好基于单表来定义SQL片段!
  • 不要存在where标签

Foreach

select * from user where 1=1 and 

  <foreach item="id" collection="ids"
      open="(" separator="or" close=")">
        #{id}
  </foreach>

(id=1 or id=2 or id=3)

10.缓存

10.1 简介

查询  :  连接数据库 ,耗资源!
	一次查询的结果,给他暂存在一个可以直接取到的地方!--> 内存 : 缓存
	
我们再次查询相同数据的时候,直接走缓存,就不用走数据库了
  1. 什么是缓存 [ Cache ]?

    • 存在内存中的临时数据。
    • 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
  2. 为什么使用缓存?

    • 减少和数据库的交互次数,减少系统开销,提高系统效率。
  3. 什么样的数据能使用缓存?

    • 经常查询并且不经常改变的数据。【可以使用缓存】

10.2 Mybatis缓存

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

  • MyBatis系统中默认定义了两级缓存:一级缓存二级缓存

    • 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)

    • 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。

    • 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

10.3一级缓存

  • 一级缓存也叫本地缓存: SqlSession

    • 与数据库同一次会话期间查询到的数据会放在本地缓存中。

    • 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;

小结:一级缓存默认是开启的,只在一次SqlSession中有效,也就是拿到连接到关闭连接这个区间段!

一级缓存就是一个Map。

10.4 二级缓存

  • 二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存
  • 基于namespace级别的缓存,一个名称空间,对应一个二级缓存;
  • 工作机制
    • 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
    • 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
    • 新的会话查询信息,就可以从二级缓存中获取内容;
    • 不同的mapper查出的数据会放在自己对应的缓存(map)中;

步骤:

  1. 开启全局缓存

    <!--显示的开启全局缓存-->
    <setting name="cacheEnabled" value="true"/>
    
  2. 在要使用二级缓存的Mapper中开启

    <!--在当前Mapper.xml中使用二级缓存-->
    <cache/>
    

    也可以自定义参数

    <!--在当前Mapper.xml中使用二级缓存-->
    <cache  eviction="FIFO"
           flushInterval="60000"
           size="512"
           readOnly="true"/>
    
  3. 测试

小结:

  • 只要开启了二级缓存,在同一个Mapper下就有效
  • 所有的数据都会先放在一级缓存中;
  • 只有当会话提交,或者关闭的时候,才会提交到二级缓冲中!

11.后续总结

  1. dao层的接口与Mapper.xml相连, 其中dao层的@Param()的参数就是SQL语句里的#{}.

  2. 在service层的接口实现类中,覆盖重写的方法return的是传入的数,不需要加""

    @Override
    public List<Permission> getPermissionByUsername(String userName) {
        return permissionMapper.getPermissionByUsername(userName);
    }
    
原文地址:https://www.cnblogs.com/gzp5608/p/13743770.html