什么是Hibernate的load()方法上下文中的代理?

Cha*_*nya 33 java proxy hibernate

该load()方法的Hibernate文档说:

请注意,如果没有匹配的数据库行,load()将抛出不可恢复的异常.如果使用代理映射类,则load()只返回未初始化的代理,并且在调用代理方法之前实际上不会命中数据库.如果您希望创建与对象的关联而不实际从数据库加载它,这将非常有用.如果为类映射定义了批量大小,它还允许将多个实例作为批处理加载.

请通过以粗体解释上面突出显示的部分的含义来帮助我理解这一点.

Gui*_*ume 70

代理是Hibernate动态生成的类,用于帮助延迟加载.例如,如果你有一个Cat类,Hibernate将生成一个扩展的代理类Cat.

如果你获得了这个代理的未初始化实例,基本上它的所有字段都将为null,除了ID,因为Hibernate尚未命中数据库.现在你第一次在这个代理上调用一个方法,它会意识到它没有被初始化,它将查询数据库以加载它的属性.这是可能的,因为动态生成的类会覆盖基类的方法并添加此初始化/未初始化的检查.

现在假设您的Cat类不是代理并且它具有father关联,当您加载Cat对象时,Hibernate将需要加载它的所有属性.因此,如果你加载一个Cat对象,Hibernate还需要加载它的父亲和父亲的父亲等等.使用代理使Hibernate只能加载所需的实例.

Cat cat1 = (Cat) session.load(1);
Cat cat2 = (Cat) session.load(2);
Cat cat3 = (Cat) session.load(3);

cat1.meow(); // this will cause Hibernate to run a query to load cat1's data
cat2.meow(); // this will cause Hibernate to run a query to load cat2's data

// After this cat3 is still an uninitiated proxy because it has not been used
Run Code Online (Sandbox Code Playgroud)

batch-size是Hibernate的另一个特性,在大多数情况下,它有助于处理延迟加载.基本想法是,休眠保持未初始化代理轨道并且当需要一个被初始化,一个单一的查询将被执行加载到 batch-size代理(而不是仅仅一个代理/查询)

Cat cat1 = (Cat) session.load(1);
Cat cat2 = (Cat) session.load(2);

cat1.meow(); // if batch-size >= 2, cat1 and cat2 will be loaded in a single query
cat2.meow(); // no query will be executed here
Run Code Online (Sandbox Code Playgroud)

  • 这个答案对 Hibernate 代理有勇气。简短且内容丰富。 (2认同)

Ein*_*rve 11

这类似于关联的延迟加载,但可能被视为更多的"懒惰创建".

代理是在运行时实现的子类.Hibernate创建一个代理(正在获取的类的子类)而不是直接查询数据库,并且只要调用其中一个方法,此代理就会从数据库加载"真实"对象.

第二个突出显示的文本说明如果您调用load()多个实例,则可以批量获取它们,这样可以减少到数据库的往返.

这也是load()和get()之间的区别,加载对象的延迟加载排序,而get立即从数据库中获取对象