Mybatis,Springboot对Mybatis的整合及Mybatis基础操作案例

1.Mybatis

官网地址: https://mybatis.org/mybatis-3/zh/index.html

mybatis是什么?有什么特点?
它是一款半自动的ORM持久层框架,具有较高的SQL灵活性,支持高级映射(一对一,一对多),动态SQL,延迟加载和缓存等特性,但它的数据库无关性较低

ORM: Object Relation Mapping,对象关系映射。对象指的是Java对象,关系指的是数据库中的关系模型,对象关系映射,指的就是在Java对象和数据库的关系模型之间建立一种对应关系,java中的实体类与数据库中的表对应,类中的属性和表中的列一一对应。一个对象对应表中的一行数据。
在这里插入图片描述

为什么mybatis是半自动的ORM框架?
用mybatis进行开发,需要手动编写SQL语句。而全自动的ORM框架,如hibernate,则不需要编写SQL语句。用hibernate开发,只需要定义好ORM映射关系,就可以直接进行CRUD操作了。由于mybatis需要手写SQL语句,所以它有较高的灵活性,可以根据需要,自由地对SQL进行定制,也因为要手写SQL,当要切换数据库时,SQL语句可能就要重写,因为不同的数据库有不同的方言(Dialect),所以mybatis的数据库无关性低。虽然mybatis需要手写SQL,但相比JDBC,它提供了输入映射和输出映射,可以很方便地进行SQL参数设置,以及结果集封装。并且还提供了关联查询和动态SQL等功能,极大地提升了开发的效率。并且它的学习成本也比hibernate低很多

1.1在pom.xml 中添加JAR包依赖

 <!--mybatis依赖包-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>

        <!--jdbc依赖包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--添加lombok的包-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

1.2 数据映射

持久层:
1.数据表: 用户的数据信息, 持久化到本地磁盘中
2.POJO: 程序通过对象封装数据信息.

映射关系: 一个POJO对象要求映射一张数据表
1.对象名称 映射数据表表名.
2. 对象的属性 映射数据表中的字段。
3. 一个接口对应一个映射文件

1.3

在这里插入图片描述

编辑pojo对象类

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private Integer id;
    private String name;
    private Integer age;
    private String sex;
}

UserMapper 接口

public interface UserMapper {

    List<User> findAll();
}

1.4编辑mybatis-config.xml配置文件

<?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://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&amp;useUnicode=true&amp;characterEncoding=utf8&amp;autoReconnect=true&amp;allowMultiQueries=true"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!--Mybatis加载Mapper映射文件-->
    <mappers>
        <mapper resource="mappers/UserMapper.xml"/>
    </mappers>
</configuration>

1.5 编辑UserMapper.xml映射文件

说明: 由于mybatis需要操作数据库.编辑Sql语句. 采用xml映射文件维护Sql语句.
关系:
1.一个接口对应一个xml映射文件
2.一个接口方法对应一个映射文件的Sql.

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

<!--namespace是mybaits映射文件的唯一标识,与接口对应-->
<mapper namespace="com.jt.mapper.UserMapper">
    <!--id 表示接口方法
        resultType 返回值结果类型
    -->
    <select id="findAll" resultType="com.jt.pojo.User">
        select * from demo_user
    </select>
</mapper>

1.6 mybatis入门案例

注意:
springboot整合mybatis使用JDK代理模式
springboot默认代理模式CGlib
spring默认代理模式JDK


package com.jt;

