用更轻的解决方案替换完整的ORM(JPA /休眠):推荐的加载/保存模式?
我正在开发一个新的Java Web应用程序,我正在探索新的方法来保存数据(对我来说是新的!)。我大多有JPA和Hibernate的经验,但是,除了简单的情况,我认为这种完整的ORM可能会变得非常复杂。另外,我不喜欢和他们一起工作。我正在寻找一个新的解决方案,可能更接近SQL。
我目前正在研究的解决方案:
但是,与Hibernate相比,这些解决方案有两个用例我担心。我想知道这些用例的推荐模式是什么。
用例 1 - 获取实体并访问其一些关联的子项和孙项实体。
- 假设我有一个实体。
Person
- 这有一个关联的实体。
Person
Address
- 这有一个关联的实体。
Address
City
- 此实体具有属性。
City
name
- 此实体具有属性。
- 这有一个关联的实体。
- 这有一个关联的实体。
从个人实体开始,访问城市名称的完整路径为:
person.address.city.name
现在,假设我使用此方法从 中加载 Person 实体:PersonService
public Person findPersonById(long id)
{
// ...
}
使用Hibernate,可以根据需要延迟加载与 关联的实体,因此可以访问并确保我有权访问此属性(只要该链中的所有实体都不可为空)。Person
person.address.city.name
但是使用我正在研究的3种解决方案中的任何一种,它都更复杂。有了这些解决方案,有哪些推荐的模式来处理这个用例?首先,我看到了3种可能的模式:
-
所有必需的关联子项和孙项实体都可以由所使用的 SQL 查询预先加载。
但是我看到此解决方案的问题是,可能还有其他一些代码需要从实体访问其他实体/属性路径。例如,也许某些代码需要访问 。如果我想重用我已经拥有的方法,那么SQL查询将需要加载更多信息!不仅是关联实体,还包括关联实体。
Person
person.job.salary.currency
findPersonById()
address->city
job->salary
现在,如果有 10 个其他位置需要从个人实体开始访问其他信息,该怎么办?我是否应该总是急切地加载所有可能需要的信息?或者可能有12种不同的服务方法来加载个人实体?:
findPersonById_simple(long id) findPersonById_withAdressCity(long id) findPersonById_withJob(long id) findPersonById_withAdressCityAndJob(long id) ...
但是,每次我使用一个实体时,我都必须知道它加载了什么,什么没有......这可能很麻烦,对吧?
Person
在实体的 getter 方法中,是否可以检查地址是否已加载,如果没有,则懒惰地加载它?这是现实生活中常用的模式吗?
getAddress()
Person
是否有其他模式可用于确保我可以从加载的模型中访问所需的实体/属性?
用例 2 - 保存实体并确保其关联和修改的实体也已保存。
我希望能够使用此方法保存实体:Person
PersonService
public void savePerson(Person person)
{
// ...
}
如果我有一个实体,并且我更改为其他实体,我如何确保在保存 ?使用 Hibernate,可以轻松地将保存操作级联到关联的实体。我正在研究的解决方案呢?Person
person.address.city.name
City
Person
我是否应该使用某种脏标志来了解在保存人员时还必须保存哪些关联的实体?
是否有任何其他已知的模式可用于处理此用例?
更新 :在JOOQ论坛上有关于这个问题的讨论。