mybatis使用collection嵌套查询的实现

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

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

下面介绍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);
	}
}

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

这个程序,在第一次根据名称查询员工信息之后,返回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属性这里。

到此这篇关于mybatis使用collection嵌套查询的实现的文章就介绍到这了,更多相关mybatis collection嵌套查询内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MyBatis的嵌套查询解析

    Mybatis表现关联关系比hibernate简单,没有分那么细致one-to-many.many-to-one.one-to-one.而是只有两种association(一).collection(多),表现很简洁.下面通过一个实例,来展示一下Mybatis对于常见的一对多和多对一关系复杂映射是怎样处理的. 以最简单的用户表订单表这个最简单的一对多做示例: 对应的JavaBean: User: public class User { private int id; private String

  • MyBatis一对多嵌套查询的完整实例

    前言 嵌套查询的实现原理为两次查询,比如产品表为主表,图片表为从表通过product_id字段与产品表id字段关联实现一对多,嵌套查询 首先查询 主表的数据 然后将主表id字段赋值给从表实体类中product_id 字段(productId)然后通过dao接口路径映射找到对应的MyBatis XMl文件SQL语句ID如:com.liao.dao.DImgMapper.selectDImgByProductId 进行子查询也就是第二次查询.然后返回数据 数据库建表语句和测试数据如下: 数据库版本为

  • Java之Mybatis多层嵌套查询方式

    目录 Mybatis多层嵌套查询 表的存储sql文件 实体类 XML Mybatis多层嵌套查询(多对多) 依赖 实体类Setmeal 实体类CheckGroup 实体类CheckItem mapper层 测试 Mybatis多层嵌套查询 三张表:user article blog 表的存储sql文件 /* Navicat MySQL Data Transfer Source Server : localhost Source Server Version : 50620 Source Host

  • MyBatis中一对多的xml配置方式(嵌套查询/嵌套结果)

    目录 MyBatis一对多的xml配置 嵌套查询 嵌套结果 一对多关联查询xml配置写法 情景概述 创建表 对应javaPojo 查询客户表client获取客户名下的附件信息 查询客户附件表client_file获取附件所属的客户信息 小结一下 MyBatis一对多的xml配置 用的是window上面的画图板,没法以文字的方式展示出来,见谅 嵌套查询 嵌套结果 一对多关联查询xml配置写法 情景概述 1.有一张客户表 Client ,存储客户信息, 姓名 name ,年龄 age等. 2.有一张

  • mybatis 集合嵌套查询和集合嵌套结果的区别说明

    目录 集合嵌套查询和集合嵌套结果的区别 1.创建2张表,建立主外键关系 2.建立实体类 3.修改配置文件 4.建立映射文件 5.创建测试类 MyBatis 嵌套查询解析 对应的JavaBean 对应的数据库 嵌套语句查询 嵌套语句查询的原理 嵌套查询的多对一 嵌套查询的N+1问题 嵌套结果查询 嵌套结果查询的执行步骤 集合嵌套查询和集合嵌套结果的区别 嵌套查询是多条sql语句分开写并配置,嵌套结果是一条sql语句关联查询并配置,实质效果是一样的.嵌套语句的查询会导致数据库访问次数不定,进而有可能

  • Fluent Mybatis零xml配置实现复杂嵌套查询

    目录 嵌套查询 in (select 子查询) exists (select子查询) 嵌套查询 使用Fluent Mybatis, 不用手写一行xml文件或者Mapper文件,在dao类中即可使用java api构造中比较复杂的嵌套查询. 让dao的代码逻辑和sql逻辑合二为一. 前置准备,maven工程设置 参考文章 使用FluentMybatis实现mybatis动态sql拼装和fluent api语法 in (select 子查询) 嵌套查询表和主查询表一样的场景 .column().in

  • Mybatis中连接查询和嵌套查询实例代码

    首先在mysql中确立表: #表一:地址国家表 CREATE TABLE address(aid INT AUTO_INCREMENT PRIMARY KEY,aname VARCHAR(20)); INSERT INTO address VALUES(NULL,"魏国"); INSERT INTO address VALUES(NULL,"蜀国"); INSERT INTO address VALUES(NULL,"吴国"); #表二:出场人物

  • mybatis使用collection嵌套查询的实现

    在开发中,可能会遇到一对多的关系,这个时候,一条sql语句就难以胜任这个任务了.只能先执行一条sql,然后根据返回的结果,再做一次sql关联查询,这个时候,使用mybatis的collection就可以实现. 如果第一次查询返回的是一个list集合,那么,后续的查询就是一个for循环.所以不使用collection的做法,在java语言中,就要分两次查询.一般而言,我们的列表查询都是分页查询,所以集合数据不会太大,第二次for循环查询效率还好. 下面介绍mybatis使用collection嵌套

  • 解决mybatis 中collection嵌套collection引发的bug

    我就废话不多说了,大家还是直接看代码吧~ <resultMap id="ParentMap" type="org.example.mybatis.Parent"> <id column="Id" jdbcType="VARCHAR" property="id" /> <result column="Name" jdbcType="VARCHAR&q

  • mybatis 实现多层级collection嵌套

    目录 mybatis多层级collection嵌套 json结构 第一步查询 第二步查询 第三步查询(第三层查询) 最后附实体截图,其实看json就可以了 方式二(推荐) mybatis多层(三层)嵌套查询 java实体描述 mybatisxml 调用方法 注意总结 mybatis多层级collection嵌套 json结构 第一步查询 第一层查询,将第一层的id传递到第二层当条件查询    column="id" <resultMap id="BaseResultMa

  • MyBatis实现两种查询树形数据的方法详解(嵌套结果集和递归查询)

    目录 方法一:使用嵌套结果集实现 1,准备工作 2,实现代码 方法二:使用递归查询实现 树形结构数据在开发中十分常见,比如:菜单数.组织树, 利用 MyBatis 提供嵌套查询功能可以很方便地实现这个功能需求.而其具体地实现方法又有两种,下面分别通过样例进行演示. 方法一:使用嵌套结果集实现 1,准备工作 (1)假设我们有如下一张菜单表 menu,其中子菜单通过 parendId 与父菜单的 id 进行关联: (2)对应的实体类如下: @Setter @Getter public class M

随机推荐