import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/*springboot整合mybatis使用JDK代理模式
springboot默认代理模式CGlib
spring默认代理模式JDK
* */
public class TestMybatis {
    /*
     * 规则说明:
     *       1.创建SqlSessionFactory 工厂模式
     *       2.获取SqlSession   理解:数据库链接+传输器对象
     *       3.获取Mapper接口对象
     * */
    @Test
    public void demo1() throws IOException {
        //1.1指定配置文件的根目录
        String resource = "mybatis-config.xml";
        //1.2通过IO流 加载配置文件   import org.apache.ibatis.io.Resources; 包路径
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //实例化工厂对象       .build  建造者模式
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2.获取SqlSession 通过SqlSession可以直接操作数据库
        SqlSession sqlSession = sqlSessionFactory.openSession();

        /*3.获取mapper接口对象
        * 有实现类通过实现类,没有的话通过代理模式获取
        * */
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        System.out.println(userMapper.getClass());//class com.sun.proxy.$Proxy9     JDK代理对象

        //4.调用接口方法
        List<User> userList = userMapper.findAll();
        //System.out.println(userList);
        for (User i:userList) {
            System.out.println(i);
        }
        //5.暂时手动关闭链接
        sqlSession.close();
    }
}

2.SpringBoot简化Mybatis

2.1 关于主启动类异常的说明

提示: “开箱即用” 原则
报错信息:
在这里插入图片描述

在这里插入图片描述
由于Mybatis依赖了JDBC的jar包. 但是该jar包文件是启动项. 当主启动类运行时,开始加载主启动项. 但是JDBC需要链接数据库.所以必须有相关的配置信息.但是此时YML文件中没有数据源的配置.所以报错.

2.2

2.2.1

删除多余文件,修改application.properties文件为application.yml
在这里插入图片描述
配置application.yml文件

#配置端口号  注意缩进(空格)
server:
  port: 8090

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    #yml文件 以0开头的代码需要" "包裹,否则不解析0
    password: root
#3.配置mybatis
mybatis:
#  定义别名包
  type-aliases-package: com.jt.pojo
#  加载所有映射文件
  mapper-locations: classpath:/mappers/*.xml
  #开启驼峰映射
  configuration:
    map-underscore-to-camel-case: true

#打印sql
logging:
  level:
    com.jt.mapper: debug

2.2.2 将Mapper接口交给容器管理

@Mapper 将接口交给Spring容器管理 Map<userMapper,JDK代理对象>

package com.jt.mapper;

import com.jt.pojo.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;
@Mapper  //将接口交给Spring容器管理 Map<userMapper,JDK代理对象>
public interface UserMapper {

    //指定接口方法 查询demo_user的全部数据
    List<User> findAll();

}


2.2.3 编辑测试类

@SpringBootTest
public class TestMybatis {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testDemo1(){
        List<User> userList = userMapper.findAll();
        System.out.println(userList);
    }
}

2.3 mybatis 基础操作

2.3.1 单个参数

//单个参数
    @Test
    public void testDemo2(){
        int id=1;
        User user=userMapper.findUserByID(id);
        System.out.println(user);
    }
<!--#号 预编译-->
    <select id="findUserByID" resultType="com.jt.pojo.User">
        select * from demo_user where id=#{id}
    </select>

2.3.2 多个数据操作 对象封装

/*2. 多个数据操作 对象封装
    * */
    @Test
    public void testDemo3(){
        String name="孙尚香";
        int age=18;
        User user=new User();
        user.setName(name).setAge(age);
       List<User> list=userMapper.findUserByNA(user);
        System.out.println(list);
    }
<!--知识点:别名包:在配置文件(yml)中指定路径:可以自动实现包路径的拼接
        resultType规则:
                1.首先根据别名包匹配,设定
                2.如果匹配不成功,则按照路径匹配

        参数传递规则:1。如果是单个参数,则使用#{key}  获取的参数的值
                    2。如果是对象参数,则使用#{属性}  获取的是属性值
             -->
    <select id="findUserByNA" resultType="User">
        select * from demo_user where name =#{name} and age=#{age}
    </select>

2.3.3-1 如果多个参数不方便使用时 (年龄范围)

/*知识点3.
    * 说明: 如果多个参数不方便使用 User对象封装时,应该使用万能的集合Map
    * */
    @Test
    public void testDemo4(){
        int minAge=18;
        int maxAge=100;
        HashMap<String, Integer> map = new HashMap<>();
        map.put("min", minAge);
        map.put("max", maxAge);
        List<User> list=userMapper.findUserByAge(map);
        System.out.println(list);
    }
