V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
joooooker21
V2EX  ›  Java

请教关于 Spring Data JPA 表关系映射和多表查询的正确姿势

  •  
  •   joooooker21 · 2019-12-05 12:31:10 +08:00 · 4308 次点击
    这是一个创建于 1597 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前在个人项目中用到了 jpa 来作为持久层,优点很明显,前期基础功能的开发很快,api 也简单易懂。

    在涉及到一些多表的关联查询时,目前是通过 JpaSpecificationExecutor 接口提供的功能来实现,代价是让实体做了多层嵌套

    //例如部门和员工,一对多的关系
    public class Department {
    }
    public class Employee {
        ...
        @ManyToOne
        private Department department;
        ...
    }
    

    这样嵌套之后,问题也很明显。比如要新增一条数据

    public void addEmployee(){
            Employee employee = new Employee();
            Department department = new Department();
            department.setId(666);
            employee.setDepartment(department);
            save(employee);
        }
    

    明显代码不够美观,还存在很多空指针的隐患。

    想请教一下针对 jpa 的多表查询,有没有更好的实现方式?要求是,操作能完全面向对象,代码尽量简洁。

    希望能得到一些建议,谢谢。

    13 条回复    2019-12-09 16:29:37 +08:00
    zhenjiachen
        1
    zhenjiachen  
       2019-12-05 12:39:12 +08:00
    你这是保存把?保存不会报空指针把?查询可以使用 querydsl,很方便,使用 @QuerydslPredicate 还可以和 SpringMvc 结合使用。
    http://www.querydsl.com/static/querydsl/4.1.3/reference/html_single/
    should
        2
    should  
       2019-12-05 12:41:02 +08:00
    可以看看这个项目,挺好用的还是 https://github.com/blinkfox/fenix
    limingjie138
        3
    limingjie138  
       2019-12-05 13:42:54 +08:00
    有唯一的主键关联 拿 example 规则查不就行了吗,我遇到的问题是关联接收两个 1 对多关系的表,建了个功能实体类(就是假实体类 我不想让建关联表就没加注解) 架设 1A 对多 B
    @entity
    public void A(){}
    -------------------------
    @entity
    public void B(){}
    -------------------------
    public void C(){
    private A a;

    }
    limingjie138
        4
    limingjie138  
       2019-12-05 13:44:38 +08:00
    电脑卡了一下= = 发了一半
    @entity
    public void A(){}
    -------------------------
    @entity
    public void B(){}
    -------------------------
    public void C(){
    private A a;
    private B b;
    get……();
    set……();
    }
    丑是丑了点 自己项目就一个需求点 懒得封装了
    joooooker21
        5
    joooooker21  
    OP
       2019-12-05 14:03:34 +08:00
    @zhenjiachen @should 好的,我去了解一下
    joooooker21
        6
    joooooker21  
    OP
       2019-12-05 14:08:56 +08:00
    @limingjie138 如果要构建动态查询,example 实现起来不是很方便
    geying
        7
    geying  
       2019-12-05 15:54:22 +08:00
    前两天用了 jpa,前期用着很方便,后期需要更新字段,复杂查询就感觉很难受,还有几个级联注释搞不明白

    然后换了 mybatis-plus,舒服了
    lau52y
        8
    lau52y  
       2019-12-05 20:50:59 +08:00 via iPhone
    简单还行,复杂都是写 sql,有时候,因为公司大部分不是单表能搞定的,很多业务表关联
    skypyb
        9
    skypyb  
       2019-12-06 08:55:15 +08:00 via Android
    所以问题来了。要是涉及到复杂 sql,jpa 怎么处理?比如那种连多表+分组排序之类的。
    只能手写 sql 吧。那 jpa 能配 xml 来写么
    SAFIIR
        10
    SAFIIR  
       2019-12-06 10:48:36 +08:00
    @skypyb 复杂 sql 的话上 QueryDSL
    joooooker21
        11
    joooooker21  
    OP
       2019-12-06 17:28:53 +08:00
    @lau52y 是的,写 sql 如果要兼容动态查询的话,好像 jpa 就无解了
    zhazi
        12
    zhazi  
       2019-12-07 16:07:46 +08:00 via Android
    那么问题来了,怎样算美?
    部门招人不需要通过部门同意吗?
    PoetAndPoem
        13
    PoetAndPoem  
       2019-12-09 16:29:37 +08:00
    我觉得没问题,ORM 就是这样的。
    代码美观通过重构实现,
    至于 NPE, 你只是 setId 用 sql 来写,其他 property 的 getter 就不报 NPE 了吗。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2485 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 15:43 · PVG 23:43 · LAX 08:43 · JFK 11:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.