hibernate工作原理:
1。 读取并解析配置文件
2。 读取并解析映射信息,创建sessionFactory
3. 打开session
4. 创建事务Transaction
5。 持久化
6. 提交事务
7. 关闭session
8. 关闭SessionFactory
============
1. hibernate延迟加载机制
就是配置中的lazy吧,延迟加载就是当真正需要数据的时候,才执行数据的加载操作,有如下延迟加载机制:
实体对象的延迟加载;
集合的延迟加载;
属性的延迟加载;
2. hibernate二级缓存机制
hibernate提供2种缓存机制来提升程序性能,分别为一级缓存和二级缓存,也称内置缓存和外置缓存,该缓存位于数据库和应用程序之间。一级缓存对应于session级别,二级缓存是sessionfactory级别的全局缓存
============
hibernate查询数据的方式,项目中使用到的有HQL, QBC,和本地SQL
HQL:支持分页查询,运行使用having和group by,支持聚集函数如 sum(), min(), max(),能调用用户自定义SQAL,支持动态绑定参数。
Query query = session.createQuery("from customer as c where c.name = :customerName" + "and c.age = :customerAge");
query.setString("customerName" , "tom");
query.setInteger("customerAge" , "21");
list result = query.list();
QBC:主要是 Criteria接口, Criterion接口, Expression类
Criteria criteria = session.createCriteria(customer.class);
Criterion criterion1 = Expression.like("name","t%");
Criterion criterion2 = Expression.eq("age",new Integer(21));
Critera = criteria.add(criterion1) ;
Critera = criteria.add(criterion2) ;
list result = criteria.list();
=========
load() 和 get() 区别:
User user = (User) session.load(User.class, userId);
User user = (User) session.get(User.class, userId);
区别1, load支持延迟加载,get 不支持。 当调用load方法的时候,并不会真正去查询数据库,只有用到user时才会去执行数据库查询。
注意:
User user = (User) session.load(User.class, userId);
System.out.println(user.getId());
对于这两行代码,不会执行数据库操作,因为load后会在hibernate一级缓存里面存放一个map对象,map的key就是userId的值,当你getId()时,它会在一级缓存中拿map的key值,而不去执行数据库查询。
区别2, 如果数据库中没有userId的对象,那么通过get方法加载,返回的是null,通过load加载,返回一个代理对象,如果后面调用user对象的某个属性(比如 user.getPassword())会抛出异常:org.hibernate.ObjectNotFoundException.
--Update
get 方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;反而load 方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库。
hibernate对于load 方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get 方法,hibernate一定要获取到真实的数据,否则返回null。
============
如何优化 hibernate?
表字段要少,表关联不要怕多,有二级缓存撑腰。
使用双向一对多关联,不适用单向一对多???
尽可能的配置对象缓存,不适用集合缓存 ***
一对多使用Bag,多对多使用Set
……
hibernate自身管理一级缓存,如果需要使用二级缓存,则需要自己实现响应的代码,最为通用的memcached (MemcachedCacheProvider需要实现hibernate提供的CacheProvider接口)