Mybatis-详细开发

612 阅读11分钟

一.什么是Mybatis?

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

二.什么是持久化?

将内存中数据保存在磁盘中

三.什么是持久层?

利用Mybatis操作代码Mapper/dao,实现数据的持久化

四.什么是高级映射?

对象与数据表的映射
对象中属性与数据表的字段映射

总结: Mybatis是持久层框架,内部整合了JDBC,以对象的方式操作数据库.

五.创建Mybatis项目

5.1新建项目

image.png

5.2导入pom.xml依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--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>
    </dependencies>

5.3安装插件

查看链接即可harrylyj.blog.csdn.net/article/det…

官方文档

5.4链接数据库

#配置端口号
server:
  port: 8091

#管理数据源
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
    password: root

#SpringBoot整合Mybatis-plus
mybatis:
  #指定别名包
  type-aliases-package: com.jt.pojo
  #扫描指定路径下的映射文件
  mapper-locations: classpath:/mappers/*.xml
  #开启驼峰映射
  configuration:
    map-underscore-to-camel-case: true
  # 一二级缓存默认开始 所以可以简化

#打印mysql日志
logging:
  level:
    com.jt.mapper: debug

5.5项目的目录

1644579663(1).png

六.增删改查

6.1Mybatis新增

6.1.1 新增测试案例

@Test
    public void testInsert(){
        User user = new User();
        user.setId(100).setName("元宵节").setAge(18).setSex("女");
        //写法1: 不需要服务器返回值
        userMapper.saveUser(user);
        //写法2: 需要返回值,返回影响的行数
        int rows = userMapper.saveUser2(user);
        System.out.println("影响的行数:"+rows);
    }

6.1.2编辑Mapper接口文件

 void saveUser(User user);
 int saveUser2(User user);

6.1.3编辑Mapper映射文件

 <!--1.新增操作
        语法:
            1.取值操作 #{属性名称}
            2.只有查询需要写resultType
            3.如果是"更新"操作可以自动返回影响的行数
            4.#{id}:填写的值要与
    -->
    <insert id="saveUser" >
        insert into demo_user(id,name,age,sex)
            value (null,#{name},#{age},#{sex})
    </insert>

    <insert id="saveUser2">
        insert into demo_user(id,name,age,sex)
            value (null,#{name},#{age},#{sex})
    </insert>

6.2Mybatis修改案例

6.2.1修改测试案例

/**
     * 要求:将ID=232的数据,将name改为"清明节"
     */
    @Test
    public void testUpdate(){
        User user = new User();
        user.setId(232).setName("清明节");
        userMapper.updateUserById(user);
    }

6.2.2编写Mapper接口文件

 void updateUserById(User user);

6.2.3编写Mapper映射文件

 <!--
        关于取值操作的说明: #{属性值},${属性值}
        1.#号取值采用占位符的方式  更加安全 防止sql注入攻击!!!
        2.$符一般的使用场景 以字段为参数时使用.
        3.使用#号时,默认会添加一对""号
        4.能使用#号 绝不用$
    -->
    <update id="updateUserById">
        update demo_user set name=#{name}
        where id = ${id}
    </update>

6.3Mybatis查询案例

6.3.1查询测试案例

 /**
     * 根据Id查询数据  id=7
     * 总结: 如果结果唯一,使用POJO对象接收
     *      如果结果不唯一,使用List<POJO>集合接收
     */
    @Test
    public void testFindUserById(){
        int id = 7;
        User user = userMapper.findUserById(id);
        System.out.println(user);
    }

6.3.2编写Mapper接口文件

 User findUserById(int id);

6.3.3编写Mapper映射文件

<select id="findUserById" resultType="com.jt.pojo.User">
        select * from demo_user where id=#{id}
    </select>

6.4Mybatis删除案例

6.4.1删除测试案例

@Test
    public void testFindUserById(){
        int id = 7;
        User user = userMapper.findDeteleById(id);
        System.out.println(user);
    }

6.4.2编写Mapper接口文件

 User findUserById(int id);

6.4.3编写Mapper映射文件

<delete id="findUserById">
        delete * from demo_user where id=#{id}
</delete>

七.关于Mybatis的特殊用法

7.1Map用法

7.1.1编辑测试类

 /**
     * Mybatis Map查询
     * 需求: 查询age>18  and age < 100的用户
     * Sql: select * from demo_user where age>18 and age<100
     * 难点: POJO对象无法传递多个同名属性!
     * 解决方案: 如果遇到同名属性则可以封装为Map集合
     */
    @Test
    public void testFindByMap(){
        Map map = new HashMap();
        map.put("minAge",18);
        map.put("maxAge",100);
        List<User> list = userMapper.findUserByMap(map);
        System.out.println(list);
    }