<!--
    根据年龄查询数据
        语法:如果传递的参数是Map,则使用#{key}
        xml转义字符:
                >  &gt;
                <  &lt;
                &  &amp;
                万能  <![CDATA[XXX]]>
-->
    <select id="findUserByAge" resultType="User">
        <![CDATA[
        select * from demo_user where age>#{min} and age < #{max}
        ]]>

<!--         select * from demo_user where age>#{minAge} and age &lt; #{maxAge} -->

    </select>

2.3.3-2 利用注解实现数据的封装

@Test
    public void testDemo5(){
        int minAge=18;
        int maxAge=100;
        List<User> list=userMapper.findUserByAge2(minAge,maxAge);
        System.out.println(list);
    }
<select id="findUserByAge2" resultType="User">
        <![CDATA[
        select * from demo_user where age>#{minAge} and age < #{maxAge}
        ]]>
    </select>

2.3.4 模糊查询

 @Test
    public void testDemo7(){
//        String name="%"+"君"+"%";
        String name="小";
        List<User> list=userMapper.findUserByLike(name);
        System.out.println(list);
    }
<!--模糊查询:
    windows系统中不区分大小写
    Linux系统中严格区分大小写(表名)
    -->
    <select id="findUserByLike" resultType="User">
        select <include refid="tableColumn"/> from demo_user where name like "%"#{name}"%"
    </select>

2.3.5 根据多个id查询

@Test
    public void testDemo8(){
        int[] array={1,3,5,7,9};
        List<User> list=userMapper.findUserByIn(array);
        System.out.println(list);

    }
<!--    1.collection   需要遍历的集合
            1.1 数组              关键字: array/list
            1.2 集合                     list/array
            1.3 Map<key,value>           key
        2.open/close  循环体的开始和结束  可以写到循环之外
        3.item  当前遍历数据的变量名
        4.separator  分隔符
    -->
    <select id="findUserByIn" resultType="User">
        select *from demo_user where id in
        <foreach collection="array" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </select>

映射第二种写法,foreach用()包裹就可以不写open="(" close=")"

<select id="findUserByIn" resultType="User">
        select *from demo_user where id in(
        <foreach collection="array" item="id" separator=",">
            #{id}
        </foreach>
        )
    </select>

2.3.6 新增insert

 @Test
    public void testDemo9(){
        User user = new User();
        user.setAge(80).setName("jack").setSex("男");
        int i = userMapper.insertUser(user);
        System.out.println(i);
        System.out.println("新增用户成功");
    }
