Session缓存
Hibernate的一级缓存是由Session提供的,因此它存在于Session的整个生命周期中,当程序调用save()/update()/saveOrupdate()/get()等及查询接口方法list()/iterator()方法时候,如果session中不存在该对象,那么会先将本次的对象存储到一级缓存中便于以后使用,当Session关闭时同时清空一级缓存数据。clear()/evict();Session的缓存可以减少访问数据库的次数,进而提高效率。保证缓存中的对象与数据库的记录保持同步,当缓存的对象改变后,session不会立即执行sql,而是将多个sql语句合并为一条sql进行执行,提高效率。当用户需要对指定的对象进行修改的时候,如果对于同一个属性修改了多次,其实hibernate的session缓存并不是执行多个update语句,而是以最后一个更新为准而发送一条更新的sql。
session.get()与session.load()方法
get()和load()方法先将获取的对象存储到一级缓存,当再次加载同一个持久化对象的时候先检测一级缓存中是否有该对象,如果有直接获取,不会发送SQL语句,否则才发送SQL
public void cache(){ Session session = SessionUtils.getCurrentSession(); session.beginTransaction(); Query query = null; DataType dataType = null; DataType dataType1 = null; try { // 获取要修改的对象 dataType = (DataType) session.get(DataType.class, new Long(1)); // session.evict(dataType);和session.clear();方法会清理缓存 dataType1 = (DataType) session.get(DataType.class, new Long(1)); System.out.println(dataType == dataType1); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } }
get()如果没有找到持久化类返回null,有可能导致空指针异常。load()如果没有找到持久化类直接抛出异常。get()是直接加载数据,load()是延迟加载,当使用被加载数据的时候才发送SQL。Hibernate对于load()认为数据库一定存在,因此可以放心的使用代理进行延迟加载,如果使用中发现了问题,那么只能抛出异常。而对于get方法一定要获取真实的数据,否则返回null。
Query对象实例中的list()和iterator方法
List()查询出来的结果会被缓存起来,那么当iterator()再查看的时候会先发送查询id的SQL,但是查询实体的SQL不会发出,因为它首先回去一级缓存中获取已经缓存的数据。
Iterator()方法加载的所有的持久化类对象要进行批处理修改的时候,每一个对象都要先缓存再修改,因此在循环中需要释放一级缓存中的内存占用,避免内存溢出。
public void cache(){ Session session = SessionUtils.getCurrentSession(); session.beginTransaction(); Query query = null; try { query = session.createQuery("from DataType"); List list = query.list(); System.out.println(list); // session.clear(); Iterator<DataType> it = query.iterate(); while(it.hasNext()){ System.out.println(it.next()); } session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } }
public void cache(){ Session session = SessionUtils.getCurrentSession(); session.beginTransaction(); Query query = null; try { query = session.createQuery("from DataType"); Iterator<DataType> it = query.iterate(); while(it.hasNext()){ DataType dataType = it.next(); dataType.setVip('K'); session.flush(); session.clear(); } session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } }
list()直接一次性获取到所有持久化类的对象 iterator()先获取的是所有的数据的id值。当真正的遍历使用数据的 时候再发送select语句。因此该方法一定要处于session会话中。 list发送的查询语句只有1条。Iterator发送多条查询语句,因此iterator的效率低下。
list()如果表中有少量条数据,iterator()如果表中有N W条数据