zoukankan      html  css  js  c++  java
  • 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();
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    ArcEngine的符号库
    Web programming is functional programming (Web编程是函数式编程)
    arcengine中拓扑的使用(ZZ)
    Win32基于事件驱动的消息机制(ZZ)
    人生要小心处理的50件事
    谁想出来的?
    80后 最牛的辞职信
    能读懂这些话的,都是心里有故事的人
    Try to code some sql statement to catch the consume much CPU time sps.
    读书是为了生命的完整
  • 原文地址:https://www.cnblogs.com/jingyunyb/p/3540662.html
Copyright © 2011-2022 走看看