前言

实际开发过程中,关联查询时非常多见的,但是这块我们一般的做法都是写LeftJoin关联查询然后再写个实体接收,这是没问题,但是一些中小型项目就是讲究个,越傻瓜越好,于是乎我找了下,已经有人实现了类似Hibernate那种注解式开发,开箱即用我体验了一把非常NICE,现在把几种实现方式总结如下。

表结构

常见的用户表和订单表,一对多的关系。
用户

订单

实体

用户

@Data
public class User{
    /**
     * 主键
     */
    @TableId(value = "user_id", type = IdType.AUTO)
    private Long userId;
	...

    @TableField(exist = false)
    private List<TOrder> orders;

重点:

@TableField(exist = false)
private List<TOrder> orders;

实现方式

方式一:自带注解式+one、many

本质还是分开单独去查每张表,最后拿到结果返回到实体中

xml同理,注解更简单

public interface TUserMapper extends BaseMapper<TUser> {


    @Results({
            @Result(column = "user_id", property = "userId"),//必须要加,否则user实体中userId为null
            @Result(column = "user_id", property = "orders",//
                    one = @One(select = "com.laker.map.moudle.sys.mapper.TOrderMapper.selectById"))
    })
    @Select("select * from t_user")
    List<TUser> findAllUserAndOrders();

结果

{
  "code": "0",
  "msg": "",
  "data": [
    {
      "userId": 1,
      "userName": "laker",
      "password": "123456",
      "nickName": "老李",
      "createTime": "2021-05-14T15:38:08",
      "orders": [
        {
          "orderId": 1,
          "orderNo": "BA202105",
          "orderUserId": 1,
          "orderTime": "2021-05-14T15:41:18"
        }
      ]
    }
  ]

方式二:自带注解left join

xml同理,注解更简单

    @Select("select u.*,o.order_no order_no from t_user u left join t_order o on  u.user_id = o.order_user_id")
    List<TUser> findAllUserAndOrders();

这里是一次SQL查询效率较高,但是要手写。

方式三:不写SQL类比JPA的OneToOne

对于一对一,一对多,多对一,多对多的关联查询,Mybatis-Plus 在处理时,需要编写关联查询方法及配置resultMap,并且书写SQL。

为了简化这种操作,可以注解来简化。

Mybatis-Plus-Relation ( mprelation ) : mybatis-plus 一对一、一对多、多对一、多对多的自动关联查询,注解方式。

参考地址:https://www.cnblogs.com/dreamyoung/p/12466656.html

步骤一:引入依赖

<dependency>
     <groupId>com.github.dreamyoung</groupId>
     <artifactId>mprelation</artifactId>
     <version>0.0.3.2-RELEASE</version> 
</dependency>

步骤二:配置AutoMapper

只要是扫描被注解的实体类

@Configuration
public class AutoMapperConfig {
    @Bean
    public AutoMapper autoMapper() {
        //配置实体类所在目录(可多个,暂时不支持通过符*号配置)
        return new AutoMapper(new String[]{"com.laker.map.moudle.sys.entity"});
    }
}

步骤三:继承工具类为重写过的IService / ServiceImpl

这里的引用包要改为:com.github.dreamyoung.mprelation

service接口:

public interface IManService extends IService<Man> {}  // IService为重写过的同名接口

Service实现:

@Service
public class ManServiceImpl extends ServiceImpl<ManMapper, Man> implements IManService {}  // ServiceImpl为重写过的同名接口

步骤四:实体配置

    @TableField(exist = false)
    @OneToMany
    @Lazy(false)
    @JoinColumn(name = "user_id", referencedColumnName = "order_user_id")
    private List<TOrder> orders;

如果不加 @Lazy(false),默认是不加载关联对象的,也可以使用编程式解决

        TUser tUser = tUserService.getById(id);
        tUserService.getAutoMapper().mapper(tUser,true);

加群一起抱团取暖,共同进步

🍎QQ群【837324215】
🍎关注我的公众号【Java大厂面试官】,一起学习呗🍎🍎🍎
🍎个人vxlakernote

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