Mybatis学习使用(二) —— 关联查询

  • resultMap
  • 分步查询
    • 懒加载
  • 关联查询
    • 一对一
    • 一对多
一、resultMap自定义结果映射规则
  • 1、在xxxMapper.xml 文件中自定义一个javaBean的封装规则

    <!--自定义某个javaBean的封装规则
            type:自定义规则的Java类型
            id:唯一id方便引用 -->
    <resultMap type="com.fc.mybatis.bean.Employee" id="MySimpleEmp">
    <!--指定主键列的封装规则,id定义主键会底层有优化;
            column:指定哪一列
            property:指定对应的javaBean属性 -->
        <id column="id" property="id"/>
        <!-- 定义普通列封装规则 -->
        <result column="last_name" property="lastName"/>
        <!-- 其他不指定的列会自动封装:我们只要写resultMap就把全部的映射规则都写上。即下面的可省略 -->
        <result column="email" property="email"/>
        <result column="gender" property="gender"/>
    </resultMap>
    
    <!-- resultMap:自定义结果集映射规则;  -->
    <!-- 对应EmployeeMapper.java接口的public Employee getEmpById(Integer id); -->
    <select id="getEmpById"  resultMap="MySimpleEmp">
        select * from tbl_employee where id=#{id}
    </select>

    总结:

  • 1、property对应javabean上的属性名
  • 2、column和查询数据库的列名一致(重命名后,要和重命名的名字一致)
二、数据库增改以满足关联查询
  • 一、场景一:
      查询Employee的同时查询员工对应的部门,每个员工有与之对应的部门信息;
    id last_name gender d_id did dept_name (private Department dept;)

    • 1、创建部门表tbl_dept
    • 2、在tbl_employee 员工表上增加部门id列d_id
    • 3、对tbl_employee 员工表增加约束; d_id 列关联上tbl_dept部门表的id

三、一对一查询
  • 1、联合查询:级联属性封装结果集
<!-- dept对应Employee中javabean的部门
    private Department dept;
-->
<resultMap type="com.fc.mybatis.bean.Employee" id="MyDifEmp">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="did" property="dept.id"/>
        <result column="dept_name" property="dept.departmentName"/>
    </resultMap>
  • 2、使用association定义关联的单个javaBean对象的封装规则
    • property="dept":指定哪个属性是联合的对象
    • javaType:指定这个属性对象的类型【不能省略】
<!-- 
        使用association定义关联的单个对象的封装规则;
     -->
    <resultMap type="com.fc.mybatis.bean.Employee" id="MyDifEmp2">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>

        <!--  association可以指定联合的javaBean对象
        property="dept":指定哪个属性是联合的对象
        javaType:指定这个属性对象的类型[不能省略]
        -->
        <association property="dept" javaType="com.fc.mybatis.bean.Department">
            <id column="did" property="id"/>
            <result column="dept_name" property="departmentName"/>
        </association>
    </resultMap>
  • 3、xxxMapper.xml数据库语句
<!--  public Employee getEmpAndDept(Integer id); 
    MyDifEmp / MyDifEmp2
-->
    <select id="getEmpAndDept" resultMap="MyDifEmp">
        SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,
        d.id did,d.dept_name dept_name FROM tbl_employee e,tbl_dept d
        WHERE e.d_id=d.id AND e.id=#{id}
    </select>
  • 4、测试单元类
// 获取接口的实现类对象
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);

System.out.println(mapper.getEmpAndDept(1));
System.out.println(mapper.getEmpAndDept(1).getDept());
  • 5、使用association进行分步查询

    • 1)、先按照员工id查询员工信息
    • 2)、根据查询员工信息中的d_id值去部门表查出部门信息
    • 3)、部门设置到员工中;

    实现步骤

  • 1、在mybatis-config 配置中注册部门DepartmentMapper接口
<mapper class="com.fc.mybatis.dao.DepartmentMapper"/>
  • 2、DepartmentMapper.xml 实现select查询部门信息
<!--public Department getDeptById(Integer id);  -->
<select id="getDeptById" resultType="com.fc.mybatis.bean.Department">
        select id,dept_name departmentName from tbl_dept where id=#{id}
</select>
  • 3、EmployeeMapper.xml
      流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性
    • select: 表明当前属性是调用select指定的方法查出的结果
    • column: 指定将员工表哪一列的值传到部门表中查询
    • d_id 是 tbl_employee员工表的关联部门表id的列
