想实现 以下子查询的功能
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 字段也一起返回,那就需要
- 再定义一个 pojo 接收所有返回字段。
- 改用
List<POJO> listPoJos(Class<POJO> clazz, IQuery<E> query)
列表接口 或StdPagedList<POJO> stdPagedPoJo(Class<POJO> clazz, IQuery<E> query)
分页接口
这里需要!!!注意!!!的是:
-
定义的pojo需要包含 上面SQL中所有的字段(A.*、bCount),直接定义在pojo类中 而不能使用继承;
-
不能用继承:
原因是 listPoJos 和 stdPagedPoJo 方法,源码中都是使用的
PoJoHelper
的POJO toPoJo(@NonNull Class<POJO> klass, @NonNull Map<String, Object> map, boolean ignoreNotFound)
方法进行结果字段的赋值的。其中反射获取类setter方法时,用的是
klass.getDeclaredMethods
(详见 SetterMeta#buildMetas 方法),获取不到父类中的setter方法。 -
不能缺少字段
同样是
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.");
-
-
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