今天同事碰到一个JPA Query 的问题, 在业务上我们有4个entity
CustomerSetType
一对多个 CustomerSet
CustomerSet
多对一 CustomerSetType, 多对一 master CustomerSet, 一对多 Customer
Customer
一对多 Client
Client
由于业务性质就不具体贴出代码, 基本的实体间关系就如上述所说。 我们使用的是ElipseLink 的 JPA 实现. 在配置多对一, 一对多的 FetchType 都是默认的设置。 也就是说多对一默认的fetchType 是 Eager, 一对多的是Lazy。
现在有一个NameQuery : select cs from CustomerSet cs where cs.customerType.code = 'ABC'
写一个简单的unit test 跑跑, 从log 看到EclipseLink 大约用了 700 多个 query。 汗一个, 难怪客户不爽, 要求改进。
改进的思路是使用 JPA query 的Hint , 只改query的配置, 保持代码annotation的配置不变还是默认方式。 这样基本上以前的代码就不需要改动。
具体的进行过程中碰到的问题:
1, 好像EclipseLink 在 NamedQuery 中 采用标准的JPA lint 名字 , 比如
<hint name="LEFT_FETCH" value="cs.customerSetType"></hint>
从log 的结果来看没有具体效果
2, 只好到EclipseLink 官方网站 找线索, 突然想起上次做查询 需要 Cursor 的时候用Hint 的时候 也碰到一个问题 标准的JPA hint name 它就是不支持。 根据这个提示找到 一个 hint name : eclipselink.left-join-fetch, 为什么要用到 left join 呢? 因为这个CustomerSet 下面可能是还没有关联上 Customer , 同理 Customer 还没有关联上 Client 的。 CustoomerSet,Customer 到Client 有3级, 我们只需要配置 fetch join 到 cs.customerlist.clientlist , 从输出的sql 可以看到有两个 left join , 一个是 customer set left join customer, 一个是 left join client。 再看sql 已经减少到 几十个。为什么还还有这么多呢? 在customer set 实体上一个有 3个一对多的关系, 我们现在只处理掉一个, 还有两个呢, 它到 customer set type, 它自身join 的 master customer set。 如法炮制, 但是它们俩就不需要 left join 了, eclipselink.join-fetch 搞定。
再来看输出的sql 只有 4个了, 主要是因为它自己的级联出来的 master customer set 需要再去搞定 type name 啥的, 基本上没有办法再精简了。
回头想想, 如果现在的OR Mapping 能做到这个效果,效率不比我们自己native sql 出来再拼装 对象的方式差吧。 做个记号,要去down 个 EclipseLink 的代码来看看它的实现补补课了。
分享到:
相关推荐
通过Oracle提供的jar包,实现jpa方式对sdo_geometry的快速支持。
详细讲述了EclipseLink的使用方法。EclipseLink的前身是Oracle的TopLink.
后台使用SpringMvc+Eclipselink+JPA+ActiveMQ+MySQL整合,前段使用sui框架,模拟微信聊天
jar包,官方版本,自测可用
jar包,官方版本,自测可用
JPA-eclipselink-项目使用 EclipseLink 实现的 JPA 项目示例JPA:java persistence api 是一个 O/R 映射持久化的规范。 API 描述了如何将 Java 对象映射到关系数据库。 此映射确保将对象转换为数据库,反之亦然,...
JPA推荐的实现: EclipseLink
eclipselink-jpa-multitenancy JCConf 2014 的多租户示例 如何测试 克隆项目 $ git clone https://github.com/phstudy/eclipselink-jpa-multitenancy.git 更改目录 $ cd eclipselink-jpa-multitenancy 运行...
下载eclipselink.jar,这个jar包版本2.5.2,下载eclipselink.jar
eclipselink 1.0 doc 文档
infinispan-jpa-eclipselink商店该缓存存储实现通过Eclipselink JPA实现将数据持久化到关系数据库。
NULL 博文链接:https://remotejavasky.iteye.com/blog/1182721
eclipselink的英文文档
添加jobss下eclipselink的module实现实体自动扫描
在maven中实现jpa数据库查询的简单demo,非常初级的代码,简单易懂,适合初学者查看学习,直接引入工程即可。
找到的一个eclipselink增删改查
### jpa-eclipselink 在软件开发中,模块化是关键,因为它鼓励可重用性。 但是,如果我们使用像Spring这样的框架,则会带来挑战,因为我们必须配置Bean或添加包扫描路径。 因此,它不能被称为真正的模块。 这个项目...
Glassfish 3.1.2.2 JPA問題整理 EclipseLink 如何更新1
是公认的 Java 持久性框架和 JPA 2.0 的参考实现。 是一种公认的 Java 日志 API 和框架,用于在必要时在一个应用程序中桥接不同的 Java 日志系统。 EclipseLink 使用其自己的日志记录平台,并具有到系统的器。...