<insert id="insertUser">
        insert into demo_user(id,name,age,sex) value (null ,#{name},#{age},#{sex})
</insert>

2.3.7 删除delete

@Test
    public void testDemo10(){
        int id=229;
        userMapper.deleteUser(id);
        System.out.println("删除用户成功");
    }
<delete id="deleteUser">
        delete from demo_user where id=#{id}
</delete>

2.3.8 更新update

@Test
    public void testDemo11(){
        int id=228;
        int age=18;
        String name="rose";
        HashMap<Object, Object> map = new HashMap<>();
        map.put("id", 228);
        map.put("age", age);
        map.put("name", name);
        userMapper.updateUser(map);
        System.out.println("修改用户成功");
    }
<delete id="updateUser">
        UPDATE demo_user SET NAME=#{name},age=#{age} WHERE id=#{id}
</delete>

3 动态 sql

3.1 根据对象中不为null的数据,充当where条件

/*
    *需求:根据对象中不为null的数据,充当where条件
    */
    @Test
    public void testDemo(){
        User user = new User();
        user.setSex("男").setAge(18);
        List<User> list =userMapper.findUserList(user);
        for (User user1 : list) {
            System.out.println(user1);
        }
    }
<!--
        动态Sql: 根据对象中不为null的属性当作where条件
        语法:
               1.如果判断成立,则动态拼接条件
               <if test="id !=null ">条件</if>
               2.where标签  去除where后边多余的一个and/or
    -->

<select id="findUserList" resultType="User">
        select * from demo_user
        <where>
            <if test="id !=null">id =#{id}</if>
            <if test="name !=null">and name =#{name }</if>
            <if test="age !=null">and age=#{age}</if>
            <if test="sex !=null">and sex=#{sex}</if>
        </where>
    </select>

3.2 根据对象中不为null的元素,充当set条件

//动态更新
    //根据对象中不为null的元素,充当set条件
    @Test
    public void testDemo2_1(){
        User user = new User();
        user.setId(231).setName("李四");
        userMapper.updateUser(user);
        System.out.println("修改成功");
    }

		@Test
    public void testDemo2_2(){
        User user = new User(232,"jack",null,null);
        userMapper.updateUser(user);
        System.out.println("修改成功");
    }
<update id="updateUser">
       <!-- update demo_user set where id=?-->
        update demo_user
        <set>
            <if test="name !=null">name =#{name},</if>
            <if test="age !=null">age =#{age},</if>
            <if test="sex !=null">sex =#{sex}</if>
        </set>
        where id=#{id}
    </update>

3.3 动态Sql-choose、when、otherwise

 @Test
    public void testDemo3(){
        User user = new User(null,"刘备",null,"男");

        List<User> list=userMapper.selectChoose(user);
        System.out.println(list);

    }
 <select id="selectChoose" resultType="User">
        <!--select *from demo_user where name =? or age?-->
        select * from demo_user
        <where>
            <choose>
                <when test="name !=null">name =#{name}</when>
                <when test="age !=null">age =#{age}</when>
                <otherwise>sex=#{sex}</otherwise>
            </choose>
        </where>
 </select>

3.4 表中的字段与POJO中的属性名称不一致时

当表中的字段与POJO中的属性名称不一致时,需要使用resultMap的方式进行映射.

新建Dog

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class Dog implements Serializable {
    private Integer dogId;
    private String dogName;
    private Integer age;
}

在数据库中新建dog表
在这里插入图片描述
注入

@Autowired(required = false)
    private DogMapper dogMapper;

测试

@Test
    public void TestDog1(){
        List<Dog> list=dogMapper.selectAll();
        for (Dog dog : list) {
            System.out.println(dog);
        }
    }

在这里插入图片描述
表中的字段名称与对象中的属性名称不一致. 结果:数据不能映射.

解决方法1:添加开启驼峰映射
解决方法2:resultMap

3.4.1解决方法1:添加开启驼峰映射

@Test
    public void TestDog1(){
        List<Dog> list=dogMapper.selectAll();
        for (Dog dog : list) {
            System.out.println(dog);
        }
    }

在application.yml添加

#开启驼峰映射
  configuration:
    map-underscore-to-camel-case: false

映射文件

<select id="selectAll" resultType="Dog">
    select *from dog
</select>

3.4.2解决方法2: resultMap

<select id="findAll" resultMap="dogRM">
        select * from dog
</select>

    <resultMap id="dogRM" type="Dog">
        <!--ID:代表主键-->
        <id column="dog_id" property="dogId"/>
        <!--结果集-->
        <result column="dog_name" property="dogName"/>
        <!--<result column="age" property="age"/>-->
    </resultMap>

4 Mybatis 关联关系

4.1 常见关联关系

1.一对一: 一个员工对应一个部门
2.一对多:一个部门对应多个员工
3.多对多(相互的一对多)
一个学生对应多个老师, 一个老师对应多个老师

4.2 一对一封装

4.2.1 表结构封装

说明: 一个员工对应一个部门.
表设计如下:
emp表:
在这里插入图片描述
dept部门表:
在这里插入图片描述

4.3 关联查询Sql

4.3.1 笛卡尔积的方式

select e.id,e.name,e.age,d.dept_id,d.dept_name
    from emp e,dept d
    where d.dept_id=e.dept_id
SELECT e.*,d.* 
    FROM emp e,dept d 
    WHERE d.dept_id=e.dept_id

在这里插入图片描述

4.3.2 连接查询

分类: 1.左连接 2.内连接 3.右连接

SELECT *FROM emp LEFT JOIN dept ON dept.`dept_id`=emp.`dept_id`

在这里插入图片描述

4.4 封装关联关系

4.4.1 封装Emp,Dept对象

public class Emp implements Serializable {

    private Integer id;
    private String name;
    private Integer age;
    //关联关系:一对一   一个员工对应一个部门
    private Dept dept;
//    private Integer deptId;
}
public class Dept implements Serializable {
    private Integer deptId;
    private String deptName;
    //一对多  一个部门对应多个员工
    private List<Emp> emps;
}

4.5 一对一封装(以员工表emp为主表)

4.5.1 测试类

@SpringBootTest
public class TestMybatis3 {

    @Autowired(required = false)
    private EmpMapper empMapper;

    @Test
    public void testEmp1(){
        List<Emp> list=empMapper.findAll();
        for (Emp emp : list) {
            System.out.println(emp);
        }
    }

}

4.5.2 测试接口

@Mapper //将接口交给容器  map(名字 ,JDK代理对象)
public interface EmpMapper {
    List<Emp> findAll();
}

4.5.3 映射文件

映射文件EmpMapper.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">

<!--namespace是mybaits映射文件的唯一标识,与接口对应-->
<mapper namespace="com.jt.mapper.EmpMapper">
    <!--
            规则:
                1.如果操作单表 一般使用resultType
                2.如果进行关联操作,使用resultMap
                3.如果是多表关联操作,则不允许出现重名字段.否则映射失败.
        -->
    <select id="findAll" resultMap="empRM">
    select e.id,e.name,e.age,d.dept_id,d.dept_name
    from emp e,dept d
    where d.dept_id=e.dept_id
    </select>

    <!--
        关于自动映射规则:
            1.没有关联映射时: 如果属性和字段同名,则可以省略不写.
            2.如果有关联映射: 则需要添加自动映射的开关autoMapping="true"
                           该注解只对当前对象有效 如果有多个对象,则需要添加多次
    -->
<resultMap id="empRM" type="Emp" autoMapping="true">
    <!--     主键必填项-->
    <id column="id" property="id"/>
    <!--        知识点:
                    1.一对一关联封装 association标签
                    2.必须指定属性的类型javaType属性
                    3.autoMapping="true" 自动映射
     -->
    <association property="dept" javaType="Dept" autoMapping="true">
        <id column="dept_id" property="deptId"/>
<!--        由于已经开启驼峰规则,下面操作可以不写-->
<!--        <result column="dept_name" property="deptName"/>-->
    </association>
</resultMap>

</mapper>

在这里插入图片描述

4.5.3.1 autoMapping=“true”

autoMapping 自动映射

<association property="dept" javaType="Dept">
        <id column="dept_id" property="deptId"/>
<!--        由于已经开启驼峰规则,下面操作可以不写-->
<!--        <result column="dept_name" property="deptName"/>-->
    </association>

在这里插入图片描述

<select id="findAll" resultMap="empRM">
        select e.*,d.dept_name
           from emp e,dept d
           where d.dept_id=e.dept_id
    </select>
    <resultMap id="empRM" type="emp">
        <id column="id" property="id"/>
        <association property="dept" javaType="Dept">
            <id column="dept_id" property="deptId"/>
        </association>
    </resultMap>

在这里插入图片描述

4.6 一对多封装(以部门表dept为主表)

@Autowired(required = false)
    private DeptMapper deptMapper;


//一对多 Dept部门表为主表
    @Test
    public void testMore(){
        List<Dept> list=deptMapper.OneToMore();
        for (Dept emp : list) {
            System.out.println(emp);
        }
    }

映射文件DeptMapper.xml

		<select id="OneToMore" resultMap="deptRM">
		    SELECT d.dept_name,e.*
		    FROM dept d, emp e
		    WHERE d.dept_id=e.dept_id
		</select>

    <resultMap id="deptRM" type="Dept" autoMapping="true">
        <id column="dept_id" property="deptId"/>
        <collection property="emps" ofType="Emp" autoMapping="true">
            <id column="id" property="id"/>
        </collection>
    </resultMap>

在这里插入图片描述

4.6 映射文件 关联查询总结

在这里插入图片描述

1.如果操作单表 一般使用resultType
2.如果进行关联(多表)操作,使用resultMap
3.如果是多表关联操作,则不允许出现重名字段.否则映射失败.

关于自动映射规则:
1. 没有关联映射时: 如果属性和字段同名,则可以省略不写.
2. 如果有关联映射: 则需要添加自动映射的开关autoMapping=“true”
该注解只对当前对象有效 如果有多个对象,则需要添加多次

  1. 一对一关联封装: association标签
    2.必须指定属性的类型javaType属性
    3.autoMapping=“true” 自动映射
  2. 一对多关联封装: collection标签
    2.必须指定属性的类型ofType属性
    3.autoMapping=“true” 自动映射

5 Mybatis 注解开发

5.1 注解

//利用注解可以根据返回值类型,自动映射
    /*
    * 规则1:注解和映射文件二选一    映射文件为主导
    * 规则2:注解写法一般适用于简单的操作,关联查询不适用
	  @Insert("")
    @Delete("")
    @Update("")
		*/
    @Select("select * from demo_user")
    List<User> findAll();
@Test
    public void testFindAll(){
        List<User> list =userMapper.findAll();
        for (User user : list) {
            System.out.println(user);
        }
    }

5.2 Mybatis缓存

5.2.1 mybatis缓存说明

说明: 如果相同的数据需要多次查询,则可以使用缓存的方式处理,提高用户的响应速度.

mybatis中提供了2种缓存的机制.
一级缓存: SqlSession级别 在同一个sqlSession内实现数据的共享 默认开启
二级缓存: SqlSessionFactory级别 由同一个sqlSessionFactory,生产的SqlSession 数据共享. 默认开启 + 配置

在这里插入图片描述

5.2 一级缓存测试

说明: SpringBoot在使用一二级缓存时,有特殊要求 需要额外注意.

/*测试mybatis的一级二级缓存
    * 现象: 如果采用springBoot的方式进行测试时发现,sql执行多次. 一级缓存无效.
    * 原因: springBoot整合mybatis之后,使用Mapper.find查询时.springBoot默认会开启
    *       多个sqlSession
    * 解决方案: 添加事务注解
    * 知识讲解: springBoot中如果添加了事务注解,则默认采用同一个SqlSession
    * */
    @Test
    @Transactional  //控制事务
    public void testCache1(){
        List<User> userList1 = userMapper.findCache1();
        List<User> userList2 = userMapper.findCache1();
        List<User> userList3 = userMapper.findCache1();
        List<User> userList4 = userMapper.findCache1();
    }

在这里插入图片描述

5.3 二级缓存测试

1.3.1 测试策略

说明: 为了构建多个mapper对象.需要准备多个线程进行测试. 可以通过浏览器让用户发起多次请求.之后测试二级缓存是否有效.
层级代码结构:

  1. Controller 层 SpringMVC 面向接口编程 2:2:1
  2. Service 层 Spring
  3. Mapper/Dao层 Mybatis

5.3.1编辑mapper层

1 编辑mapper映射文件

List<User> findCache1();

2 编辑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.jt.mapper.UserAnnoMapper">

    <select id="findCache1" resultType="User">
        select * from demo_user
    </select>
</mapper>

5.3.2 Service

1.编辑service接口

package com.jt.service;

import com.jt.pojo.User;

import java.util.List;

public interface UserService {

    List<User> findCache1();
}


2.编辑ServiceImpl实现类

package com.jt.service;

import com.jt.mapper.UserAnnoMapper;
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService{

    @Autowired
    private UserAnnoMapper userMapper;

    @Override
    public List<User> findCache1() {

        return userMapper.findCache1();
    }
}


5.3.2 Controller层

package com.jt.controller;

import com.jt.pojo.User;
import com.jt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 要求返回List集合的JSON串
     */
    //@RequestMapping("/findCache")
    @GetMapping("/findCache")
    public List<User> findCache1(){

        return userService.findCache1();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值