(一)SessionFactory
1. getCurrentSession()和openSession()区别
getCurrentSession创建的session会和绑定到当前线程,而openSession不会。
getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭(调用session的close()方法)
这里getCurrentSession本地事务(本地事务:jdbc)时 要在配置文件里进行如下设置
* 如果使用的是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
* 如果使用的是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>
(这个不能忘记,我在测试中如果没有上面在hibernate.cfg.xml中配置,使用getCurrentSession()时,会出错(org.hibernate.HibernateException: No CurrentSessionContext configured!)
在 SessionFactory 启动的时候, Hibernate 会根据配置创建相应的 CurrentSessionContext ,在 getCurrentSession() 被调用的时候,实际被执行的方法是 CurrentSessionContext.currentSession() 。在 currentSession() 执行时,如果当前 Session 为空, currentSession 会调用 SessionFactory 的 openSession 。所以 getCurrentSession() 对于 Java EE 来说是更好的获取 Session 的方法。
(二)Session
1. getTransaction()和beginTransaction()
session.getTransaction()只是根据session获得一个Transaction实例,但是并没有启动它
session.beginTransaction()在获得一个Transaction后调用其begin()方法
2. Session检索方式
概括起来,Hibernate提供了以下几种检索对象的方式:
(1)导航对象图检索方式
根据已经加载的对象,导航到其他对象。
(2)OID检索方式
按照对象的OID来检索对象。Session的get()和load()方法提供了这种功能。如果在应用程序中事先知道了OID,就可以使用这种检索对象的方式。
(3)HQL检索方式
使用面向对象的HQL查询语言。Session的find()和query()接口来执行HQL查询。
(4)QBC检索方式
使用QBC(Qurey By Criteria) API来检索对象。这种API封装了基于字符串形式的查询语句,提供了更加面向对象的接口。
(5)本地SQL检索方式
使用本地数据库的SQL查询语句。Hibernate会负责把检索到的JDBC ResultSet结果集映射为持久化对象图。
导航对象图检索方式
利用类与类之间的关系来检索对象。譬如我们要查找一份订单,就可以由订单对象自动导航找到订单所属的客户对象。当然,前提是必须在对象-关系映射文件上配置了它们的多对一的关系。
Order order = (Order )session.get(Order.class,1);
Customer customer = order.getCustomer();
OID检索方式
主要指用Session的get()和load()方法加载某条记录对应的对象。
Customer customer = (Customer )session.get(Customer.class,1);
Customer customer = (Customer )session.load(Customer.class,1);
HQL(Hibernate Query Language)检索方式
是面向对象查询语言,它具有以下功能:
- 在查询语句中设定各种查询条件;
- 支持投影查询,即仅检索出对象的部分属性;
- 支持分页查询;
- 支持连接查询;
- 支持分组查询,允许使用having和group by关键字;
- 提供内置聚集函数,如sum()、min()和max();
- 能够调用用户定义的SQL函数;
- 支持动态绑定参数。
find()和query()都支持HQL检索方式,区别在于:前者只是执行一些简单的HQL语句的便捷查询,它不具有动态绑定参数的功能,而且在将来版本中,有可能会淘汰find()方法;而query()接口才是真正的HQL查询接口,它提供了以上列出的所有功能。
1 Query query = session.createQuery("from Customer as c where " +"c.name=:customerName and c.age=:customerAge"); 2 // 动态绑定参数 3 query.setString("customerName", "Test"); 4 query.setInteger("customerAge", 21); 5 // 执行检索 6 List result = query.list(); 7 // 方法链编程风格 8 List result1 = session.createQuery( "from Customer as c where c.name=:customerName and c.age=:customerAge").setString( "customerName", "Test").setInteger("customerAge", 21) .list();
QBC(Qurey By Criteria)检索方式
QBC API提供了检索对象的一种方式,它主要由Criteria接口、Criterion接口和Expression类组成,它支持在运行时动态生成查询语句。
1 Criteria criteria = session.createCriteria(Customer.class); 2 3 Criterion criterion1 = Expression.like("namr", "T%"); 4 5 Criterion criterion2 = Expression.eq("age", new Integer(21)); 6 7 criteria = criteria.add(criterion1); 8 9 criteria = criteria.add(criterion2); 10 11 // 执行检索 List result = criteria.list(); 12 13 // 方法链编程风格 List result1 = session.createCriteria(Customer.class).add(Expression.like("namr""T%")).add(Expression. 14 15 eq("age", new Integer(21))).list(); 16 17 Hibernate还提供了QBE(Qurey By Example)检索方式,它是QBC的子功能。QBE允许先创建一个随想模板,然后检索出和这个样板相同的对象。 18 19 示例代码: 20 21 Customer exampleCustomer=new Customer(); 22 23 exampleCustomer.setAge(21); 24 25 List result1 = session.createCriteria(Customer.class).add( Example.create(exampleCustomer)).list();
QBE的功能不是特别强大,仅在某些场合下有用。一个典型的使用场合就是在查询窗口中让用户输入一系列的查询条件,然后返回匹配的对象。QBE方式目前只能支持对象属性字段的等于查询和字符串的模糊匹配,不能支持区间,或者,大于等操作。在这些情况下,还是采用HQL检索方式或QBC检索方式。
本地SQL检索方式
采用HQL或QBC检索方式时,Hibernate生成标准的SQL查询语句,使用于所有的数据库平台,因此这两种检索方式都是跨平台的。有的应用程序可能需要根据底层数据库的SQL方言,来生成一些特殊的查询语句。在这种情况下,可以利用Hibernate提供的SQL检索方式。
1 Query query = session.createSQLQuery("select {c.*} from CUSTOMER as c where c.NAME like :customerName and c.AGE=:customerAge"); 2 3 // 动态绑定参数 4 5 query.setString("customerName", "Test"); 6 7 query.setInteger("customerAge", 21); 8 9 // 执行检索 10 11 List result = query.list();
以上我们看到了五种检索方式的应用,在实际项目中用的最广泛的还是HQL和QBC。