CGB2107-Day05-Mybatis高级

本文详细介绍了MyBatis的一对一映射实现,包括关联查询和子查询两种方式,并探讨了驼峰规则映射的简化配置。同时,讲解了一级缓存和二级缓存的工作原理及其在实际应用中的测试案例。最后,总结了MyBatis的优化策略,包括动态Sql和resultMap的使用,以及如何提升性能。
摘要由CSDN通过智能技术生成

CGB2107-Day05-Mybatis高级

1. Mybatis高级用法

1.1 一对一案例

1.1.1 编辑测试案例
 /**
     * 完成一对一映射.
     * 规定:  一个员工对应一个部门.
     * 选取方向: 员工方
     * 需求: 需要在员工中 完成部门对象的封装.
     */
    @Test
    public void testOneToOne(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
        List<Emp> list = empMapper.findAll();
        System.out.println(list);
        sqlSession.close();
    }
1.1.2 编辑业务接口

img

1.1.3 编辑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.EmpMapper">

    <select id="findAll" resultMap="empRM">
        select e.id,e.name,e.age,d.dept_id,d.dept_name
        from emp e,dept d
        where e.dept_id = d.dept_id
    </select>

    <!--
        规则:
            1.如果映射的字段与对象的属性一致,则可以省略不写.
            2.最好保留主键的字段信息.
            3.如果需要封装单个对象则使用association标签
                3.1 property 代表封装对象的属性
                3.2 javaType 指定属性的类型 注意路径
            4.如果遇到关联封装,必须全部配置映射关系. 如果属性与字段名称一致
              则可以使用autoMapping="true"实现自动映射
    -->
    <resultMap id="empRM" type="Emp" autoMapping="true">
        <id column="id" property="id"/>
        <!--完成Dept对象的封装-->
        <association property="dept" javaType="Dept">
            <id column="dept_id" property="deptId"/>
            <result column="dept_name" property="deptName"/>
        </association>
    </resultMap>
</mapper>

1.2 关联查询和子查询的说明

  1. 关联查询: 通过大量的sql语句 实现数据的关联查询. 其中Sql语句相对复杂. 但是数据封装简单.
  2. 子查询: 可以通过子查询的方式实现复杂的数据封装. 其中Sql几乎都是单表查询,Sql简单, 但是数据封装复杂.

1.3 子查询实现一对一封装

1.3.1 编辑测试方法
/*一对一查询 方式2 where 条件子查询 */
    @Test
    public void testOneToOne2(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
        List<Emp> list = empMapper.findAllWhere();
        System.out.println(list);
        sqlSession.close();
    }
1.3.2 编辑业务接口

在这里插入图片描述

1.3.3 编辑xml映射文件
 <!--where条件的子查询-->
    <select id="findAllWhere" resultMap="empRM2">
        select * from emp
    </select>
    <!--
        子查询的说明:
            1.column="子查询的字段信息"
            2.select= "sql的ID" 作用:根据column中的数据 实现子查询!!!
    -->
    <resultMap id="empRM2" type="Emp" autoMapping="true">
        <id column="id" property="id"></id>
        <association property="dept" javaType="Dept"
                     column="dept_id" select="findDept"/>
    </resultMap>
    <select id="findDept" resultMap="deptRM">
        select * from dept where dept_id = #{dept_id}
    </select>
    <resultMap id="deptRM" type="Dept">
        <id column="dept_id" property="deptId"/>
        <result column="dept_name" property="deptName"/>
    </resultMap>
1.3.4 子查询的调用逻辑图

img

2.1 一对多

2.1.1 业务逻辑

业务说明: 一个部门对应多个员工.

img

2.1.2 一对多Sql语句
/*利用左连接 实现数据查询 */
SELECT d.dept_id,d.dept_name,e.id,e.name,e.age FROM 
dept d
	LEFT JOIN	
emp e	
	ON 
	d.dept_id = e.dept_id
1234567
2.1.3 编辑测试类
/**
     * 一对多的测试  一个部门下有多个用户信息
     */
    @Test
    public void testOneToMore(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
        List<Dept> list = deptMapper.findDept();
        System.out.println(list);
        sqlSession.close();
    }
