Mybatis(2)——关联查询,延迟加载,逆向工程

1 关联查询

1 一对一查询

数据结构:
在这里插入图片描述

1.1 使用 resultType

使用 resultType, 创建 Empl 的包装类,此包装类(Vo)中包括了员工信息和部门信息,这样返回对象的时候, mybatis 自动把用户信息也注入进来了。

创建员工包装类继承员工类:
在这里插入图片描述
修改 mapper 接口:

public interface EmplMapper {
	// 查询所有员工
	List<EmplVo> findAll();
}

在这里插入图片描述
注意:resultMap 的 id 和 select后面的resultMap对应。注意type和resultType中的内容。

1.2 使用 resultMap

使用 resultMap,定义专门的 resultMap 用于映射一对一查询结果。
修改 pojo,加入对应的关联 pojo 的属性:在 Employee 中添加:
在这里插入图片描述
在这里插入图片描述
配置说明:
association:配置一对一关系映射
| – property;Empl 实体类中的Dept 的属性名
| – javaType:属性的类型
| – column:关联的数据库字段名
id:关联查询的标识
| – column:主表(dept)的主键
| – property:主表主键列所对应的 pojo 的属性名
result:其他字段属性映射
| – column:表字段列名
| – property:表中所对应 pojo 的属性名

注意:在使用association 进行关联映射后,无论字段列名与 pojo 类属性名是否一致,都需要使用 id 或者 result 进行配置,否则无法映射成功,属性为null。

1.3 使用 resultMap,配置不同mapper

效率最高,利用mybatis一级缓存特性。
1.实体Employee添加 private Dept dept;getter/setter方法

2.接口中有方法findAll(); 配置EmplMapper.xml

<mapper namespace="com.java201.dao.EmployeeMapper">
    <resultMap id="emplDept" type="Employee">
        <id column="id" property="id"/>
        <result column="empl_name" property="emplName"/>
        <result column="empl_gender" property="emplGender"/>
        <result column="empl_job" property="emplJob"/>
        <result column="empl_salary" property="emplSalary"/>
        <result column="dept_id" property="deptId"/>
<!--        配置一对一关系关联-->
        <association column="dept_id" property="dept" javaType="dept" select="com.java201.dao.DeptMapper.findById">
<!--利用mybatis一级缓存特性,效率高-->
        </association>
    </resultMap>
    <select id="findAll" resultMap="emplDept">
        select * from employee;
    </select>
</mapper>

3.接口DeptMapper添加方法findById

扫描二维码关注公众号,回复: 8693898 查看本文章
public interface DeptMapper {
    List<Dept> findAll();
    Dept findById(Integer id);
}

4.配置DeptMapper.xml

<mapper namespace="com.java201.dao.DeptMapper">
    <select id="findAll" resultType="com.java201.pojo.Dept">
        select * from dept
    </select>
    <resultMap id="deptMap" type="Dept">
        <id column="id" property="id"/>
        <result property="deptName" column="dept_name"/>
        <result column="dept_desc" property="deptDesc"/>
    </resultMap>
    // 这里要配置resultType="deptMap",不然就会数据库下划线转驼峰,取不出来值
    <select id="findById" resultType="deptMap" parameterType="integer">
        select * from dept where id=#{id}
    </select>
</mapper>

当 数据库中dept_id都为1时,测试的时候,只会查询一次dept表(id=1),这样就体现出了一级缓存的优势,提高查询效率。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.2 一对多查询

查询一个部门下的所有员工 —— 一对多

  1. 修改pojo
    在这里插入图片描述
  2. 配置mapper
    DeptMapper.xml(重点在collection)
    在这里插入图片描述
    EmployeeMapper.xml
    在这里插入图片描述
  3. 测试
    在这里插入图片描述
    结果:
    在这里插入图片描述

1.3 多对多查询

主要通过角色去关联查询权限,知道某个角色,就知道他的权限数据。

标准 权限 设计表:5张表
用户表:user;
用户-角色
角色表:role
角色-权限;
权限表:access

案例:
https://blog.csdn.net/weixin_45044097/article/details/103052705

2 mybatis延迟加载

2.1 概念

举例说明什么是延迟加载:
我们想查询一个员工的信息,同时还要查询出他所在的部门,我们可以先查询出员工的信息,当需要部门信息的时候,再根据员工的和部门关联的 dept_id 去发送一次查询,获取部门信息,把对部门信息的按需查询就是延迟加载。
所以延迟加载 即先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能。因为查询单表要比关联查询多张表速度要快。

2.2 association实现

association 和 collection 具备延迟加载的功能,拿 association 来说明,collection 和 association 使用的方法都是一样的。需求就是上面提到的,查询员工并且关联查询部门,查询部门使用延迟加载。由上面的分析可知,延迟加载要查询两次,第二次是按需查询,之前一对一关联查询的时候只需要查一次,把员工和部门信息都查出来了,所以只要写一个 statement 即可。 但是延迟加载查两次,所以要有两个 statement,并且这两个statement 分别在不同的映射文件中。mybatis 实现延迟加载的方式是由 cglib 生成代理对象,所以需要在 pom.xml 中引入 cglib 的依赖。

<dependency>
	<groupId>cglib</groupId>
	<artifactId>cglib</artifactId>
	<version>2.2.2</version>
</dependency>

(动态代理,jdk代理实现接口的类)

2.3 具体实现步骤

  1. 下载cglib依赖
  2. 需要在核心配置文件sqlMapConfig.xml中的setting中手动开启延迟加载,关闭立即加载。
// 开启延迟加载
<setting name="lazyLoadingEnabled" value="true"/>
// 关闭立即加载
<setting name="aggressiveLazyLoading" value="false"/>
  1. mapper接口,mapper.xml配置和一对一查询效率高的方式的配置一致。

3 mybatis逆向工程

在写 mybatis 的时候有很多代码其实都差不多,比如对一个表的CURD 操作,我们重复去写这些代码没有什么意义,所以逆向工程帮我们解决这个问题(代码生成器)。

3.1 说明

官方自带逆向工程,但是并不是很方便,推荐使用插件mybatisCodeHelper;
收费!!(免费用几天)

3.2 自动生成代码

1.选择生成代码
2.配置

4 分页

4.1 分页步骤

select * from user limit 5; //限制5条
select * from user limit 0,5;//开始下标,长度Length
  1. 下载依赖
  2. 核心配置文件中 配置拦截器插件(environment后面)
<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
        <property name="param1" value="value1"/>
	</plugin>
</plugins>
  1. 代码中使用
//第二种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.startPage(1, 10);//开始的页数pageNum,页面大小pageSize(显示条数)
List<Country> list = countryMapper.findAll();

参考官方文档:
https://pagehelper.github.io/docs/howtouse/

5 通用mapper

极大的方便开发人员,可以随意按照自己需要选择的通用方法,还可以很方便的开发自己的通用方法。
简化单表操作(CRUD)
支持单表操作,不支持通用的多表联合查询。
不是表中的字段的属性必须加@Transient注解(序列化)
不支持devtools热加载

参考官方文档:
https://mapperhelper.github.io/docs/

发布了79 篇原创文章 · 获赞 7 · 访问量 1840

猜你喜欢

转载自blog.csdn.net/weixin_45044097/article/details/103042249