Hibernate管理Session

2020-03-25  本文已影响0人  BlueSkyBlue

Hibernate自身提供了三种管理Session对象的方法:

在Hibernate配置文件中,hibernate.current_session_context_class属性用于指定Session的管理方式,可选值包括

我们来考虑一个需求,如何在一个DAO类中添加Department对象到数据库中。我们也许会使用构造函数的方式添加。

public void save(Session session, Department dept){
    session.save(dept);
}

若需要传入一个Session,则意味上上一层可能是Service,需要获取到Session对象,上一层需要和Hibernate的API紧密耦合。所以不推荐使用此种方式。我们希望提供一个干净的save方法。

可以获取和当前线程绑定的Session对象,这样做有两个好处:

  1. 不需要从外部传入Session对象。
  2. 多个DAO方法可以使用同一个事务。

使用当前线程绑定的Session来改造上述的程序
首先我们先创建一个HIbernate工具类(HibernateUtil)。该类为单例模式的。

public class HibernateUtils {
    private SessionFactory sessionFactory;

    public static HibernateUtils instance = new HibernateUtils();

    public static HibernateUtils getInstance(){
        return instance;
    }

    public SessionFactory getSessionFactory() {
        if(sessionFactory == null){
            //1.1 Create configuration object.
            Configuration configuration = new Configuration().configure();
            sessionFactory = configuration.buildSessionFactory();
        }
        return sessionFactory;
    }

    public Session getSession(){
        return getSessionFactory().getCurrentSession();
    }
}

之后在DAO中执行保存操作

public class HelloWorldDAO {
    public void save(HelloWorld helloWorld){
        Session session = HibernateUtils.getInstance().getSession();
        session.save(helloWorld);
    }
}

测试类

public void test(){
    Session session = HibernateUtils.getInstance().getSession();
    System.out.println(session.hashCode());
    Transaction transaction = session.beginTransaction();
    HelloWorldDAO dao = new HelloWorldDAO();

    HelloWorld helloWorld = new HelloWorld();
    helloWorld.setTitle("Hello Session");
    helloWorld.setDate(new Date());
    helloWorld.setTitle("Title");
    helloWorld.setAuthor("HFR");
    dao.save(helloWorld);
    transaction.commit();
    System.out.println(session.isOpen());
}

Session是由Thread管理的,则在提交,回滚事务时已经关闭。

Hibernate按照以下规则将Session与本地线程绑定在一起:

批量处理数据

通常指批量的添加,删除和修改。
在应用层进行批量操作,有以下几种方式:

凡是批量操作,使用原生的JDBC API是最快的,而且效率高,速度快。

通过Session

不推荐使用Session进行批量操作:因为Session的save和update方法会把处理的对象放入缓存中,如果通过一个Session来处理大量的持久化对象,应该及时从缓存中清空已处理完毕并不再使用的对象,具体做法是处理完一个对象或小批量的对象后,立即调用flush方法刷新缓存,然后调用clear方法清空缓存。

News news = null;

for(int i=0;i<1000;i++){
  news = new News();
  news.setTitle("title" + i);
  session.save(news);
  if((i+1)%20 == 0){
    session.flush();
    session.clear();
  }
}

通过Session处理操作会遇到记下几种限制:

通过StatelessSession

StatelessSeesion和Session有以下的区别:

注意:HQL只支持INSERT INTO ...SELECT形式的插入语句,但不支持INSERT INTO...VALUES形式的插入语句。所以HQL不能进行批量插入操作。

上一篇 下一篇

猜你喜欢

热点阅读