7.1.2编写Mapper接口文件

 List<User> findUserByMap(Map map);

7.1.3编写Mapper映射文件

 <!--
        取值用法: #{对象中的属性/Map中的key}
        转义字符:
            大于 > &gt;
            小于 < &lt;
            与号 & &amp;
        万能转义标签: <![CDATA[ 内容 ]]>
        xml流文件   报文 更加安全  解析复杂
        字节流信息: 直播!!!
    -->
    <select id="findUserByMap" resultType="com.jt.pojo.User">
        <!--select * from demo_user where age>#{minAge} and age &lt; #{maxAge}-->
        <![CDATA[
            select * from demo_user where age>#{minAge} and age < #{maxAge}
        ]]>

    </select>

7.2关于#号与$符号区别

7.2.1测试案例

 /**
     *  指定字段查询数据
     */
    @Test
    public void testFindByColumn(){
        String column = "age";
        int value = 18;
        Map map = new HashMap();
        map.put("column",column);
        map.put("value",value);
        List<User> list = userMapper.findByColumn(map);
        System.out.println(list);
    }

7.2.2编写Mapper接口文件

List<User> findByColumn(Map map);

7.2.3编写Mapper映射文件

 	<!--使用$符 获取字段信息 -->
    <select id="findByColumn" resultType="com.jt.pojo.User">
        select * from demo_user where ${column}=#{value}
    </select>

7.3@Param注解用法

7.3.1测试代码

/**
     * 说明: 简化Map集合操作
     * Mybatis中不允许直接传递多个数据,如果是多值需要转化为单值.\
        1.将多值数据转化为POJO对象.\
        2.将多值数据转化为Map集合. Mybatis为转化Map集合提供了注解@Param
     */
    @Test
    public void testFindByParam(){
        int minId = 10;
        int maxId = 100;
        List<User> list = userMapper.findUserByMId(minId,maxId);
        System.out.println(list);
    }

7.3.2编写Mapper接口文件

List<User> findUserByMId(@Param("minId") int minId,
                             @Param("maxId") int maxId);

7.3.3编写Mapper映射文件

  <select id="findUserByMId" resultType="com.jt.pojo.User">
        select * from demo_user where id > #{minId} and id &lt; #{maxId}
    </select>

7.4模糊查询

7.4.1编辑测试类

 /**
     * 业务需求: 查询name中包含"君"字的数据
     * Sql: select * from demo_user where name like "%君%"
     */
    @Test
    public void findUserByLike(){
        String name = "君";
        List<User> list = userMapper.findUserByLike(name);
        System.out.println(list);
    }

7.4.2编写Mapper接口文件

 List<User> findUserByLike(String name);

7.4.3编写Mapper映射文件

	<!--别名包: com.jt.pojo 只要定义成功之后,以后写类名即可-->
    <select id="findUserByLike" resultType="User">
        select * from demo_user where name like "%"#{name}"%"
    </select>

7.5Sql简化标签

<!--
        别名包: com.jt.pojo 只要定义成功之后,以后写类名即可
    -->
    <select id="findUserByLike" resultType="User">
         <include refid="selectDemoUser"/> where name like "%"#{name}"%"
    </select>

    <!--Sql标签介绍:
        可以将重复的/复杂的/特殊的Sql封装到Sql标签中
    -->
    <sql id="selectDemoUser">
        select id,name,age,sex from demo_user
    </sql>

7.6Mybatis的"集合"操作list/array/map

7.6.1业务需求

说明: Mybatis如果遇到批量操作,则可以使用集合的类型
案例: 查询id=1,3,4,5,6的数据
Sql: select * from demo_user where id in (1,3,4,5,6)
in的限定条件: 如果海量数据(500万)查询时不要使用in.尽可能使用主键查询.

//List ids = Arrays.asList(array);
    @Test
    public void findUserByIn(){
        Integer[] array = {1,3,4,5,6};
        List<User> list = userMapper.findUserByIn(array);
        System.out.println(list);
    }

7.6.2编辑Mapper接口文件

List<User> findUserByIn(Integer[] array);

7.6.3编辑Mapper映射文件

