MybatisFlex关联查询

2023-09-05 11:24:10 浏览数 (2)

在 MyBatis-Flex 中,提供了 4 个 Relations 注解,他们分别是:

  • RelationOneToOne:用于一对一的场景
  • RelationOneToMany:用于一对多的场景
  • RelationManyToOne:用于多对一的场景
  • RelationManyToMany:用于多对多的场景

添加了以上配置的实体类,在通过 BaseMapper 的方法查询数据时,需要调用 select***WithRelations() 方法,Relations 注解才能生效。 否则 MyBatis-Flex 自动忽略 Relations 注解。

一对一 @RelationOneToOne

代码语言:javascript复制
一对一 @RelationOneToOne
假设有一个账户,账户有身份证,账户和身份证的关系是一对一的关系,代码如下所示:

Account.java :

java
public class Account implements Serializable {

    @Id(keyType = KeyType.Auto)
    private Long id;

    private String userName;

    @RelationOneToOne(selfField = "id", targetField = "accountId")
    private IDCard idCard;

    //getter setter
}
IDCard.java :

java
@Table(value = "tb_idcard")
public class IDCard implements Serializable {

    private Long accountId;
    private String cardNo;
    private String content;

    //getter setter
}
@RelationOneToOne 配置描述:

selfField 当前实体类的属性
targetField 目标对象的关系实体类的属性
PS: 若 selfField 是主键,且当前表只有 1 个主键时,可以不填写。因此,以上的配置可以简化为 @RelationOneToOne(targetField = "accountId")

假设数据库 5 条 Account 数据,然后进行查询:

java
List<Account> accounts = accountMapper.selectAllWithRelations();
System.out.println(accounts);

一对多 @RelationOneToMany

代码语言:javascript复制
Account.java :

java
public class Account implements Serializable {

    @Id(keyType = KeyType.Auto)
    private Long id;

    private String userName;

    @RelationOneToMany(selfField = "id", targetField = "accountId")
    private List<Book> books;

    //getter setter
}
Book.java :

java
@Table(value = "tb_book")
public class Book implements Serializable {

    @Id(keyType = KeyType.Auto)
    private Long id;
    private Long accountId;
    private String title;

    //getter setter
}

多对一 @RelationManyToOne

代码语言:javascript复制
假设一个账户有很多本书籍,一本书只能归属一个账户所有;账户和书籍的关系是一对多的关系,书籍和账户的关系为多对一的关系,代码如下:

Account.java:

java
public class Account implements Serializable {

    @Id(keyType = KeyType.Auto)
    private Long id;

    private String userName;

    //getter setter
}
Book.java 多对一的配置:

java
@Table(value = "tb_book")
public class Book implements Serializable {

    @Id(keyType = KeyType.Auto)
    private Long id;
    private Long accountId;
    private String title;

    @RelationManyToOne(selfField = "accountId", targetField = "id")
    private Account account;

    //getter setter
}

多对多 @RelationManyToMany

代码语言:javascript复制
假设一个账户可以有多个角色,一个角色也可以有多个账户,他们是多对多的关系,需要通过中间件表 tb_role_mapping 来维护:

tb_role_mapping 的表结构如下:

sql
CREATE TABLE  `tb_role_mapping`
(
    `account_id`  INTEGER ,
    `role_id`  INTEGER
);
Account.java 多对多的配置:

java
public class Account implements Serializable {

    @Id(keyType = KeyType.Auto)
    private Long id;
    private String userName;

    @RelationManyToMany(
            joinTable = "tb_role_mapping", // 中间表
            selfField = "id", joinSelfColumn = "account_id",
            targetField = "id", joinTargetColumn = "role_id"
    )
    private List<Role> roles;

    //getter setter
}
Role.java 多对多的配置:

java
@Table(value = "tb_role")
public class Role implements Serializable {

    private Long id;
    private String name;

    //getter setter
}
@RelationManyToMany 配置描述:

selfField 当前实体类的属性
targetField 目标对象的关系实体类的属性
joinTable 中间表
joinSelfColumn 当前表和中间表的关系字段
joinTargetColumn 目标表和中间表的关系字段
注意:selfField 和 targetField 配置的是类的属性名,joinSelfColumn 和 joinTargetColumn 配置的是中间表的字段名。

若 selfField 和 targetField 分别是两张关系表的主键,且表只有 1 个主键时,可以不填写。因此,以上配置可以简化如下:

java
public class Account implements Serializable {

    @Id(keyType = KeyType.Auto)
    private Long id;
    private String userName;

    @RelationManyToMany(
            joinTable = "tb_role_mapping", // 中间表
            joinSelfColumn = "account_id",
            joinTargetColumn = "role_id"
    )
    private List<Role> roles;

    //getter setter
}

0 人点赞