1234567891011
2.1.4 编辑业务接口

img

2.1.5 编辑xml映射文件
<select id="findDept" resultMap="listRM">
        SELECT d.dept_id,d.dept_name,e.id,e.name,e.age FROM
            dept d
                LEFT JOIN
            emp e
            ON
                d.dept_id = e.dept_id
    </select>

    <!--
        关于一对多 数据封装说明:
            collection: 封装集合的固定写法.
                property:   指定属性
                ofType:     封装List集合的泛型对象
    -->
    <resultMap id="listRM" type="Dept">
        <id column="dept_id" property="deptId"/>
        <result column="dept_name" property="deptName"/>
        <collection property="emps" ofType="Emp" autoMapping="true">
            <id column="id" property="id"/>
        </collection>
    </resultMap>

1.3 驼峰规则映射

说明: 在mybatis映射数据时,经常出现字段名称与属性名称不一致的现象. 但是其中一部分可以采用驼峰规则的方式完成自动映射. 所以有如下的配置.

1.3.1 编辑mybatis-config.xml

官网API:
在这里插入图片描述
配置信息写在configuration 配置标签之下.

 <!--Mybatis的核心配置-->
    <settings>
        <!--开启了驼峰映射规则 dept_id 自动映射到 deptId -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
1.3.2 编辑xml 映射文件
  <!--
        关于一对多 数据封装说明:
            1.collection: 封装集合的固定写法.
                property:   指定属性
                ofType:     封装List集合的泛型对象
            2.如果开启驼峰映射规则,可以简化赋值过程
            3.autoMapping="true" 自动实现映射
            4.一般最好保留主键,为后续扩展提供方便.
    -->
    <resultMap id="listRM" 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"/>
        </collection>
    </resultMap>
12345678910111213141516

1.4 Mybatis中的缓存机制

1.4.1 什么是缓存机制

说明: 引入缓存可以有效降低用户访问物理设备的频次.提高用户响应速度.
扩展:
1.mybatis自身缓存 一级缓存/二级缓存
2.Redis缓存 读取10万次/秒, 写 8.6万次/秒

img

1.4.2 一级缓存

概念说明: Mybatis默认开启一级缓存, 一级缓存可以在同一个SqlSession对象中查询相同的数据,可以实现数据的共享(缓存操作).

一级缓存测试:

/**
     * Mybatis一级缓存: 默认开启
     *      规则: 同一个SqlSession内部有效.
     */
    @Test
    public void cache1(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        List<DemoUser> list1 = demoUserMapper.findAll();
        List<DemoUser> list2 =demoUserMapper.findAll();
        List<DemoUser> list3 =demoUserMapper.findAll();
        System.out.println(list1 == list2);
        sqlSession.close();
    }
1.4.3 二级缓存

说明: 二级缓存mybatis中默认也是开启的.但是需要手动标识. 二级缓存可以在同一个SqlSessionFactory内部有效.

全局配置:

img

img

二级缓存的使用

在这里插入图片描述

  /**
     * 二级缓存说明:
     *     sqlSession查询数据之后,会将缓存信息保存到一级缓存中.但是不会立即将
     *     缓存交给二级缓存保管.如果需要使用二级缓存,则必须将sqlSession业务逻辑执行成功之后关闭.
     */
    @Test
    public void cache2(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
        demoUserMapper.findAll();
        //关闭一级缓存
        sqlSession.close();

        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        DemoUserMapper demoUserMapper2 = sqlSession2.getMapper(DemoUserMapper.class);
        demoUserMapper2.findAll();
        sqlSession2.close();
    }

2. Mybatis框架总结

2.1 ORM思想

概括: 利用对象的方式封装数据库
核心规则:
对象与表一一映射.
对象的属性与表中的字段一一映射.

2.2 Mybaits框架介绍

小结: Mybatis是一个优秀的持久层框架,基于ORM设计思想,实现了以对象的方式操作数据库.

2.3 Mybaits使用步骤

2.3.1 导入jar包

