您的位置:首页 > 其它

hibernate的核心类和接口

2014-02-08 16:18 232 查看
一、Configuration类
1、负责管理hibernate的配置信息
2、读取hibernate.cfg.xml
3、加载hibernate.cfg.xml配置文件中配置的驱动,url、用户名、密码、连接池
4、管理*.hbm.xml对象关系文件
示意代码:

Configuration cf = new Configuration().configure();


二、SessionFactory(会话工厂)接口
1、缓存sql语句和某些数据(session级缓存也叫一级缓存)
2、在应用程序初始化的时候创建,是一个重量级的类,一般用单例模式保证一个应用中只需要一个SessionFactory实例
3、如果某个应用访问多个数据库,则要创建多个会话工厂实例,一般是一个数据库一个会话工厂实例
4、通过SessionFactory接口可以获取Session(会话)实例
示意代码:

Configuration cf = new Configuration().configure();
SessionFactory sf = cf.buildSessionFactory();
Session s = sf.getCurrentSession();
//或者是 Session s = sf.openSession();


通过SessionFactory获取Session的两个方法:openSession()和getCurrentSession()
1、openSession()是获取一个新的session
2、getCurrentSession()获取和当前线程绑定的session,换言之,在同一个线程中,我们获取的session是同一个session,这样有利于事务控制
  配置可以使用getCurrentSession
  hibernate.cfg.xml
  <property name="current_session_context_class">thread</property>

  Session s1 = MySessionFactory.getSessionFactory().openSession();
  Session s2 = MySessionFactory.getSessionFactory().openSession();
  System.out.println(s1.hashCode()+" "+s2.hashCode()); //10313829 10313830

  Session s1 = MySessionFactory.getSessionFactory().getCurrentSession();
  Session s2 = MySessionFactory.getSessionFactory().getCurrentSession();
  System.out.println(s1.hashCode()+" "+s2.hashCode()); //10313829 10313829

3、如何选择
原则:
(1)如果需要在同一个线程中,保证使用同一个Session则使用getCurrentSession()
(2)如果在一个线程中,需要使用不同的Session则使用openSession()
4、通过getCurrentSession()获取的session在事务提交后,会自动关闭,通过openSession()获取的session则必须手动关闭,但是我们建议不管什么形式获取的session,都手动关闭。
5、如果是通过getCurrentSession()获取session,进行查询也需要事务提交。
本地事务:针对一个数据库的事务
全局事务:跨数据库的事务(jta)

openSession()和getCurrentSession()的联系,深入探讨:
在SessionFactory启动的时候,Hibernate会根据配置创建相应的CurrentSessionContext,在getCurrentSession()被调用的时候,实际被执行的方法是CurrentSessionContext.currentSession()。在currentSession()执行事,如果当前Session为空,currentSession会调用SessionFactory的openSession。

package com.yb.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
final public class HibernateUtil {
private static SessionFactory sessionFactory = null;

//使用线程局部模式
private static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();

private HibernateUtil(){};

static{
sessionFactory = new Configuration().configure().buildSessionFactory();
}

//获取全新的session
public static Session openSession(){
return sessionFactory.openSession();
}

//获取和线程关联的session
public static Session getCurrentSession(){
Session session = threadLocal.get();
//判断是否得到
if(session==null){
session = sessionFactory.openSession();
//把session对象设置到threadLocal,相当于该session已经和线程绑定
threadLocal.set(session);
}
return session;
}

}


三、Session(会话)接口
1、Session一个实例代表与数据库的一次操作(当然一次操作可以是crud组合)。
2、Session实例通过SessionFactory获取,用完需要关闭。
3、Session是线程不同步的(不安全),因此要保证在同一线程中使用,可以用getCurrentSession()。
4、Session可以看做是持久化管理器,它是与持久化操作相关的接口。
示意代码:

Configuration cf = new Configuration().configure();
SessionFactory sf = cf.buildSessionFactory();
Session s = sf.getCurrentSession();
//或者是:Session s = sf.openSession();


get()和load()区别
1、get()方法直接返回实体类,如果查不到数据则返回null。load()会返回一个实体代理对象(当前这个对象可以自动转化为实体对象),但当代理对象被调用时,如果数据不存在,就会抛出个org.hibernate.ObjectNotFoundException异常。
2、load先到缓存(session缓存/二级缓存)中去查,如果没有则返回一个代理对象(不马上到DB中去找),等后面使用这个代理对象操作的时候,才到DB中查询,这就是我们常说的load在默认情况下支持延迟加载(lazy)
3、get先到缓存(session缓存/二级缓存)中去查,如果没有就到DB中去查(即马上发出sql)。总之,如果你确定DB中有这个对象就用load(),不确定就用get()(这样效率高)

四、Transaction(事务)接口
Transaction ts = s.beginTransaction();
......
ts.commit();
s.close();
发生异常需要ts.rollback()回滚

Session sess = factory.openSession();
Transaction tx;
try{
tx = sess.beginTransaction();
//do some work
......
tx.commit();
}catch (Exception e){
if(tx != null) tx.rollback();
throw e;
}finally{
sess.close();
}


五、query接口
通过query接口我们可以完成更加复杂的查询任务

try{
ts = session.beginTransaction();
//获取query引用【这里Employee不是表,而是domain类名】
//【id指的是映射对象的属性名称,而不是对应的表的字段名称】
Query query = session.createQuery("from Employee where id=100");
//通过list方法获取结果,这个list会自动的封装成对应的domain对象

List<Employee> list = query.list();
for(Employee e : list){
System.out.println(e.getName()+" "+e.getHiredate());
}
ts.commit();
}catch(Exception e){
if(ts != null) ts.rollback();
throw e;
}finally{
sess.close();
}


六、Criteria接口
Criteria接口也可用于面向对象方式的查询,关于它的具体用法我们这里先不做介绍,简单的看几个案例。
最简单的案例:返回50条记录

Criteria crit = sess.createCriteria(Cat.class);
crit.setMaxResults(50);
List cats = crit.list();
限制结果集内容
List cats = sess.createCriteria(Cat.class).add(Restrictions.like("name","Rritz%")).add(Restrictions.between("weight",minWeight,maxWeight)).list();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: