您的位置 首页 java

Mybatis Plus 关联查询和级联查询

当查询数据分散在多个表中的时候,要一次将结果查出来,这时就需要进行表关联了,将关联之后的结果,映射到 Java 对象上,并最终返回给请求端。本文一起来看一下基于 mybatis plus 从多个表中查询关联数据,并映射到结果集上的两种查询方法。

Mybatis Plus 关联查询和级联查询

两个表关联后,我们有两种返回查询结果集的方式,一种是平铺方式,也就是两个表的字段都放到一个entity中;另一种是在一个entity中持有另一个entity,这就是我们常说的级联查询。

我们举例以班级表和学生表为例,一个班级对应多个学生,一个学生对应一个班级,对应关系就是班级对学生是一对多,学生对班级是一对一(从一个学生的角度去查询,一个学生同一时间只能在一个班级)。

我们先来构造数据。

1、构造两个表,班级表和学生表

 -- 构造班级表
DROP TABLE IF EXISTS classz;

CREATE TABLE classz
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '班级名称',
PRIMARY KEY (id)
);

DROP TABLE IF EXISTS student;

CREATE TABLE student
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
cid BIGINT(20),
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
PRIMARY KEY (id)
);  

2、初始化表中数据

 DELETE FROM classz;

INSERT INTO classz (id, name) VALUES
(1, '一年一班'),
(2, '一年二班');

DELETE FROM student;

INSERT INTO student (id, cid, name) VALUES
(1, 1,'小明'),
(2, 1,'小欧');  

数据构造了两个班级,小明和小欧都在1班。

如果我们从学生的角度查询学生,并把学生对应的班级也关联出来,那么这两种方式的展示方式,我们先看第一种,平铺式的,也就是所有结果字段都在一个类中。

1、构造entity,用于保存结果

 package com.itzhimei.mybatis.plus.model;

import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

/**
 * @Auther: www.itzhimei.com
 * @Description: 班级和学生entity
 */
@Data
public class ClasszAndStudent {
    private Long id;
    private String name;

    private Long stdId;
    private Long cid;
    private String stdName;
}
  

2、在mapper中构建一个查询方法,两个表关联,字段重名就命名别名,与entity对应上

 package com.itzhimei.mybatis.plus.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itzhimei.mybatis.plus.model.Classz;
import com.itzhimei.mybatis.plus.model.ClasszAndStudent;
import org.apache.ibatis.annotations. Select ;

import java.util.List;

/**
 * @Auther: www.itzhimei.com
 * @Description:
 */public interface ClasszMapper extends BaseMapper<Classz> {

    /**
     * 关联查询
     * @return
     */    @Select("select a.*,b.id stdId,b.cid, b.name stdName from classz a ,student b where a.id = b.cid and a.id = 1")
    List<ClasszAndStudent> selectClassAndStudents();


}
  

3、测试

 
/**
 * @Auther: www.itzhimei.com
 * @Description:
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class ClassStudentTest {

    @Autowired
    private ClasszMapper classzMapper;

    @Autowired
    private StudentMapper studentMapper;
    @Test
    public void testSelect() {
        List<ClasszAndStudent> classzs = classzMapper.selectClassAndStudents();
        classzs. forEach (System.out::println);
    }

}  

4、输出:

 ---------------SQL打印输出---------------
==>  Preparing: select a.*,b.id stdId,b.cid, b.name stdName from classz a ,student b where a.id = b.cid and a.id = 1 
==>  Parameters : 
<==    Columns: ID, NAME, STDID, CID, STDNAME
<==         Row : 1, 一年一班, 1, 1, 小明
<==        Row: 1, 一年一班, 2, 1, 小欧
<==       Total : 2


-------------------代码打印输出----------------------
ClasszAndStudent(id=1, name=一年一班, stdId=1, cid=1, stdName=小明)
ClasszAndStudent(id=1, name=一年一班, stdId=2, cid=1, stdName=小欧)
  

我上面说到的平铺式的,就是这种效果:

 ClasszAndStudent(id=1, name=一年一班, stdId=1, cid=1, stdName=小明)  

另一种就是 级联查询 方式的返回查询结果。

1、构造实体,用于保存数据

 package com.itzhimei.mybatis.plus.model;

import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;

import java.util.List;

/**
 * @Auther: www.itzhimei.com
 * @Description: 学生entity
 */
@Data
public class Student {
    private Long id;
    private Long cid;
    private String name;

    @TableField(exist = false)
    private Classz classz;
}
  
 package com.itzhimei.mybatis.plus.model;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

import java.util.List;

/**
 * @Auther: www.itzhimei.com
 * @Description: 班级entity
 */
@Data
public class Classz {
    private Long id;
    private String name;
}
  

2、在StudentMapper中添加一个级联查询方法

 package com.itzhimei.mybatis.plus.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itzhimei.mybatis.plus.model.Classz;
import com.itzhimei.mybatis.plus.model.Student;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * @Auther: www.itzhimei.com
 * @Description:
 */public interface StudentMapper extends BaseMapper<Student> {

    /**
     * 一对一的级联查询
     * @return
     */    @Results(id="id",value = {
            @Result(property = "id",column = "id"),
            @Result(property = "name",column = "name"),
            @Result(property = "cid",column = "cid"),
            @Result(property = "classz",column = "cid", one = @One(select = "com.itzhimei.mybatis.plus.mapper.ClasszMapper.selectById"))
    })
    @Select("select * from student ")
    List<Student> selectStudentsAndClass();
}
  

注意代码中的注解,其中这一行:

 @Result(property = "classz",column = "cid", one = @One(select = "com.itzhimei.mybatis.plus.mapper.ClasszMapper.selectById"))  

作用就是执行了ClasszMapper.selectById()方法,用主键查询对应的班级,将查询结果set到了Student实体类中的Classz classz属性中(请看上面Student类中的属性)。

3、测试

 package com.itzhimei.mybatis.plus.test;

import com.itzhimei.mybatis.plus.mapper.ClasszMapper;
import com.itzhimei.mybatis.plus.mapper.StudentMapper;
import com.itzhimei.mybatis.plus.model.ClasszAndStudent;
import com.itzhimei.mybatis.plus.model.Student;
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 java.util.List;

/**
 * @Auther: www.itzhimei.com
 * @Description:
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class ClassStudentTest {

    @Autowired
    private ClasszMapper classzMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Test
    public void testSelectCascade() {
        List<Student> students = studentMapper.selectStudentsAndClass();
        students.forEach(System.out::println);
    }
}
  

4、输出

 ---------------SQL打印输出---------------
==>  Preparing: select * from student 
==> Parameters: 
<==    Columns: ID, CID, NAME
<==        Row: 1, 1, 小明
====>  Preparing: SELECT id,name FROM classz WHERE id=? 
====> Parameters: 1(Long)
<====    Columns: ID, NAME
<====        Row: 1, 一年一班
<====      Total: 1
<==        Row: 2, 1, 小欧
<==      Total: 2

-------------------代码打印输出----------------------
Student(id=1, cid=1, name=小明, classz=Classz(id=1, name=一年一班))
Student(id=2, cid=1, name=小欧, classz=Classz(id=1, name=一年一班))
  

看代码的输出结果:

 Student(id=1, cid=1, name=小明, classz=Classz(id=1, name=一年一班))  

Student中包含的Classz也带有数据,是这种Student(Classz)包含一个实体的效果,这就实现了一个一对一级联查询效果。

文章来源:智云一二三科技

文章标题:Mybatis Plus 关联查询和级联查询

文章地址:https://www.zhihuclub.com/196912.shtml

关于作者: 智云科技

热门文章

网站地图