mybatis使用collection嵌套查询的实现

作者:luffy5459 时间:2021-07-06 22:04:58 

在开发中,可能会遇到一对多的关系,这个时候,一条sql语句就难以胜任这个任务了。只能先执行一条sql,然后根据返回的结果,再做一次sql关联查询,这个时候,使用mybatis的collection就可以实现。

如果第一次查询返回的是一个list集合,那么,后续的查询就是一个for循环。所以不使用collection的做法,在java语言中,就要分两次查询。一般而言,我们的列表查询都是分页查询,所以集合数据不会太大,第二次for循环查询效率还好。

下面介绍mybatis使用collection嵌套查询解决这个问题。这里为了简单,以员工与部门的关系来做这个实验,其实员工与部门的关系还应该使用一个中间表来关联,这里只用两张表。

表结构与数据如下所示:

mybatis使用collection嵌套查询的实现

数据:

mybatis使用collection嵌套查询的实现

这里采用maven构建springboot+mybatis-plus+mysql工程。

<dependency>
     <groupId>com.baomidou</groupId>
     <artifactId>mybatis-plus-boot-starter</artifactId>
     <version>3.2.0</version>
   </dependency>

<dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
   </dependency>

<dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
   </dependency>

定义的实体:

员工信息:

package com.xxx.springboot.mybatis.domain;

import java.util.List;

import com.baomidou.mybatisplus.annotation.TableName;

import lombok.Data;

@Data
@TableName("xx_emp")
public class Employee {
private Integer id ;
private String name ;
private int age ;

private List<Department> depts ;
}

部门信息 

package com.xxx.springboot.mybatis.domain;

import com.baomidou.mybatisplus.annotation.TableName;

import lombok.Data;

@Data
@TableName("xx_dept")
public class Department {

private Integer id ;

private String name ;

private Integer userId ;

}

Mapper接口

package com.xxx.springboot.mybatis.mapper;

import org.apache.ibatis.annotations.Mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xxx.springboot.mybatis.domain.Department;
import com.xxx.springboot.mybatis.domain.Employee;
@Mapper
public interface EmpMapper extends BaseMapper<Employee>{
Employee queryByName(String name);
Department queryByUserId(Integer userId);
}

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">
<mapper namespace="com.xxx.springboot.mybatis.mapper.EmpMapper">
 <resultMap id="empMap" type="com.xxx.springboot.mybatis.domain.Employee" >
   <id column="id" property="id" />
   <result column="name" property="name" />
   <result column="age" property="age" />
   <collection property="depts" javaType="java.util.ArrayList" ofType="com.xxx.springboot.mybatis.domain.Department"
   select="com.xxx.springboot.mybatis.mapper.EmpMapper.queryByUserId" column="{userId=id}"></collection>
 </resultMap>
 <resultMap id="deptMap" type="com.xxx.springboot.mybatis.domain.Department">
   <id column="id" property="id"/>
   <result column="name" property="name"/>
   <result column="user_id" property="userId"/>
 </resultMap>
 <select id="queryByName" resultMap="empMap">
    SELECT
    *
    FROM xx_emp
    WHERE name  = #{name}
 </select>
 <select id="queryByUserId" resultMap="deptMap">
   SELECT
   *
   FROM xx_dept
   WHERE user_id = #{userId}
 </select>
</mapper>

测试类:

package com.xxx.springboot;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xxx.springboot.mybatis.domain.Employee;
import com.xxx.springboot.mybatis.mapper.EmpMapper;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MyBatisTest {

@Autowired
private EmpMapper empMapper;

@Test
public void testEmpQuery() {
Employee emp = empMapper.queryByName("aa");
System.out.println(emp);
}
}

运行单元测试,打印信息如下:

mybatis使用collection嵌套查询的实现

这个程序,在第一次根据名称查询员工信息之后,返回id=1,name=aa,age=18,接着,根据id=1 查询了部门表,其实这里的id=1,作为参数传入部门表中,就成了user_id对应的参数,然后就查询出了两个部门记录id=1,id=3,最后打印的员工信息里面,depts就是一个集合。

使用这个嵌套查询,需要注意的是collection有如下属性:

property 实体中对应的属性,这里是depts。    javaType 实体属性的类型,这里是一个集合,所以使用java.util.ArrayList表示。    ofType 集合范型中的类型,这里是部门信息,对应java类Department    select  嵌套子查询的ID    column 这里最关键,也比较难理解,默认一个参数,可以直接写column = "id",最后根据参数类型匹配。这里其实是传入子查询中的参数,也就是子查询的关联属性user_id对应的参数值,在collection这里就是主sql中查询出来的列值,如果这里id有了别名,比如emp_id,这里就应该写column = "emp_id"。还有一种写法,通过大括号来表示,这种写法可以传入多个参数(多个参数用逗号隔开)。对于本示例而言,正确的写法就是column={userId=id},userId对应  queryByUserId查询语句中 SELECT * FROM xx_dept WHERE user_id = #{userId}  参数userId。id就是主sql查询出来的列id值,就是xx_emp对应的id列值。

我个人在使用collection的时候,大概明白这种嵌套查询的作用,但是就是不明白,怎么传递参数,后来看过一些例子,原来主要点就在column属性这里。

来源:https://blog.csdn.net/feinifi/article/details/124615025

标签:mybatis,collection,嵌套查询
0
投稿

猜你喜欢

  • java并发编程_线程池的使用方法(详解)

    2023-03-29 22:23:00
  • Spring Security添加验证码的两种方式小结

    2021-08-05 17:24:25
  • SpringBoot绿叶显示yml和端口问题及解决方法

    2023-12-09 00:29:13
  • C#多线程学习之(三)生产者和消费者用法分析

    2021-08-11 01:55:26
  • Spring Security 实现用户名密码登录流程源码详解

    2023-05-31 11:13:59
  • JPA Specification常用查询+排序实例

    2023-11-23 04:56:32
  • Java emoji持久化mysql过程详解

    2023-10-10 23:11:49
  • Java多线程编程综合案例详解

    2023-12-09 18:13:25
  • 深入理解Spring Boot的日志管理

    2021-11-16 09:58:40
  • java编程实现优先队列的二叉堆代码分享

    2022-11-13 15:32:13
  • Java中自动生成构造方法详解

    2023-06-21 14:17:44
  • Java中ResultSetMetaData 元数据的具体使用

    2021-06-25 12:38:13
  • WebService教程详解(一)

    2022-02-26 09:59:50
  • JavaCV实现照片马赛克效果

    2023-04-27 15:55:14
  • Java多线程Atomic包操作原子变量与原子类详解

    2023-08-18 07:46:25
  • java实现小球碰撞功能

    2023-04-05 19:22:41
  • java实现MapReduce对文件进行切分的示例代码

    2023-10-07 21:46:59
  • Java设计模式之职责链模式详解

    2023-01-26 21:16:26
  • Java字符串常量池示例详解

    2021-10-11 10:55:02
  • Java泛型映射不同的值类型详解及实例代码

    2023-07-29 00:20:52
  • asp之家 软件编程 m.aspxhome.com