课堂使用的是springboot整合mybatis的版本.但是使用其中的依赖包 3.5.7的版本.
在这里插入图片描述
2). mysql的驱动版本 mysql:mysql-connector-java:8.0.22
3). 驱动的配置: com.mysql.cj.jdbc.Driver
4). 高版本应该使用高版本数据库

2.3.2 编辑核心配置文件
  1. 数据库环境的配置
  2. Mapper接口与xml映射文件的绑定关系.
2.3.3 创建接口/xml映射文件

在这里插入图片描述
说明: 接口与xml映射文件 一对一映射.
在这里插入图片描述

2.3.4 入门案例步骤
  1. 指定mybatis-config.xml的路径
  2. 读取指定的核心配置文件.
  3. 通过SelSessionFactoryBuilder.buid方法创建SqlSessionFactory.
  4. 获取SqlSession
  5. 获取Mapper的接口
  6. 从mapper接口文件中获取业务数据.
  7. 调用xml文件的Sql语句实现数据获取.
  8. mybatis自动封装为对象返回 交给用户处理.

2.4 简化mybatis操作

注解: @BeforeEach 在执行@Test注解之前执行.

2.5 Mybatis的参数封装

1. 封装为实体对象   user对象
2. 更为常用的方式   Map集合
3. 如果传递的数据有多个,则可以使用注解@Param("sex") String sex 封装为Map.
123

2.6 #号 $符用法

  1. 使用#{} 获取数据时,默认有预编译的效果.防止sql注入攻击.
  2. mybatis使用#{}获取数据时,默认为数据添加一对""号.
  3. 当以字段名称为参数时,一般使用${},但是这样的sql慎用. 可能出现sql注入攻击问题.
	小结: 一般条件下能用#{}号,不用${}

2.7 mybatis转义字符

 	xml文件中的转义字符.
            &gt;  > 大于
            &lt;  < 小于
            &amp;  & 号
        说明:如果sql中有大量的转义字符 建议使用转义标签体
        语法: <![CDATA[  xxx内容 报文   ]]>
123456

2.8 Mybatis集合写法

  1. array
  2. list
  3. map
  <!--
        需求: 批量删除多个数据
        难点: 如果使用#{集合}获取的是集合对象的整体.删除无效.
        思路: 将数组拆分为单个数据. 可以通过遍历的方式操作
        语法: mybatis为了参数取值方便,特意封装了遍历的标签 foreach
        关于标签参数说明:
            <foreach collection=""></foreach>
            1.如果传递的参数是数组,     则collection="array"
            2.如果传递的参数是list集合, 则collection="list"
            3.如果传递的参数是Map集合,  则collection="map中的key"

        标签属性说明:
            1.collection 集合的名称
            2.item 每次遍历的数据的形参变量
            3.open 循环的开始标签
            4.close 循环的结束标签
            5.index 循环遍历下标 一般不用
            6.separator 循环遍历的分割符
    -->

2.9 mybatis特殊查询

模糊查询: “%” #{属性}"%" 或者 xxxx.setName("%精%")

2.10 Mybatis优化

1.指定具体的类型的别名
2.别名包
3.别名注解 一般不常用
4.Sql标签 将通用的Sql进行抽取. 通过ID进行引用
5.mybatis的驼峰映射规则 可以自动将下划线去除,映射到属性中.

2.11 动态Sql

  1. if-where where去除多余的and / or
  2. set标签 去除多余的,号
  3. choose when otherwise 用法上和java中的switch类型.

2.12 resultMap用法

当结果集中的字段与属性名不一致时使用. 可以使用驼峰映射规则优化.

2.13 关联关系

2.13.1 一对一

逻辑: 一个员工对应一个部门
表示: 在对象中封装其他对象 对一 封装单个对象 对多封装List集合
在这里插入图片描述

一对一映射标签:
在这里插入图片描述

2.13.2 一对多

在这里插入图片描述

2.14 mybatis中的缓存机制

  1. 一级缓存 默认开启 SqlSession内共享数据.
  2. 二级缓存 默认开启 需要标识 SqlSessionFactory内共享数据.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

管程序猿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值