hibernate的核心类和接口

一、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();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
原文地址:https://www.cnblogs.com/jingyunyb/p/3540662.html