yumc
V2EX  ›  Java

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

  •  
  •   yumc · Jun 11, 2020 · 4233 views
    This topic created in 2168 days ago, the information mentioned may be changed or developed.

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

    17 replies    2020-06-11 14:34:27 +08:00
    njshiyanhz
        1
    njshiyanhz  
       Jun 11, 2020 via Android
    querydsl
    bxb100
        2
    bxb100  
       Jun 11, 2020 via Android
    2 挺合适
    zhazi
        3
    zhazi  
       Jun 11, 2020   ❤️ 1
    voidxx
        4
    voidxx  
       Jun 11, 2020
    站内搜索 [querydsl]
    hantsy
        5
    hantsy  
       Jun 11, 2020
    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
        6
    damai0419  
       Jun 11, 2020
    1 、querydsl
    2 、合适
    Ico945
        7
    Ico945  
       Jun 11, 2020
    刚好新接触一个项目是 JPA 的,用 querydsl 很方便,可以把条件放到一个数组里然后执行 sql 操作就不显臃肿;查询更新再赋值好多都是这么做的- -
    EastLord
        8
    EastLord  
       Jun 11, 2020
    2.更新操作可以不用 save
    caotian
        9
    caotian  
       Jun 11, 2020
    1. specification
    2. json patch
    cnwlei
        10
    cnwlei  
       Jun 11, 2020
    query.where(cb.and(ps.toArray(new Predicate[ps.size()])));
    yumc
        11
    yumc  
    OP
       Jun 11, 2020
    谢谢各位的解答。
    我在周末会详细的分析学习以下,非常感谢😘
    hantsy
        12
    hantsy  
       Jun 11, 2020
    @EastLord 嗯,Hibernate 中在一个 Session 生命周期内, 状态的修改,在 flush 时(事务会触发)自动同步到数据库。Hibernate 以前在 Seam 最常用的一种方式,是手动 Flush,在一个 Conversation 内,多次修改(比如多步提交),最后提交手动 Flush 才同步到数据库。
    Cowhitewhite
        13
    Cowhitewhite  
       Jun 11, 2020
    哈哈 我之前都是?1 ?2 ?3
    lickysee
        15
    lickysee  
       Jun 11, 2020
    提供一个自己的思路,代码仅供参考,希望对你有帮助。
    ```
    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
        16
    lickysee  
       Jun 11, 2020
    大致上的思路就是将判断如果是空就不进行查询这种重复的代码提取出来,返回一个 Specification,然后结合官方给出来的例子,进行条件的拼接。

    参照官方文档 Example 98. Combined Specifications
    wysnylc
        17
    wysnylc  
       Jun 11, 2020
    不要用注解写 sql,维护起来很麻烦
    先查询后更新有并发问题记得加锁,有事务也有并发问题不要觉得加了事务就万无一失
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1418 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 52ms · UTC 17:06 · PVG 01:06 · LAX 10:06 · JFK 13:06
    ♥ Do have faith in what you're doing.