关于 spring data jpa 的一些业务问题

2020-06-11 00:23:20 +08:00
 yumc

1.多条件动态查询如何实现呢?
目前是使用 @Query 写原生 SQL,通过 IF 表达式实现,SQL 非常臃肿并且存在两个小问题。
还望各位前辈指导。
2.更新操作目前解决方案是通过先查询,再赋值,最后使用 save 方法更新,这样做是不是不合适呢? 我看过相关博客文章,有提到重写 jpa 的 save 方法可以做饭动态更新(不更空属性),接下来我会尝试一下。
请问各位大佬有没有更成熟的 jpa 多条件动态查询 和动态更新的解决方案呢,非常感谢各位的建议。

3390 次点击
所在节点    Java
17 条回复
njshiyanhz
2020-06-11 00:35:08 +08:00
querydsl
bxb100
2020-06-11 02:12:21 +08:00
2 挺合适
zhazi
2020-06-11 02:15:58 +08:00
voidxx
2020-06-11 08:37:47 +08:00
站内搜索 [querydsl]
hantsy
2020-06-11 08:46:33 +08:00
1. Spring Data JPA 集成了多种方法,这些只要看了文档就不会有疑问了。
a 基于 Certeria API 的 Specification
b Query By Example
cQueryDSL
https://github.com/hantsy/spring4-sandbox/tree/master/data-jpa/src/main/java/com/hantsylabs/example/spring/jpa

基于字符拼接的查询方式这几年几乎不用,好几个项目中明文要求是不允许用,国内只管结果的, 当然很少公司有代码洁癖,很少讲 Typesafe 的。另外如果能够做 Typesafe 的还 JOOQ 代替 Jdbc SQL 的语句。


2.本来就应该这样用
damai0419
2020-06-11 09:11:06 +08:00
1 、querydsl
2 、合适
Ico945
2020-06-11 09:52:56 +08:00
刚好新接触一个项目是 JPA 的,用 querydsl 很方便,可以把条件放到一个数组里然后执行 sql 操作就不显臃肿;查询更新再赋值好多都是这么做的- -
EastLord
2020-06-11 10:18:54 +08:00
2.更新操作可以不用 save
caotian
2020-06-11 10:47:21 +08:00
1. specification
2. json patch
cnwlei
2020-06-11 11:43:04 +08:00
query.where(cb.and(ps.toArray(new Predicate[ps.size()])));
yumc
2020-06-11 13:25:58 +08:00
谢谢各位的解答。
我在周末会详细的分析学习以下,非常感谢😘
hantsy
2020-06-11 13:46:51 +08:00
@EastLord 嗯,Hibernate 中在一个 Session 生命周期内, 状态的修改,在 flush 时(事务会触发)自动同步到数据库。Hibernate 以前在 Seam 最常用的一种方式,是手动 Flush,在一个 Conversation 内,多次修改(比如多步提交),最后提交手动 Flush 才同步到数据库。
Cowhitewhite
2020-06-11 13:49:38 +08:00
哈哈 我之前都是?1 ?2 ?3
lickysee
2020-06-11 14:21:16 +08:00
lickysee
2020-06-11 14:24:50 +08:00
提供一个自己的思路,代码仅供参考,希望对你有帮助。
```
public class SpecificationUtil {

public static <T> Specification<T> stringLike(
final String field,
final String param
) {
return skipNullAndBlank(
param,
(builder, root) -> builder.like(root.get(field), "%" + param + "%")
);
}


private static <T> Specification<T> skipNullAndBlank(
String p,
BiFunction<CriteriaBuilder, Root<T>, Predicate> f
) {
return ((Specification<T>) (root, query, builder) -> {
if (Strings.isBlank(p)) {
return query.getGroupRestriction();
} else {
return f.apply(builder, root);
}
});
}
}
```
lickysee
2020-06-11 14:28:19 +08:00
大致上的思路就是将判断如果是空就不进行查询这种重复的代码提取出来,返回一个 Specification,然后结合官方给出来的例子,进行条件的拼接。

参照官方文档 Example 98. Combined Specifications
wysnylc
2020-06-11 14:34:27 +08:00
不要用注解写 sql,维护起来很麻烦
先查询后更新有并发问题记得加锁,有事务也有并发问题不要觉得加了事务就万无一失

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

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

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

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

© 2021 V2EX