<!--  id  last_name  email   gender    d_id   -->
 <resultMap type="com.fc.mybatis.bean.Employee" id="MyEmpByStep">
    <id column="id" property="id"/>
    <result column="last_name" property="lastName"/>
    <result column="email" property="email"/>
    <result column="gender" property="gender"/>
    <!-- association定义关联对象的封装规则
        select:表明当前属性是调用select指定的方法查出的结果
        column:指定将哪一列的值传给这个方法

        流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性

        d_id是tbl_employee员工表的关联部门表id的列
     -->
        <association property="dept" 
            select="com.fc.mybatis.dao.DepartmentMapper.getDeptById"
            column="d_id">
        </association>
     </resultMap>

     <!--  public Employee getEmpByIdStep(Integer id);-->
     <select id="getEmpByIdStep" resultMap="MyEmpByStep">
        select * from tbl_employee where id=#{id}
     </select>
  • 分步查询的日志如下:
DEBUG 06-23 15:13:09,306 ==>  Preparing: select * from tbl_employee where id=?   (BaseJdbcLogger.java:159) 
DEBUG 06-23 15:13:09,343 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:159) 
DEBUG 06-23 15:13:09,365 ====>  Preparing: select id,dept_name departmentName from tbl_dept where id=?   (BaseJdbcLogger.java:159) 
DEBUG 06-23 15:13:09,366 ====> Parameters: 1(Integer)  (BaseJdbcLogger.java:159) 
DEBUG 06-23 15:13:09,368 <====      Total: 1  (BaseJdbcLogger.java:159) 
DEBUG 06-23 15:13:09,369 <==      Total: 1  (BaseJdbcLogger.java:159) 
Employee [id=1, lastName=111, email=aa@qq.com, gender=0]
Department [id=1, departmentName=ha]
  • 6、在分步查询基础上实现懒加载
    mybatis-config.xml 中配置
<!-- 懒加载;显示的指定每个我们需要更改的配置的值,即使他是默认的。防止版本更新带来的问题  -->
<setting name="lazyLoadingEnabled" value="true"></setting>
<setting name="aggressiveLazyLoading" value="false"></setting>

测试类

// 获取接口的实现类对象
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
Employee employee = mapper.getEmpByIdStep(1);
System.out.println(employee.getLastName());
System.out.println(employee.getDept());

打印出的日志, 即调用getDept()方法才去查询数据库

DEBUG 06-23 15:59:31,908 ==>  Preparing: select * from tbl_employee where id=?   (BaseJdbcLogger.java:159) 
DEBUG 06-23 15:59:31,947 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:159) 
DEBUG 06-23 15:59:32,027 <==      Total: 1  (BaseJdbcLogger.java:159) 
111
DEBUG 06-23 15:59:32,028 ==>  Preparing: select id,dept_name departmentName from tbl_dept where id=?   (BaseJdbcLogger.java:159) 
DEBUG 06-23 15:59:32,028 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:159) 
DEBUG 06-23 15:59:32,030 <==      Total: 1  (BaseJdbcLogger.java:159) 
Department [id=1, departmentName=ha]
四、一对多查询

场景二:
  查询部门的时候将部门对应的所有员工信息也查询出来:注释在DepartmentMapper.xml中

  • 1、数据库操作,左拼接查询
  • 2、department.java的javabean中添加emps, 并添加get/set方法
private List<Employee> emps;
  • 3、在DepartmentMapper.java 中添加接口方法
// 查询出一个部门中所有员工
public Department getDeptByIdPlus(Integer id);
  • 4、DepartmentMapper.xml 中使用collection标签定义关联的集合类型的属性封装规则
    • collection定义关联集合类型的属性的封装规则
    • ofType:指定集合里面元素的类型
<!--嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则  -->
<resultMap type="com.fc.mybatis.bean.Department" id="MyDept">
<id column="did" property="id"/>
    <result column="dept_name" property="departmentName"/>
    <!-- 
        collection定义关联集合类型的属性的封装规则 
        ofType:指定集合里面元素的类型
    -->
    <collection property="emps" ofType="com.fc.mybatis.bean.Employee">
        <!-- 定义这个集合中元素的封装规则 -->
        <id column="eid" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="email" property="email"/>
        <result column="gender" property="gender"/>
    </collection>
</resultMap>
<!-- public Department getDeptByIdPlus(Integer id); -->
<select id="getDeptByIdPlus" resultMap="MyDept">
    SELECT d.id did,d.dept_name dept_name,
            e.id eid,e.last_name last_name,e.email email,e.gender gender 
    FROM tbl_dept d LEFT JOIN tbl_employee e ON d.id=e.d_id WHERE d.id=#{id}
</select>
  • 5、一对多下的分步查询和一对一分步查询的异同点
    • 1、将单个关联对象association 换成集合关联对象 collection
    • 2、 同样property="dept" 对应上javabean的名字dept
    • 3、将多列的值封装map传递;比如:column="{deptId=id}"
    • 4、column表示传到下一步操作的列
    • 5、select指向下一步操作的方法
    • 6、fetchType=”lazy”:表示使用延迟加载;
      • lazy:延迟
      • eager:立即
