FluentMybatis中使用 select子句 子查询

想实现 以下子查询的功能

select a.*, 
	(select count(1) from B as b where b.a_id = a.id) as bCount 
from A as a
order by bCount desc

经过一番踩坑后,记录下实现的方式。。。。

fluent中语法需要使用:

AQuery query = AQuery.query()
	.selectAll()	// 这里相当于 select A.* 把A表原有的列带上
	// 注意这里使用的是 A.id 直接用的是表名,而没有对A表起别名
	// 原因是如果A表使用了别名,那底下orderBy的时候,bCount字段sql也会自动带上别名,那就会出错了
	.select.apply("(select count(1) from B where b.a_id = A.id) as bCount")		// 增加子查询列
	.end()
	.orderBy.desc("bCount").end()

// 查列表
List<AEntity> entities = aDao.listEntity();

// 查分页
Integer page = 1;
Integer size = 10;
StdPagedList<AEntity> pageList = aDao.stdPagedEntity(query.paged(page, size));

如果需要把 bCount 字段也一起返回,那就需要

  1. 再定义一个 pojo 接收所有返回字段。
  2. 改用 List<POJO> listPoJos(Class<POJO> clazz, IQuery<E> query) 列表接口 或 StdPagedList<POJO> stdPagedPoJo(Class<POJO> clazz, IQuery<E> query) 分页接口

这里需要!!!注意!!!的是:

  1. 定义的pojo需要包含 上面SQL中所有的字段(A.*、bCount),直接定义在pojo类中 而不能使用继承;

    1. 不能用继承:

      原因是 listPoJos 和 stdPagedPoJo 方法,源码中都是使用的 PoJoHelperPOJO toPoJo(@NonNull Class<POJO> klass, @NonNull Map<String, Object> map, boolean ignoreNotFound) 方法进行结果字段的赋值的。

      其中反射获取类setter方法时,用的是 klass.getDeclaredMethods (详见 SetterMeta#buildMetas 方法),获取不到父类中的setter方法。

    2. 不能缺少字段

      同样是 POJO toPoJo(@NonNull Class<POJO> klass, @NonNull Map<String, Object> map, boolean ignoreNotFound) 方法,最后一个参数值 默认使用的是 false(虽然PoJoHelper中提供的有 PoJoHelper.toPoJoListIgnoreNotFound 方法,但 IRichMapper 中使用的都是 PoJoHelper.toPoJoList 方法),如果缺少字段,则会报错

      throw new RuntimeException("property[" + name + "] of class[" + klass.getName() + "] not found.");

  2. pojo中的字段类型

    我测试的过程中,数据库中create_time是datetime类型,pojo中定义createTime为Date类型,但结果赋值时报错:

    convert map to object[class=xxxx.dto.ADTO, property=createTime, type=class java.util.Date] error: argument type mismatch
    

    debug时发现,赋值时的value是LocalDateTime类型的,因此

    解决方式:createTime定义为 LocalDateTime 即可解决。

PoJoHelper中还是有一些坑的~~

其他子查询

在尝试实现的时候,也搜了很多资料,但网上能搜到的都是 where f1 in (select xxx) 条件中的子查询

这样的子查询其实语法中已经提供了:

WHERE in(IQuery query);
WHERE notIn(IQuery query);

直接 .where.f1.in(子查询query) 即可

官方文档中也有说明:

https://gitee.com/fluent-mybatis/fluent-mybatis/wikis/exists%20%E5%92%8C%20in%20%E5%AD%90%E6%9F%A5%E8%AF%A2?sort_id=4106029

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值