Java Spring JPA存储库n+;1问题,一个替代方案
我正在为现有的MySQL数据库编写一个基于Java的服务器。我可以改变数据库的结构,但任何改变也意味着要挖掘一个非常古老的CakePHP项目,我希望尽可能不去触及这个项目 我对Java中的数据库访问没有太多经验,所以当我开始寻找一个好的框架时,我最终得到了Spring数据存储库(主要是因为我已经有了用于REST服务的Spring引导执行器),并且手动滚动Hibernate或其他JPA实现看起来既单调又复杂 现在的问题是,我的查询速度不是很快。例如,查询我的~200个用户,并加载他们的关联(user.groups、user.groups.rights、user.groups.rights.permissions、user.rights、user.rights.permissions、users.nfc_密钥)。我需要所有这些数据,因为连接到Java服务器的一个客户端需要这些信息来登录用户,即使主服务器宕机,也需要这些信息来加速登录(换句话说,它会缓存信息) 问题是,执行查询需要8秒钟!我知道这些问题,具体来说是n+1问题。因为我所有的集合都是延迟加载的,所以hibernate查询组、组、权限等,。。。。为每个用户单独设置。例如,“我的组”字段如下所示:Java Spring JPA存储库n+;1问题,一个替代方案,java,spring,hibernate,ebean,Java,Spring,Hibernate,Ebean,我正在为现有的MySQL数据库编写一个基于Java的服务器。我可以改变数据库的结构,但任何改变也意味着要挖掘一个非常古老的CakePHP项目,我希望尽可能不去触及这个项目 我对Java中的数据库访问没有太多经验,所以当我开始寻找一个好的框架时,我最终得到了Spring数据存储库(主要是因为我已经有了用于REST服务的Spring引导执行器),并且手动滚动Hibernate或其他JPA实现看起来既单调又复杂 现在的问题是,我的查询速度不是很快。例如,查询我的~200个用户,并加载他们的关联(use
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
@JoinTable(
name = "user_group_memberships",
joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")},
inverseJoinColumns={@JoinColumn(name="group_id", referencedColumnName="id")}
)
private List<Group> groups;
@ManyToMany(fetch=FetchType.LAZY,cascade={CascadeType.ALL})
@可接合(
name=“用户\组\成员身份”,
joinColumns={@JoinColumn(name=“user\u id”,referencedColumnName=“id”)},
inverseJoinColumns={@JoinColumn(name=“group\u id”,referencedColumnName=“id”)}
)
私人名单组;
我尝试将FetchType更改为EAGER,唯一的作用是通过查询急切地获取所有组,但不是通过SQL连接,而是通过执行n查询
我在UserRepository中查看并实现了一个查询,使用左连接获取加载信息,需要从列表更改为集合,对由于我的hashCode/equals实现导致的空指针问题感到恼火,再次延迟加载/set代理,以发现查询时间缩短到2秒左右,这还不错,但与CakePHP执行相同查询的速度相比,仍然非常慢
我现在的问题主要是:是否有直接的解决方案可以使用Spring数据存储库来解决此类问题,或者我最好切换到另一个框架(这在项目的早期阶段仍然是可能的)?我专门研究了Play框架中使用的ebean,它们似乎有一个非常好的API,并且还允许定义获取路径(这将更好地解决n+1问题),但是我也了解到该项目维护不善。您的看法是什么?查询速度与很多事情有关: 1.驱动程序-2.数据库-3.连接池配置 根据我在JPA的经验: 尝试在视图层中打开会话,并尝试使用HikariCP 加速连接速度
请注意,我有偏见,因为我是Ebean ORM的主要维护者 Ebean存在的一个主要原因是,我认为JPQL在优化ORM查询/对象图构造方面设计得很差。特别是缺少对“部分对象”和“获取路径”的支持。在某种程度上,JPA fetch组试图解决这些问题,但您注意到这两个问题都是由Ebeans查询语言直接处理的。JPA获取组不符合IMO(例如,从DB、L2和L3构建混合对象图) 请注意,在生活的繁忙时期(孩子们等),我故意保持埃比安的低调。Ebean ORM有一个赞助商,如果你看项目发布,你会发现它的健康状况良好 Eben ORM实际上已经有10年的历史了,所以它并不完全是一个新的或年轻的项目 最近,ElasticSearch集成发布了,它能够从ElasticSearch构建对象图(或对象图的路径)。这可以在不加载数据库的情况下提供读取可伸缩性 此外,您可能知道Ebean可以评测应用程序并自动调优ORM查询(如果没有,请查看视频) 希望这能有所帮助。 干杯,罗伯 更新: 添加一些链接供对细节感兴趣的人参考(并避免N+1、优化ORM查询等):
- N+1
- 部分对象
- 自动查询调整
- ElasticSearch