queryWrapper处理一对一,一对多,多对多

SELECT
bu.ID AS id,
bu.FULLNAME AS fullName,
bu.ID_NUMBER AS idNumber,
bu.MOBILE AS Mobile,
bu.USER_TYPE AS userType,
bc.BANK_CODE AS bankCode,
bc.BANK_NAME AS bankName,
bc.CARD_NUMBER AS cardNumber,
bc.PASSWORD AS password
FROM
bank_user AS bu
LEFT JOIN
(
bank_card AS bc
)
ON
bu.ID = bc.USER_ID
WHERE
bu.ID = 1 ; 将这段代码换成queryWrapper的写法,结果返回userdetailDTO对象,此对象包含所有查询的字段

是的,定义一个 BankUser 对象时,通常需要在其内部定义一个 BankCard 字段来表示其与 bank_card 表的关联关系。

例如,在 BankUser 类中定义一个 BankCard 对象作为其属性:```java

public class BankUser {
    private Long id;  // 用户 ID
    private String fullName;  // 用户名
    // 其他属性...

    private BankCard bankCard;  // 与 bank_card 表的关联关系

    // Getter 和 Setter 方法...
}


```

然后,在查询 BankUser 对象时,需要使用 LEFT JOIN 将 bank_user 和 bank_card 表进行关联,并使用 select 方法指定需要查询的字段:

```java

QueryWrapper<BankUser> queryWrapper = new QueryWrapper<>();
queryWrapper.select("b.ID", "b.FULLNAME", "c.BANK_CODE", "c.BANK_NAME", "c.CARD_NUMBER")
        .eq("b.ID", 1L)
        .last("LEFT JOIN bank_card c ON b.ID = c.USER_ID");
BankUser bankUser = bankUserService.getOne(queryWrapper);


```

这样查询出来的 BankUser 对象中就会包含一个 BankCard 对象,可以使用 getBankCard 方法获取它:

```java

BankCard bankCard = bankUser.getBankCard();


```

getBankCard 方法的实现可以简单地返回实例变量 bankCard。

需要注意的是,如果使用 MyBatisPlus 进行相关的代码生成,其会自动生成 Entity 类和相关的 Mapper 接口。在 Entity 中,会将两个表的字段映射成对应的属性,而 Mapper 接口中则会自动生成基本的 CRUD 方法。可以基于这些接口和类进行后续的开发工作。

好的,下面是将该 SQL 转换为使用queryWrapper的 Java 代码,并返回 UserDetailDTO 对象的示例代码:```java

QueryWrapper<BankUser> queryWrapper = new QueryWrapper<>();
queryWrapper.select("ID AS id", "FULLNAME AS fullName", "ID_NUMBER AS idNumber",
        "MOBILE AS Mobile", "USER_TYPE AS userType", "BANK_CODE AS bankCode",
        "BANK_NAME AS bankName", "CARD_NUMBER AS cardNumber", "`PASSWORD` AS `password`")
        .eq("bu.ID", 1L)
        .last("LEFT JOIN bank_card AS bc ON bu.ID = bc.USER_ID");
BankUser bankUser = bankUserService.getOne(queryWrapper);

UserDetailDTO userDetailDTO = new UserDetailDTO();
BeanUtils.copyProperties(bankUser, userDetailDTO);

if (bankUser.getBankCard() != null) {
    BankCard bankCard = bankUser.getBankCard();
    userDetailDTO.setBankCode(bankCard.getBankCode());
    userDetailDTO.setBankName(bankCard.getBankName());
    userDetailDTO.setCardNumber(bankCard.getCardNumber());
    userDetailDTO.setPassword(bankCard.getPassword());
}
return userDetailDTO;


```

在代码中,首先使用 QueryWrapper 构建了 SQL 查询语句。其中 select 方法用于指定需要查询的字段,eq 方法指定查询条件。last 方法则用于指定表的连接方式,可以使用任意 SQL 语句,这里使用了 LEFT JOIN。

接着,调用 bankUserService 的 getOne 方法执行查询,并将查询结果转换为 UserDetailDTO 对象,这里使用了 Spring 框架提供的 BeanUtils.copyProperties 方法进行转换。

最后,如果查询结果中包含 BankCard 对象,则从 BankCard 对象中取出相应的字段并设置到 UserDetailDTO 对象中。

这样就可以非常简单地实现将该 SQL 语句转换为使用 QueryWrapper 的 Java 代码,并返回 UserDetailDTO 对象了。

下面是一对多

如果你不想使用中间表实现 BankUser 和 BankCard 之间的多对多关系,可以考虑使用一对多和多对一的关联,这需要在 BankUser 中定义一对多关系,为 BankCard 定义多对一关系,例如:

public class BankUser {
    private Long id;
    private String fullName;
    // 其他属性...

    // 一对多关联,一个 BankUser 对象可以对应多个 BankCard 对象
    private List<BankCard> bankCardList; 

    // Getter 和 Setter 方法...
}

public class BankCard {
    private Long id;
    private String bankCode;
    private String bankName;
    private String cardNumber;
    // 其他属性...

