在ORM /实体的延迟加载的情况下,我对术语“水合”的理解如下:
“水合”描述了填充使用延迟加载获取的实体的某些或全部先前未填充的属性的过程。
例如:Author
从数据库中加载类:
@Entity
class Author
{
@Id
long id;
List<Book> books;
}
最初,books
不填充集合。
据我了解,books
从数据库加载集合的过程称为“水化”集合。
这个定义正确吗?我应该在此过程中使用另一个更通用的术语吗?
在ORM /实体的延迟加载的情况下,我对术语“水合”的理解如下:
“水合”描述了填充使用延迟加载获取的实体的某些或全部先前未填充的属性的过程。
例如:Author
从数据库中加载类:
@Entity
class Author
{
@Id
long id;
List<Book> books;
}
最初,books
不填充集合。
据我了解,books
从数据库加载集合的过程称为“水化”集合。
这个定义正确吗?我应该在此过程中使用另一个更通用的术语吗?
Answers:
Hydrate最初是一个术语,用于从db中填充实例化(但为空)的值对象/模型(特别是在Hibernate中)。
其他各种ORM和工具(例如BizTalk)都使用Hydrate和其他相关术语(例如,BizTalk使用术语“脱水”表示实例可用但尚未填充)。
就我个人而言,我不赞成重复进行术语大修,在没有重新发明语言的情况下,填充意味着同一件事。它什么也没有添加,并导致混乱(遇到重新发明的术语时通常会首先想到:这在某种程度上是不同的和神奇的吗?)。
这种语言,特别是脱水的BizTalk扩展是多余的。我希望人们不会忘记说什么,是空还是清晰?
Hydrated及其相关的隐喻本质上是营销工具,其发明旨在将Hibernate与竞争产品区分开。
在这一点上,Hibernate和其他ORM产品已经使用了这些术语多年,因此水合物(和脱水)仍然存在。
由于这是一个非常常见的问题,因此此答案基于我在博客上写的一篇文章。
当您获取实体时,Hibernate将尝试从二级缓存或数据库中加载它。
如果该实体未存储在二级缓存中,则将执行查询并将JDBCResultSet
转换为Object[]
包含加载时实体属性值的。
该二级缓存存储此Object[]
缓存的实体时。因此,从数据库或二级缓存加载实体时,您将获得Object[]
实体属性值数组。
将Object[]
加载的状态转换为Java实体对象的过程称为hydration,它看起来如下:
final Object[] values = persister.hydrate(
rs, id, object,
rootPersister, cols, eagerPropertyFetch, session
);
加载状态以EntityEntry对象的形式保存在当前运行的Persistence Context中,稍后将用于默认的脏检查机制,该机制将当前实体数据与加载时快照进行比较。
加载的状态还用作第二级实体缓存的缓存条目值。
改造实体到的反向操作Object[]
绑定SQL参数值时所使用INSERT
,UPDATE
或DELETE
语句被称为脱水。
水化是一个宽松的名词。在我们公司中,我们使用“补水”来加载整个对象图的所有对象属性。这是一篇讨论各种水合程度的文章(同样,这是一种通用用法,尽管它们在休眠状态下使用)。
我认为,在ORM中,术语“水合物”仅表示框架为您提供了对象。因此,从存储中提取数据后,ORM将对象“水化”。该术语可以在ORM框架为您提供商店中表示的对象/图形时随时使用。
水化是一个通用的ORM域术语,表示一种返回查询结果的方法。它不是一个过程,不是动词,不是发生的动作或事件,而是名词。因此,水合只能意味着使用水合,即使用该特定方法,没有别的东西,并且本身没有带来任何东西,因此永远不应使用。特定的水化可以实例化对象并在返回其引用之前填充它,但是水化通常并不意味着要填充。不同的水合作用返回不同的结构:
这是一个ORM实施细节。一些ORM提供了多种混合方式,您可以通过将一个参数传递给查询生成器来选择一种混合方式,而某些ORM则不给您这种控制权,而是用惯例取代它,以求精明它通常会导致错误的假设。