1、load() 和get() 方法 首先都会去session中 check 是否存在相同PK的instance。
(1)、如果存在,那么就立刻返回 session中的 instance 。可能返回 一个代理(load方式内含主键),也可能返回一个actual entity class instance(get方式)。
(2)、如果不存在,load方法 创建并返回一个代理proxy ,get方法会去数据库查询并返回一个实例
instance of the actual entity class .
所以,不管load或者get方法返回代理还是实例,都依赖于你在当前session期间第一次想获得相同PK实例的调用的方式是load还是get。So , whetherget()
orload()
return proxy or the actual entity class depends on whether you use get() or load() to get the instance of the same PK in the current session for the first time。
Session session = HibernateUtil.getSessionFactory().openSession(); Item loadItem= (Item ) session.load(Item.class, 1); System.out.println(loadItem.getClass().getName()); Item getItem = (Item ) session.get(Item .class, 1); System.out.println(getItem .getClass().getName());
load()
and
get()
to see the effect.
2、如果load返回一个代理,他不会立刻访问数据库在load方法中,那么代理proxy什么时候会访问数据库?
(1)、如果在当前session期间没有找到相同PK的实例的其他属性(除了PK以外的属性) item.getName() 那么就会查询数据库.
(2)、在代理访问数据库以后,相同PK的实例会存在session缓存中, 所以当你用代理获取实例的其他属性的时候,或者你用get方法获取相同PK的实例,数据库将不会再访问,因为session已经存在。
For example:
/**Session starts***/ Item item = (Item) session.load(Item.class, new Long(1)); item.getId(); //Will not access DB as only the identifier property is access 不会访问数据库 item.getDescription(); // access the DB and initialize the proxy . After that , the item proxy is said to be initialized 访问数据库并实例化 item.getPrice(); //will not access DB as the item with the PK 1 can be get from the session 不会访问数据库 因为session中已经存在 Item item2 = session.get(Item.class, new Long(1)) //will not access DB as the item with the PK 1 can be get from the session 不会访问数据库因为已经存在
3、如果你用load方法实例化一个无效的PK,或者访问实例的其他属性或者调用一个方法(例如
isInitialized()
) 在代理proxy上,那么会抛出一个ObjectNotFoundException
异常,所以如果你能捕获这个异常 ,那么就表示 代理加载到了一个无效的PK.
如果你想确定 运行期 ID是否有效,你可以使用get方法 并且check 是否返回null 。load()方法经常使用在 设置了外键关联的地方。
get()方法使用在 你想加载对象 的时候Use get()
when you want to load an object
load()方法使用在你想获取对象的关联属性 但是又不想通过额外的sql语句查询的时候。Useload()
when you need to obtain a reference to the object without issuing extra SQL queries。例如:
for example, to create a relationship with another object:
public void savePost(long authorId, String text) { Post p = new Post(); p.setText(text); // No SELECT query here. 没有额外的查询Author表 // Existence of Author is ensured by foreign key constraint on Post.确保Post的外键关联Author的主键。 // 确保 authorId 在数据库中确实存在。在有外键关联的地方,防止插入的时候报错。因为主表没插入数据不存在。 p.setAuthor(s.load(Author.class, authorId)); s.save(p); }