跳到主要内容

关联查询概述

自动关联查询,告别繁琐的 ResultMap

概述

MyBatisGX 支持声明式的关联查询配置,通过注解定义实体间的关联关系,框架自动处理关联数据的抓取。

关联类型

┌─────────────────────────────────────────────────────────────────┐
│ 关联类型 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 一对一 (OneToOne) │
│ ┌────────┐ ┌────────────┐ │
│ │ User │ ──────▶ │ UserDetail │ │
│ └────────┘ 1:1 └────────────┘ │
│ │
│ 一对多 (OneToMany) │
│ ┌────────┐ ┌────────┐ │
│ │ Org │ ──────▶ │ User │ │
│ └────────┘ 1:N └────────┘ │
│ │
│ 多对一 (ManyToOne) │
│ ┌────────┐ ┌────────┐ │
│ │ User │ ──────▶ │ Org │ │
│ └────────┘ N:1 └────────┘ │
│ │
│ 多对多 (ManyToMany) │
│ ┌────────┐ ┌──────────┐ ┌────────┐ │
│ │ User │ ──────▶ │ UserRole │ ◀────── │ Role │ │
│ └────────┘ M:N └──────────┘ └────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘

注解体系

注解说明
@OneToOne一对一关联
@OneToMany一对多关联
@ManyToOne多对一关联
@ManyToMany多对多关联
@JoinColumn外键列配置
@JoinTable中间表配置
@Fetch抓取模式配置
FetchMode抓取模式枚举

关联方向

单向关联

@Entity
@Table(name = "user")
public class User {

@Id
private Long id;

// 只有 User 知道 UserDetail 的存在
@OneToOne
@JoinColumn(name = "detail_id")
private UserDetail userDetail;
}

双向关联

@Entity
@Table(name = "user")
public class User {

@Id
private Long id;

@OneToOne(mappedBy = "user")
private UserDetail userDetail;
}

@Entity
@Table(name = "user_detail")
public class UserDetail {

@Id
private Long id;

@OneToOne
@JoinColumn(name = "user_id")
private User user;
}

抓取策略

FetchType

策略说明
LAZY懒加载,访问时才查询
EAGER立即加载,主查询时一并查询
@OneToOne(fetch = FetchType.EAGER)
private UserDetail userDetail;

@OneToMany(fetch = FetchType.LAZY)
private List<User> userList;

FetchMode

模式说明SQL 行为
SIMPLE简单查询存在 N+1 问题
BATCH批量查询1+M 查询,解决 N+1
JOIN联表查询1+1 查询,可能结果膨胀
NONE不抓取完全不生成关联 SQL
@OneToMany(fetch = FetchType.EAGER)
@Fetch(FetchMode.BATCH)
private List<User> userList;

关联字段命名

mappedBy

指定关系由对方维护,用于双向关联:

// User 端
@OneToMany(mappedBy = "org") // 由 Org 端的 org 字段维护
private List<User> userList;

// Org 端
@ManyToOne
@JoinColumn(name = "org_id")
private Org org;

@JoinColumn

指定外键列名:

@ManyToOne
@JoinColumn(name = "org_id", referencedColumnName = "id")
private Org org;
属性说明
name外键列名
referencedColumnName关联的主键列名

自动抓取条件

当 mapper.xml 中存在对应方法时,自动抓取失效

// 如果在 UserMapper.xml 中定义了 findById 方法
// MyBatisGX 不会自动处理关联抓取

基本示例

@Entity
@Table(name = "user")
public class User {

@Id
private Long id;

private String name;

// 一对一
@OneToOne(mappedBy = "user", fetch = FetchType.EAGER)
@Fetch(FetchMode.BATCH)
private UserDetail userDetail;

// 多对一
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "org_id")
@Fetch(FetchMode.SIMPLE)
private Org org;

// 多对多
@ManyToMany(mappedBy = "userList", fetch = FetchType.LAZY)
@Fetch(FetchMode.BATCH)
private List<Role> roleList;
}

下一步