    // 多对一关联,一个 BankCard 对象对应一个 BankUser 对象
    private BankUser bankUser;

    // Getter 和 Setter 方法...
}

在定义实体类之后,可以使用 MyBatisPlus 提供的 @TableField 和 @TableId 注解来标注类的属性与数据库表中的字段的对应关系:

public class BankUser {
    // 属性定义...
    @TableField(exist = false)  // 表示该属性在数据库表中不存在
    private List<BankCard> bankCardList;
    // getter 和 setter 方法...
}

public class BankCard {
    // 属性定义...
    @TableField("user_id")  // 表示该属性对应数据库表中的 user_id 字段
    private Long userId;
    // 与 BankUser 之间的多对一关系
    @TableField(exist = false)  // 表示该属性在数据库表中不存在
    private BankUser bankUser;
    // getter 和 setter 方法...
}

在查询 BankUser 时,可以在查询对象 QueryWrapper 中通过 lambda 表达式指定 BankUser 对象需要关联查询 BankCard 对象,并使用 select 方法指定需要查询的字段:

QueryWrapper<BankUser> queryWrapper = new QueryWrapper<>();
queryWrapper.select("b.ID", "b.FULLNAME", "c.BANK_CODE", "c.BANK_NAME", "c.CARD_NUMBER")
    .eq("b.ID", 1L)
    .lambda()
    .leftJoin(BankCard.class, BankCard::getUserId, BankUser::getId)
    .eq(BankCard::getDeleted, 0);
BankUser bankUser = bankUserService.getOne(queryWrapper);

查询结果中,BankUser 对象中的 bankCardList 属性会包含多个 BankCard 对象。需要注意的是,在定义关联关系时,需要通过@TableField注解表明它们所对应的数据库表中的字段。

下面是多对多:

如果 bankUser 和 bankCard 是多对多的关系,那么它们之间是存在中间表的。通常情况下,中间表中除了两个表的主键外,还会包含其他的一些字段,比如创建时间、修改时间等。因此,类的定义中就需要引入一个中间实体类。

假设 bankUser 和 bankCard 是多对多关系,中间表名为 user_card,那么我们可以定义如下的实体类:

public class BankUser {
    private Long id;
    private String fullName;
    // 其他属性...

    // 与中间表 user_card 的关联关系,通过中间表关联 bank_card 表
    private List<UserCard> userCardList;

    // Getter 和 Setter 方法...
}

public class BankCard {
    private Long id;
    private String bankCode;
    private String bankName;
    private String cardNumber;
    // 其他属性...

    // 与中间表 user_card 的关联关系,通过中间表关联 bank_user 表
    private List<UserCard> userCardList;

    // Getter 和 Setter 方法...
}

public class UserCard {
    private Long id;
    private Long userId;  // 与 bank_user 表的外键关联
    private Long cardId;  // 与 bank_card 表的外键关联
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
    // 其他属性...

    // Getter 和 Setter 方法...
}

在定义实体类后,我们可以使用 MyBatisPlus 提供的 @TableField 和 @TableId 注解来标注类的属性与数据库表中的字段的对应关系。具体来说,BankUser 和 BankCard 类中的 userCardList 属性对应的是 UserCard 类的 userId 和 cardId 字段。它们的定义可能如下所示:

public class BankUser {
    // 属性定义...
    @TableField(exist = false)  // 表示该属性在数据库表中不存在
    private List<UserCard> userCardList;
    // getter 和 setter 方法...
}

public class BankCard {
    // 属性定义...
    @TableField(exist = false)  // 表示该属性在数据库表中不存在
    private List<UserCard> userCardList;
    // getter 和 setter 方法...
}

public class UserCard {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @TableField("user_id")
    private Long userId;
    @TableField("card_id")
    private Long cardId;
    @TableField("create_time")
    private LocalDateTime createTime;
    @TableField("update_time")
    private LocalDateTime updateTime;
    // 其他属性...
    // getter 和 setter 方法...
}

在查询 BankUser 时,可以通过 LEFT JOIN 将 bank_user、user_card 和 bank_card 三张表关联起来,并使用 select 方法指定需要查询的字段:

QueryWrapper<BankUser> queryWrapper = new QueryWrapper<>();
queryWrapper.select("b.ID", "b.FULLNAME", "c.BANK_CODE", "c.BANK_NAME", "c.CARD_NUMBER",
        "uc.CREATE_TIME", "uc.UPDATE_TIME")
    .eq("b.ID", 1L)
    .last("LEFT JOIN user_card uc ON b.ID = uc.USER_ID LEFT JOIN bank_card c ON uc.CARD_ID = c.ID");
BankUser bankUser = bankUserService.getOne(queryWrapper);

查询结果中,BankUser 对象中的 userCardList 属性会包含多个 UserCard 对象,每个 UserCard 对象中则包含了与之关联的 BankCard 对象和 BankUser 对象。

需要注意的是,如果使用 MyBatisPlus 进行相关的代码生成,其会自动生成实体类、Mapper 接口和中间表对应的 Service 和 Mapper 接口。可以基于这些接口和类进行后续的开发工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值