<!--
        Mybatis集合操作
            1."集合"的类型: array/list/Map集合
            2. 目的:从集合中获取其中的数据. 一个一个取值
            3. 方案: Mybatis提供了循环遍历的方式
            4. 语法:
                    4.1collection需要遍历的数据
                        数组:     collection="array"
                        List集合: collection="list"
                        Map<key,array/list>集合:  collection="map中的key"
                    4.2 open/close  开始和接收标签
                    4.3 item: 定义取值的变量  通过#{xx}获取数据
                    4.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>

8.1主键自增

8.1.1方法一

<insert id="insertBook" useGeneratedKeys="true" keyProperty="id">
    insert into t_book (b_name,author) values (#{name},#{author});
</insert>

这种方式比较简单,就是在插入节点上添加 useGeneratedKeys 属性,同时设置接收回传主键的属性。配置完成后,我们执行一个插入操作,插入时传入一个对象,插入完成后,这个对象的 id 就会被自动赋值,值就是刚刚插入成功的id。

8.1.2方法二

第二种方式则是利用MySQL自带的 last_insert_id() 函数查询刚刚插入的id

<insert id="insertBook">
    <selectKey keyProperty="id" resultType="java.lang.Integer">
        SELECT LAST_INSERT_ID()
    </selectKey>
    insert into t_book (b_name,author) values (#{name},#{author});
</insert>

这种方式是在 insert 节点中添加 selectKey 来实现主键回填,实际上这种方式的功能更加丰富,因为 selectKey 节点中的 SQL 我们既可以在插入之前执行,也可以在插入之后执行(通过设置节点的 Order 属性为 AFTER 或者 BEFORE 可以实现),具体什么时候执行,还是要看具体的需求,如果是做主键回填,我们当然需要在插入 SQL 执行之后执行 selectKey 节点中的 SQL。

注意第二种方式一样也要通过设置 keyProperty 来指定将查询到的数据绑定到哪个属性上。

八.Mybatis-动态SQL

8.1 if-where标签

8.1.1 编写测试类

/**
     * 需求: 根据对象中不为null的属性,查询数据
     * 业务说明: 由于数据来源于前端服务器.参数可以是任意的数据,
     * 但是要求后端能实现所有数据的查询.  一个方法通用!!!
     */
    @Test
    public void testFindUser(){
        User user = new User();
        user.setAge(3000).setSex("男");
        List<User> list = userMapper.findUser(user);
        System.out.println(list);
    }

8.1.2编写Mapper接口文件

@Mapper //为接口创建代理对象,交给Spring容器管理
public interface UserMapper2 {
    List<User> findUser(User user);
}

8.1.3编写Mapper映射文件

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

    <!--
        Mybatis:动态sql语法 根据业务条件,动态拼接Sql
        语法:
              1. if标签: 如果判断为真 则拼接sql
              2. where标签: 去除where后边多余1个and/or
    -->
    <select id="findUser" 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>
</mapper>

8.2 if-set标签

编写测试类

 /**
     * 业务说明:
     *      根据对象中不为null的属性进行更新操作,id当做唯一条件.
     * 需求:
     *      将id=5的用户的 name改为 御弟哥哥  年龄 18
     */
    @Test
    public void testUpdate(){
        User user = new User();
        user.setId(5).setName("御弟哥哥").setAge(18);  //sex=null
        userMapper.updateUser(user);
        System.out.println("修改操作成功!!!");
        }

编写Mapper接口

void updateUser(User user);

编写Mapper映射文件

<!--
        思考: 如何做到通用
        使用动态sql:根据对象中不为null的属性当做set条件
        标签说明: set标签在修改操作中去除1个多余的,号
    -->
    <update id="updateUser">
        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>

8.3动态Sql-choose、when、otherwise

8.3.1编写测试类

说明: 如果不想使用所有的条件可以使用choose 类似于java中的switch 语法\
如果name有值,则按照name查询, if\
如果age有值,则按照age查询, else-if\
否则按照sex查询数据. else
 @Test
    public void testFindChoose(){
        User user = new User();
        user.setName("御弟哥哥").setAge(18).setSex("男");
        List<User> list = userMapper.findUserChoose(user);
        System.out.println(list);
    }

8.3.2编写Mapper接口文件

List<User> findUserChoose(User user);

8.3.3编写Mapper映射文件

 <!--分支结构的语法-->
    <select id="findUserChoose" resultType="User">
        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>
    </select>
标签属性解释
resultTypeSql语句执行的返回值
parameterType参数类型
id自定义
collerction|表示需要遍历的类型基本上只有:list,array,Map这三中写法。
index|表示循环的下标。
separator|表示每个对象的分隔符(也是进行下一次循环的标识符)。
item|表示当前循环对象。
open|以什么开头。
close|以什么结尾。
columnPrefix|"指定字段映射的前缀"

九.解决属性名和字段名不一致的问题

resultMap标签

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

    <!--
        1.Sql 最好都小写  ctrl + shift + y
                        ctrl + shift + u
        2.结果集映射必须与属性名称一致.
        3.resultType适用于 单表查询&结果集字段与属性一致
        4.如果resultType不满足要求,就是用resultMap完成数据的映射
    -->
    <select id="findAll" resultMap="resultUser">
        select id as user_id,
               name as user_name,
               age user_age,
               sex user_sex
        from demo_user
    </select>

    <resultMap id="resultUser" type="User">
        <!--id表示主键 必须添加-->
        <id column="user_id" property="id"/>
        <!--其它属性-->
        <result column="user_name" property="name"/>
        <result column="user_age" property="age"/>
        <result column="user_sex" property="sex"/>
    </resultMap>

</mapper>

1.可以通过sql语句 加别名的方式 与column保持一致
2.在#{id}中的字段要与property中的 保存一致 所以就是与实体类的属性一致

十.表关联查询

常见的表关联查询的关系

核心: 从一头出发,看向另一头

  1. 一对一 一个用户/一个ID 老公/老婆 一个员工对应一个部门
  2. 一对多 一个老师对应多个学生, 一个部门对应多个员工
  3. 多对一 多对一本质还是一对一
  4. 多对多 一个老师对应多个学生 一对多
    一个学生对应多个老师 一对多 双向一对多

10.1一对一

10.1.1编写实体类

@SpringBootTest
public class TestMybatis4 {

    @Autowired
    private EmpMapper empMapper;
    @Autowired
    private DeptMapper deptMapper;

    //主对象 员工和部门一对一
    @Test
    public void testOneToOne(){
        List<Emp> list = empMapper.findEmp();
        System.out.println(list);
    }
}

10.1.2编写Mapper接口文件

@Mapper
public interface EmpMapper {
    List<Emp> findEmp();
}

10.1.3编写Mapper映射文件

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

    <!--
        规则:
            1.使用关联查询时,不能出现同名字段,否则映射报错
    -->
    <select id="findEmp" resultMap="empRM">
        select emp.*,dept.dept_name
        from emp,dept
        where emp.dept_id = dept.dept_id
    </select>

    <!--
        知识点:
            1.autoMapping="true"
            如果字段名称和属性名称一致,则自动映射
            2.association 一对一对象
            3.javaType    固定搭配 封装对象的类型
            总结:Mybatis可以实现关联查询的数据封装.
                可以为主对象封装数据/同时可以为引用封装数据
    -->
    <resultMap id="empRM" type="Emp" autoMapping="true">
        <!--1.标识主键-->
        <id column="id" property="id"/>

        <!--2.一对一封装 Dept对象-->
        <association property="dept" javaType="Dept" autoMapping="true">
            <id column="dept_id" property="deptId"></id>
            <result column="dept_name" property="deptName"/>
        </association>
    </resultMap>
</mapper>

10.2 一对多

10.2.1编写测试类

 //部门和员工一对多
    @Test
    public void testOneToMore(){

        List<Dept> list = deptMapper.findAll();
        System.out.println(list);
    }

10.2.2编写Mapper接口文件

@Mapper
public interface DeptMapper {
    List<Dept> findAll();
}

10.2.3编写Mapper映射文件

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

    <select id="findAll" resultMap="deptRM">
        select dept.dept_name,emp.* from dept,emp
        where emp.dept_id = dept.dept_id
    </select>

    <!--
        固定搭配: collection + ofType
    -->
    <resultMap id="deptRM" type="Dept" autoMapping="true">
        <id column="dept_id" property="deptId"/>
        <result column="dept_name" property="deptName"/>
        <!-- 一对多封装 -->
        <collection property="emps" ofType="Emp" autoMapping="true">
            <id column="id" property="id"></id>
        </collection>
    </resultMap>

</mapper>

10.3多对多

多对多详细解释1 详细解释2

11.使用注解开发

面向接口编程的根本原因:解耦,可拓展,提高复用,分层开发中、上层不用管具体的实现,大家都遵守共同的标准,使得开发变得容易,规范性好

11.1Mybatis CRUD注解说明

  /**
     * 规则:
     *      1.注解和映射文件标签二选一
     *      2.一个接口方法只能添加一个注解
     *      3.注解只适用于单表的简单操作,复杂操作使用xml映射文件写法
     * @return
     */
    @Select("select * from emp")
  /* @Insert("sql")
    @Update("sql")
    @Delete("sql")*/
    List<Emp> findAll();

11.2@MapperScan注解说明

指定扫描包注解路径 image.png

12. Mybatis 缓存概念

12.1 原生Mybatis操作步骤

12.1.1 Mybatis官网介绍

在这里插入图片描述

5.1.2 Mybatis入门案例

/*
    * Mysql入门实现步骤:
    *   1.编辑mybatis-config.xml核心配置文件
    *       1.1指定数据源配置
    *   2.编辑POJO实体对象.要求与数据库表中的字段一一对应
    *   3.编辑Mapper接口. 添加接口方法
    *   4.编辑接口的实现类(配置文件方式) 要求namespace id  resultType
    *   5.mybatis加载指定的mapper映射文件
    *   6.创建SqlSessionFactory工厂对象
    *   7.获取SqlSession,开启数据库链接
    *   8.获取接口对象(代理对象)
    *   9.调用接口方法,获取返回值结果
    *   10.关闭sqlSession链接.
    * */
    @Test
    public void testDemo1() throws IOException {

        /*创建SqlSessionFactory*/
        String resource = "mybatis/mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        /*从SqlSessionFactory中获取sqlSession*/
        SqlSession sqlSession = sqlSessionFactory.openSession();

        /*获取mapper接口,执行接口方法*/
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        /*Mybatis为接口创建了一个代理对象
            知识点: 框架中通过接口调用方法时,如果没有实现类,则为其创建代理对象
                    代理对象~实现类
         */
        System.out.println(userMapper.getClass());
        List<User> userList = userMapper.findAll();
        System.out.println(userList);

        /*执行之后关闭SqlSession*/
        sqlSession.close();
    }

12.1.3 重要概念说明

SqlSessionFactory
说明: 作用在内部已经关联了数据库,该设计是工厂模式的一种, 目的为了生产SqlSession
类比: factory(面粉/肉/菜…)加工------面条
SqlSession
说明: 用户利用SqlSession 实现数据库CURD操作
类比: 吃面条\

12.2 Mybatis中的缓存

12.2.1 缓存机制

说明: 如果遇到大量的重复请求,如果每次查询 都查询数据库,则性能较低. 如果第一次查询查询数据库,之后的查询执行缓存的操作.则可以提高查询的效率. 储存: 缓存中的数据一般都在内存中

image.png

12.2.2 Mybatis缓存机制-一级缓存

说明: 由同一个SqlSession执行的重复的查询操作.,则可以自动的实现数据的共享.
级别: SqlSession对象

  /**
     * 1.Mybatis 默认条件下一级缓存默认开启的.
     * 2.执行重复操作时,Mybatis一级缓存生效,查询一次数据库.
     * 3.如果查询期间执行更新操作,则一级缓存清空.保证数据都是新的
     */
    @Test
    public void testCache1(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        userMapper.findAll();
        //userMapper.insert(xxx);
        userMapper.findAll();
        userMapper.findAll();
    }

12.2.3 Mybatis缓存机制-二级缓存

说明: 在同一个SqlSessionFactory中生产的SqlSession内实现数据共享.
级别: SqlSessionFactory

/**
     * 规则:
     *  1. 二级缓存默认是开启的.
     *  2. 二级缓存需要标记. cache标签
     *  3. 如果需要使用二级缓存,则应该关闭SqlSession
     *  4. 多线程条件下如果需要实现数据共享,则要求数据必须序列化! 考点!!!
     */
    @Test
    public void testCache2(){
        //对象1
        SqlSession sqlSession1 = sqlSessionFactory.openSession();
        UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
        //线程A
        List<User> list1 = userMapper1.findAll();
        sqlSession1.close();    //只有关闭sqlSession 数据才会保存到缓存中
        //对象2
        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
        //线程B
        List<User> list2 = userMapper2.findAll();
        sqlSession2.close();
    }

12.2.4标识二级缓存

image.png

12.2.5关于对象序列化问题

说明: 在多线程条件下.数据如果需要共享,必须序列化 image.png

<!--    property:实体类对象名称-->
<!--    column:数据库字段名称-->
<!--    javaType:指定属性的类型-->
<!--    type:实体类对象类型-->
<!--    autoMapping:自动映射-->
<!--    ofType:指定集合内部(泛型)的对象类型-->
<!--    collection: 封装集合类型-->
<!--    association:表示一对一封装-->
<!--    resultType:如果单表查询首选-->
<!--    resultMap:如果进行关联查询-->
<!--    autoMapping:开启自动映射-->
<!--columnPrefix:"指定字段映射的前缀"-->