Java Hibernate 的 load() 方法上下文中的代理是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20988626/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is proxy in the context of load() method of Hibernate?
提问by Chaitanya
The Hibernate documentation for the load()
method says:
该load()
方法的 Hibernate 文档说:
Be aware that load() will throw an unrecoverable exception if there is no matching database row. If the class is mapped with a proxy, load() just returns an uninitialized proxy and does not actually hit the database until you invoke a method of the proxy. This is useful if you wish to create an association to an object without actually loading it from the database. It also allows multiple instances to be loaded as a batch if batch-size is defined for the class mapping.
请注意,如果没有匹配的数据库行,则 load() 将抛出不可恢复的异常。如果类与代理映射,则 load() 仅返回未初始化的代理,并且在调用代理的方法之前不会实际访问数据库。如果您希望创建与对象的关联而不实际从数据库加载它,这将非常有用。如果为类映射定义了批处理大小,它还允许将多个实例作为批处理加载。
Please help me to understand this by explaining the meaning of the parts highlighted above in bold.
请通过解释上面以粗体突出显示的部分的含义来帮助我理解这一点。
采纳答案by Guillaume
Proxies are classes generated dynamically by Hibernate to help with lazy loading. For instance, if you have a Cat
class, Hibernate will generate a proxy class that extends Cat
.
代理是由 Hibernate 动态生成的类,用于帮助延迟加载。例如,如果您有一个Cat
类,Hibernate 将生成一个扩展Cat
.
If you get an uninitialized instance of this proxy, essentially all its fields will be null except the ID because Hibernate has not yet hit the database. Now the first time you will call a method on this proxy, it will realize that it is not initialized and it will query the database to load it's attributes. This is possible because the dynamically generated class overrides the base class's methods and adds this initialized/uninitialized check.
如果你得到这个代理的一个未初始化的实例,除了 ID 之外,它的所有字段基本上都是空的,因为 Hibernate 还没有访问数据库。现在第一次调用这个代理上的方法时,它会意识到它没有被初始化,它会查询数据库以加载它的属性。这是可能的,因为动态生成的类会覆盖基类的方法并添加此初始化/未初始化检查。
Now assume that your Cat
class is not a proxy and that it has a father
association, when you load a Cat object, Hibernate will need to load all it's attributes. So if you load a Cat
object, Hibernate will also need to load its father and the father's father and so on. Using proxies enable Hibernate to only load the required instances.
现在假设您的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
batch-size
is another feature of Hibernate that, in most instances, help dealing with lazy loading. Basically the idea is that Hibernate keeps track of the uninitialized proxies and when one of the needs to be initialized, a single query will be executed to load up tobatch-size
proxies (instead of just one proxy/query)
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
回答by Einar Bjerve
This is similar to lazy-loading of associations, but might be seen as more of a "lazy-create".
这类似于关联的延迟加载,但可能更像是“延迟创建”。
A proxy is a subclass implemented at runtime. Hibernate creates a proxy (a subclass of the class being fetched) instead of querying the database directly, and this proxy will load the "real" object from the database whenever one of its methods is called.
代理是在运行时实现的子类。Hibernate 创建了一个代理(被获取的类的一个子类)而不是直接查询数据库,并且这个代理将在调用其方法之一时从数据库加载“真实”对象。
The second highlighted text explains that if you call load()
on multiple instances, you can fetch them as a batch, and in that way reduce roundtrips to the database.
第二个突出显示的文本解释说,如果您调用load()
多个实例,您可以批量获取它们,从而减少到数据库的往返次数。
This is also the difference between load() and get(), load sort of lazy-loads the object, while get fetches the object from the database right away
这也是 load() 和 get() 的区别,load 是惰性加载对象,而 get 是立即从数据库中获取对象
回答by Mayank Kesari
Proxy objects are empty instances which are used in Lazy Loading for initialising the object fields when they are demanded using getter method. Until then the object is empty containing only the main ID.
代理对象是空实例,它们在延迟加载中用于在使用 getter 方法需要时初始化对象字段。在那之前,对象是空的,只包含主 ID。