例如数据库表可能存放有 30 列,本身是列式存储。
实际的查询场景可能每次查询 5 列,且组合可能不一样。
如果用 jpa projections 可能面临需要定义一堆 entiny ,组合数爆炸。

楼主是想说,会定义太多的 dto?

对的 动态列每一个组合可能都需要一个 dto 不太优雅 😂

#2
DTO 处:返回的数据字段换成 Map 类型会不会好些
JPA 处: 我还真忘了 JPA 返回 Map 类型是不是一定要写 native sql ,OP 自己评估下吧

这和 jpa 有什么关系,映射到对象不就这样吗

用 QueryDsl 试试

("select new com.demo.ArticleQueryDto(a.id, a.viewCount) from t_article a")

Query 声明的时候 select 用 new 啊,然后写不同的参数的构造函数就是了呗,转换 sql 语句的时候似乎只会 select 你访问的属性字段,似乎不会再 select 所有字段了

JPA Specification

querydsl 如何

我没觉得不优雅,你这样查询估计也是一个接口对应一个前端视图,静态类型检查反而方便调试。这种生成 dto 的体力活,用 IDEA 的插件 JPA BUDDY 生成就行。

这是个方法 但估计得用 createQuery 写 nativeSql

QueryDsl 很强大 👍 用 DSL 可以实现

可以解决动态 where 但 select column 不行的

哈哈 666 的操作可行 !

理解了。这也是一个法子哈。静态定义理解代价小。但总觉得需要维护很多类, 如果有更新会比较麻烦。

可行! Dsl 可以搞定。 哈哈,其实想知道「更 jpa 」的写法。目前看 new object 不错。

是这种? blog.csdn.net/qq_42815754/article/details/107635867

这种? www.cnblogs.com/cccy0/p/11278168.html

这好像和我之前的问题类似:
www.hesudu.com/t/843880#reply10

你这个返回的列是动态的,这就算到 SQL 那里也不是动态查询,你每次动态选择的列,对 SQL 执行屁影响都没有。WHERE 条件每次都是随机生成的,这才是 ORM 或者 SQL 查询上的动态查询。

请先把你的动态查询给分成两个过程。首先,WHERE 条件动态是一个过程,用 JPA 的 Specification 。然后,返回列的动态是一个过程,这个简单的很,你不论如何都查询出来一个 Entity ( JPA 的要求也必须是一个 Entity 对应一套表),然后在将这个 Entity ,根据接口返回的需要,返回不同的 DTO/VO ,或者仅返回指定字段的 Map (看你的场景,返回哪些列是用得时候才知道的,这样返回 MAP 更合适)。

除了上面 dsl/jpql, 还可以用投射,另外定义个 interface 相当于 dto 来接受结果集

对理解有帮助 👍 这里之所以说是动态,因为默认是全部列返回,如果后端是列存数据库性能就会比较差
你和楼上头像好像。dto 的方法可以👍,但可能一个 entity 我的场景中可以衍生出 15 个 dto 。他们只有个别字段不一样。

Nope !

CriteriaQuery 可以实现👏

场景很相似!

感觉 jdbctemplate 更适合啊,这场景

我觉得你这个其实更应该是 graphQL ?

用下我的这个库吧 ( github.com/ksprider/Surgical ),可以解决一个 entity 对应 n 多种组合的 dto 的场景。

Spring Data JPA + QueryDsl 。强烈推荐。投影查询,对象封装,JOIN 检索,UPDATE 部分列。要多舒服有多舒服。

我写过一个 QueryDsl 的案例,你可以看看。
springboot.io/t/topic/4424

手动赞一下 querydsl 很强大 用了 querydsl 是不是一般都不需要 dao 层了 service 层似乎直接就完成工作了

是的。抽象一下,直接在 Controller 就可以通过 Lambda 操作数据库。很方便,不需要写 Service ,Mapper ,xml 以及一堆堆的映射。

dao 层是为了分层才设计出来的,真正的业务,哪有一条 CRUD 就结束的。

看情况呗,我的业务只是为了更新一个字段。我没必要写过 Service ,写个 Dao 。

public void handler (){
 this.service.apply(query -> {
 return query.update(user).set(user.enabled, false).where(user.id.eq(1)).exec();
 })
}

如果没有编程规范的话 怎么样都行

同意 需要依据团队规范,但这里不知道有没有好的实践方式。

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

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

...