问题
  • 1、Mybatis Generator代码不报错,但是没有生成文件
    解决方案:
    此种情况一般都是设置的路径有误,将从\ 换成/
    比如: ./src/main/java
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Mybatis-plus多表关联查询是指在使用Mybatis-plus框架进行数据库操作时,通过多个表之间的关联关系,实现一次性查询多个表中的数据。这种查询方式可以大大提高查询效率,减少数据库访问次数,提高系统性能。在Mybatis-plus中,可以使用注解或XML配置的方式实现多表关联查询,具体实现方式可以参考Mybatis-plus官方文档。 ### 回答2: MyBatis-Plus是基于MyBatis的增强工具,提供了很多实用的功能,其中包括了多表关联查询。在实际开发中,我们经常需要查询多个表的数据,此时就需要用到多表关联查询。下面介绍一下MyBatis-Plus多表关联查询的实现方法。 1.通过@TableName注解指定表名 在实体类上使用@TableName注解,可以指定当前实体类对应的表名,这样在进行多表关联查询时,就可以直接使用表名进行操作。示例代码如下: ``` @Data @TableName("t_user") public class User { @TableId(type = IdType.AUTO) private Long id; private String username; private String password; } ``` 2.使用Mapper中的方法进行多表关联查询 MyBatis-Plus提供了一些方法,可以进行多表关联查询。其中比较常用的方法是selectList()和selectPage()。这些方法可以通过Wrapper条件构造器指定查询条件,并且支持多表关联查询。示例代码如下: ``` public interface UserMapper extends BaseMapper<User> { @Select("select * from t_user u " + "left join t_role r on r.id = u.role_id " + "where u.id = #{id}") UserVO selectUserWithRole(Long id); @Select("select * from t_user u " + "left join t_role r on r.id = u.role_id " + "${ew.customSqlSegment}") List<UserVO> selectUserListWithRole(@Param(Constants.WRAPPER) Wrapper wrapper); } ``` 3.使用@Result注解映射查询结果 在使用Mapper中的方法进行多表关联查询时,我们可以使用@Result注解对查询结果进行映射,这样可以更方便地获取查询结果。示例代码如下: ``` public interface UserMapper extends BaseMapper<User> { @Select("select u.*, r.name as roleName from t_user u " + "left join t_role r on r.id = u.role_id " + "where u.id = #{id}") @Results({ @Result(column = "roleName", property = "roleName") }) UserVO selectUserWithRole(Long id); } ``` 总之,MyBatis-Plus多表关联查询使用起来非常方便,只需要在实体类中指定表名,使用Mapper中的方法进行查询,并使用@Result注解对查询结果进行映射即可。需要注意的是,在进行多表关联查询时,要确保关联的字段在两个表中是唯一的,并且要注意查询效率和查询结果的正确性。 ### 回答3: Mybatis-Plus是一个优秀的基于Mybatis的ORM框架,它极大地简化了开发人员的开发工作。在实际开发中,多表关联查询是常见的需求,Mybatis-Plus提供了多种方式支持多表关联查询。以下是几种常见的多表关联查询方式: 1.通过Join方式查询 使用Join语句可以在一个查询查询多张表,从而实现多表关联查询,如下: ``` SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ON t1.id = t2.t1_id ``` 如果需要使用Join方式查询,需要使用Mybatis-Plus的Wrapper类实现多表关联查询。 2.通过关联查询实现多表查询 如果需要实现包含关联实体的复杂查询,可以使用Mybatis-Plus提供的lambdaQuery方法。例如: ``` List<User> userList = userMapper.selectList(Wrappers .lambdaQuery(User.class) .eq(User::getStatus, 1) .nested(i -> i.eq(User::getName, "Tom") .or() .eq(User::getName, "Jerry")) .orderByAsc(User::getAge) .select(User::getId, User::getName, User::getAge, User::getEmail) .leftJoin(User.class, User::getId, UserRole::getUserId) .leftJoin(UserRole.class, UserRole::getRoleId, Role::getId) .select(UserRole::getRoleId, Role::getName) ) ``` 3.通过XML mapper方式查询 使用XML mapper文件可以实现多表关联查询。通过XML可以方便地实现复杂的多表查询。如下: ``` <select id="getUserRoleList" resultMap="BaseResultMap"> select ur.*, r.name as roleName from user_role ur left join role r on ur.role_id = r.id where ur.user_id = #{userId} </select> ``` 更多关于Mybatis-Plus多表关联查询,可以参考Mybatis-Plus官方文档或者相关博客文章。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值