Spring JPA 动态列查询有什么好的思路

2022-06-06 15:28:35 +08:00
 leiuu

例如数据库表可能存放有 30 列,本身是列式存储。

实际的查询场景可能每次查询 5 列,且组合可能不一样。

如果用 jpa projections 可能面临需要定义一堆 entiny ,组合数爆炸。

2987 次点击
所在节点    Java
30 条回复
KingOfUSA
2022-06-07 09:34:33 +08:00
@leiuu 用下我的这个库吧 ( https://github.com/ksprider/Surgical ),可以解决一个 entity 对应 n 多种组合的 dto 的场景。
KevinBlandy
2022-06-07 14:53:27 +08:00
Spring Data JPA + QueryDsl 。强烈推荐。投影查询,对象封装,JOIN 检索,UPDATE 部分列。要多舒服有多舒服。

我写过一个 QueryDsl 的案例,你可以看看。

[https://springboot.io/t/topic/4424]( https://springboot.io/t/topic/4424)
leiuu
2022-06-07 16:27:11 +08:00
@KevinBlandy 手动赞一下 querydsl 很强大 用了 querydsl 是不是一般都不需要 dao 层了 service 层似乎直接就完成工作了
KevinBlandy
2022-06-07 17:45:06 +08:00
@leiuu 是的。抽象一下,直接在 Controller 就可以通过 Lambda 操作数据库。很方便,不需要写 Service ,Mapper ,xml 以及一堆堆的映射。
RookieRicardo
2022-06-07 17:50:11 +08:00
@KevinBlandy

@leiuu

dao 层是为了分层才设计出来的,真正的业务,哪有一条 CRUD 就结束的。
KevinBlandy
2022-06-07 17:55:05 +08:00
@RookieRicardo 看情况呗,我的业务只是为了更新一个字段。我没必要写过 Service ,写个 Dao 。

```java
public void handler (){
this.service.apply(query -> {
return query.update(user).set(user.enabled, false).where(user.id.eq(1)).exec();
})
}
```
RookieRicardo
2022-06-07 17:58:11 +08:00
@KevinBlandy 如果没有编程规范的话 怎么样都行
leiuu
2022-06-07 18:59:29 +08:00
@RookieRicardo 同意 需要依据团队规范,但这里不知道有没有好的实践方式。

QueryDsl 很灵活,service 涉及多个 entiny 也可以支持 。可能很多需求在 service 层写 dsl 就实现了。所以会纠结是否需要独立抽象 dao 层。

```java
QPerson person = QPerson.person;
List<Person> persons = query.from(person)
.where(person.firstname.eq(firstname))
.orderBy(person.surname.desc())
.list(person);

...
```
kongkongye
2022-07-22 19:15:48 +08:00
@nothingistrue 有个问题,如果返回 map 的话是不对 swagger 之类的不太友好,前端单看 swagger 接口说明不知道会返回啥字段,不过好像也没啥好办法
nothingistrue
2022-07-22 21:19:41 +08:00
严格意义上来说,swagger 的接口定义是要自己写 yaml ,跟你后端定义的对象无关的。能够自动根据 Java 类生成 Swagger 接口定义的,是 Springfox-swagger 插件。而这个插件,是允许你通过注解的方式用自己的定义覆盖默认定于一的,所以及时使用 Map 仍然能够不影响 swagger 这类的接口定义,只是需要多做一些注解 /注释性的工作。

当然,用 Map 不影响,不是鼓励 Map ,首选仍然是特定的类。楼主这里推荐用 Map ,是因为它返回内容当中的字段是不固定的,有可能还是前端要啥后端返回啥,这时候没法定义特定的类了(或者说定义的类就用一次,太浪费),用 Map + 注释 /注解会更省事。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/857591

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX