# 连表查询
通过对dao(mapper)层注解的方式来进行一对一,一对多的连表查询,极大的提高了开发效率。
说明:
@Link
注解方式,不会影响到Mybatis自带的注解,以及在Mybatis的Xml中编写Sql语句。- 一对多的连表查询,会有N+1的问题。
# 前提条件准备
为了直观感受和使用连表查询,下面将通过4张表(t_teat_a
、t_test_b
、t_test_c
、t_test_d
)进行说明,四张表分别用abcd进行简称。
以下连表查询都是写在TestADao.class
类中
类:TestADao.class
public interface TestADao extends BaseDao<TestAVo, TestADto> {
........
}
类:TestADto.class
@Data
public class TestADto implements Serializable {
private static final long serialVersionUID = 1L;
protected TestAVo testAVo2;
protected TestAVo testAVo;
protected TestBVo testBVo;
protected TestCVo testCVo;
protected TestDVo testDVo;
protected List<TestBDto> testBList;
protected List<TestCDto> testCList;
protected Integer count;
protected String crtBy;
}
# 演示表结构
表:t_test_a
字段 | 类型 | 描述 |
---|---|---|
id | bigint | 主键 |
b_id | bigint | b表主键 |
c_id | bigint | c表主键 |
a_id | bigint | a表主键 |
表:t_test_b
字段 | 类型 | 描述 |
---|---|---|
id | bigint | 主键 |
a_id | bigint | a表主键 |
c_id | bigint | c表主键 |
表:t_test_c
字段 | 类型 | 描述 |
---|---|---|
id | bigint | 主键 |
a_id | bigint | a表主键 |
b_id | bigint | b表主键 |
表:t_test_d
字段 | 类型 | 描述 |
---|---|---|
id | bigint | 主键 |
a_id | bigint | a表主键 |
# 一对一连表查询
说明:
- 一对一连表查询,可以进行左连接,右连接,内连接查询,且可以进行多表(大于等于2张表)连查。
- 左连接或者右连接查询时,可以在
ON
或者WHERE
后区别进行条件过滤。
# a
内连 a
@Link(ones = {
@OneToOne(leftColumn = "a_id", rightClass = TestAVo.class, rightAlias = "testAVo2") })
List<TestADto> listTestAATestA(@Param(Constants.WRAPPER) Wrapper<TestAVo> wrapper);
说明:
- 由于查询的两个表为同一个表,所以必须给其中一个表设置别名,且该别名必须跟TestADto对象中得属性名对应,如:rightAlias = "testAVo2"。
- 由于在TestADao.class中进行注解,所有leftClass默认为TestAVo.class,可以默认省略。
- leftColumn或者rightColumn都不写,默认为表主键。
- leftAlias或者rightAlias都不写,默认都为表实体对象属性值,如:leftAlias = "testAVo"。
# a
内连 c
@Link(ones = { @OneToOne(leftColumn = "c_id", rightClass = TestCVo.class) })
List<TestADto> listTestAATestC(@Param(Constants.WRAPPER) Wrapper<TestAVo> wrapper);
说明:
- a表的c_id字段,与c表中的id主键字段,进行连表查询。
# a
内连 b
@Link(ones = { @OneToOne(rightClass = TestBVo.class, rightColumn = "a_id") })
List<TestADto> listTestAATestB(@Param(Constants.WRAPPER) Wrapper<TestAVo> wrapper);
说明:
- a表的id主键字段,与b表中的a_id字段,进行连表查询。
# a
内连 b
, a
内连 c
@Link(ones = { @OneToOne(leftColumn = "b_id", rightClass = TestBVo.class),
@OneToOne(leftColumn = "c_id", rightClass = TestCVo.class)})
List<TestADto> listTestAATestBATestC(@Param(Constants.WRAPPER) Wrapper<TestAVo> wrapper);
# a
内连 b
, b
内连 c
, a
内连 d
@Link( ones = {
@OneToOne(leftColumn = "b_id", rightClass = TestBVo.class),
@OneToOne(leftClass = TestBVo.class, leftColumn = "c_id", rightClass = TestCVo.class),
@OneToOne(rightClass = TestDVo.class, rightColumn = "a_id")})
List<TestADto> listTestAATestBATestCATestD(@Param(Constants.WRAPPER) Wrapper<TestAVo> wrapper);
# a
左连 b
@Link( ones = {
@OneToOne(leftColumn = "b_id", rightClass = TestBVo.class,
joinType = JoinType.LEFT, onArgName = "abOn") })
List<TestADto> listTestALtTestB(@Param(Constants.WRAPPER) Wrapper<TestAVo> wrapper);
说明:
JoinType.LEFT
表示左连接。onArgName = "abOn"
表示左连接ON
后面的条件参数,通过abOn可以在ON
后面进行条件过滤。
# a
左连 b
,a
左连 c
@Link( ones = {
@OneToOne(leftColumn = "b_id", rightClass = TestBVo.class,
joinType = JoinType.LEFT, onArgName = "abOn"),
@OneToOne(leftColumn = "c_id", rightClass = TestCVo.class,
joinType = JoinType.LEFT, onArgName = "acOn")})
List<TestADto> listTestALtTestBLtTestC(@Param(Constants.WRAPPER) Wrapper<TestAVo> wrapper);
# a
右连 b
@Link( ones = {
@OneToOne(leftColumn = "b_id", rightClass = TestCVo.class,
joinType = JoinType.RIGHT, onArgName = "acOn") })
List<TestADto> listTestARtTestC(@Param(Constants.WRAPPER) Wrapper<TestAVo> wrapper);
# a
内连 b
分页查询
@Link( ones = {
@OneToOne(rightClass = TestBVo.class, rightColumn = "a_id") })
IPage<TestADto> pageTestAATestB(IPage<TestADto> page, @Param(Constants.WRAPPER) Wrapper<TestAVo> wrapper);
# a
内连 b
条数查询
@Link( ones = { @OneToOne(rightClass = TestBVo.class, rightColumn = "a_id") })
Integer countTestAATestB(@Param(Constants.WRAPPER) Wrapper<TestAVo> wrapper);
# 一对多连表查询
说明:
- 一对多连表查询,可以先进行一对一查询,再进行一对多查询。
- 一对多查询,多的那部分还可以进行一对一查询。
# a
一对多 b
@Link( manys = {
@OneToMany(leftColumn = "b_id", rightClass = TestBVo.class,
ofTypeClass = TestBDto.class, property = "testBList") })
List<TestADto> listTestAWTestB(@Param(Constants.WRAPPER) Wrapper<TestAVo> wrapper);
说明:
ofTypeClass
需要配置多表实体对应的Dto类。rightClass
可以省略,会根据ofTypeClass
实体对象类进行规制解析。property
对应TestADto中类型为List<TestBDto>的属性名,即testBList。
# a
一对多 b
,a
一对多 c
@Link( manys = {
@OneToMany(leftColumn = "b_id", rightClass = TestBVo.class,
ofTypeClass = TestBDto.class, property = "testBList"),
@OneToMany(leftColumn = "c_id", rightClass = TestCVo.class,
ofTypeClass = TestCDto.class, property = "testCList")})
List<TestADto> listTestAWTestBWTestC(@Param(Constants.WRAPPER) Wrapper<TestAVo> wrapper);
# a
内连 b
,a
一对多 b
@Link( ones = { @OneToOne(leftColumn = "b_id", rightClass = TestBVo.class)},
manys = { @OneToMany(leftClass = TestAVo.class, leftColumn = "b_id",
rightClass = TestBVo.class, ofTypeClass = TestBDto.class, property = "testBList") })
List<TestADto> listTestAATestBWTestB(@Param(Constants.WRAPPER) Wrapper<TestAVo> wrapper);
# a
内连 b
,(a
一对多 b
,b
内连 c
)
@Link( ones = { @OneToOne(leftColumn = "b_id", rightClass = TestBVo.class)},
manys = { @OneToMany(leftClass = TestAVo.class, leftColumn = "b_id",
rightClass = TestBVo.class, ofTypeClass = TestBDto.class, property = "testBList",
ones = { @OneToOne(leftColumn = "c_id", rightClass = TestCVo.class)} )})
List<TestADto> listTestAATestBWTestBATestC(@Param(Constants.WRAPPER) Wrapper<TestAVo> wrapper);
说明:
OneToMany
中有OneToOne[]
类型的属性。
赞助商