mybatis使用collection嵌套查询的实现(mybatis嵌套查询与连接查询)

网友投稿 505 2022-08-07


mybatis使用collection嵌套查询的实现(mybatis嵌套查询与连接查询)

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

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

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

表结构与数据如下所示:

数据:

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

com.baomidou

mybatis-plus-boot-starter

3.2.0

mysql

mysql-connector-java

org.projectlombok

lombok

定义的实体:

员工信息:

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 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 queryByName(String name);

Department queryByUserId(Integer userId);

}

EmpMapper.xml配置文件

select="com.xxx.springboot.mybatis.mapper.EmpMapper.queryByUserId" column="{userId=id}">

select="com.xxx.springboot.mybatis.mapper.EmpMapper.queryByUserId" column="{userId=id}">

SELECT

*

FROM xx_emp

WHERE name = #{name}

SELECT

*

FROM xx_dept

WHERE user_id = #{userId}

测试类:

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属性这里。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java中的HashMap为什么会产生死循环
下一篇:Java中为什么不同的返回类型不算方法重载(java方法重载返回值不同)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~