浅谈Hibernate中的几个查询
一、load和get
相信大家对这两个方法已经非常熟悉了,都是根据数据索引来查找对象,这里针对其区别来从各方面比较一下:
1、load方面在查询时,先从一级缓存中寻找与数据索引对应的实体对象,然后构建并返回一个代理对象,当我们真正使用这个代理对象的时候,这时候才会进入二级缓存查找或到数据库加载数据,如果数据库中没有找到则抛出一个ObjectNotFoundException;
2、get方法在查询时,同样是先从一级缓存中寻找与数据索引对应的实体对象,如果有则直接返回该实体对象,如果没有则马上进入二级缓存查找或到数据库加载数据,查找到则直接返回查询对象,没有则返回一个null;
二、list和iterator
1 、list方法会直接避开一二级缓存直接到数据库中加载数据,然后将查询结果放入缓存中,当然如果你配置了查询缓存,他会先进入查询缓存寻找,如果没有满足条件的再进入数据库加载数据;
2、iterator方法在查询时是先从数据库中查询出所有满足条件的数据索引,然后再根据这些数据索引进入一级和二级缓存进行匹配,如果对于数据索引有实体对象则直接返回该对象,如果没有则在具体使用对象的时候才会进入数据库加载数据,并且把数据索引和对于实体对象放进缓存;
三、延迟加载
1、对于load方法,它在查询对象的时候始终返回的一个代理对象,那么为什么hibernate要引入这么一个方式呢,为什么不像get方法一样直接返回查询对象呢?出于对hibernate的性能考虑,hibernate则提出了一个解决方案,那就是延迟加载,这里load方法的使用则正是实体对象延迟加载的表现。
2、对于iterator方法,为什么它每次查询对要先将所有满足条件的数据索引查询出来,而不是像list一样直接返回满足条件的结果集?和load方法一样,这样做也是为了解决hibernate的性能问题,当只有具体使用时才会根据数据索引进入数据库加载数据。这里有个问题,当进入数据库加载数据后会将所有满足条件的数据索引和实体对象放进缓存中,但是如果数据有100W条呢?这时候会出现outOfMerroyError,一种解决方案是在一边查询数据时一边session.evict()或sessionFactory.evict();来销毁缓存中的对象。实际应用中对于这种问题还是建议大家使用JDBC来处理。