最近在搞这方面的东东,但是感觉有点混乱各位不吝赐教,提供链接之类的都可以

解决方案 »

  1.   

    此回复为自动发出,仅用于显示而已,并无任何其他特殊作用
    楼主【believefym】截止到2008-06-24 11:16:24的历史汇总数据(不包括此帖):
    发帖数:61                 发帖分:3762               
    结贴数:58                 结贴分:3562               
    未结数:3                  未结分:200                
    结贴率:95.08 %            结分率:94.68 %            
    值得尊敬
      

  2.   

    hibernate 有几个核心的接口 session transaction是其中的两个
    session接口提供了一系列操作数据库的方法
    也就是说你想调用这些方法必须用session.XX();的形式
    session是轻量级的,也就是可以创建多个session.而sessionfacotry就是重量级的了
    transaction是事物管理接口,你去看看hibernate的API文档就知道怎么回事了!
    如有不对请楼下的指正
      

  3.   

    谢谢楼上的
    谁再说说关于session,transaction作用范围,session关闭状态的后果之类的,大家能理解我的意思就行,说得可能不是很专业 
      

  4.   

    session---all
    transaction---current session
      

  5.   

    朋友,任何地方都没有Hibernate的官方文档说得清楚。
      

  6.   

    http://www.java2000.net/forumdisplay.jsp?fid=24
    这里有些关于hibernate的资料
      

  7.   

    hibernate对多表操作不太好,ibatis会好一些,只是建议
      

  8.   

    数据库每一次的查询都是一次不小的开销,例如连结的开启、执行查询指令,当数据库与应用服务器不在同一个服务器上时,还必须有远程调用、Socket的建立等开销,在Hibernate这样的ORM框架中,还有数据的封装等开销必须考虑进去。
    快取(Cache)是数据库在内存中的临时容器,从数据库中读取的数据在快取中会有一份临时拷贝,当您查询某个数据时,会先在快取中寻找是否有相对应的拷贝,如果有的话就直接返回数据,而无需连接数据库进行查询,只有在快取中找不到数据时,才从数据库中查询数据,藉由快取,可以提升应用程序读取数据时的效能。
    对于Hibernate这样的ORM框架来说,快取的机制更形重要,在Hibernate中快取分作两个层级:Session level与SessionFactory level(又称Second level快取)。
    这边先介绍Session level的快取,在Hibernate中Session level快取会在使用主键加载数据或是延迟初始(Lazy Initialization) 时作用,Session level的快取随着Session建立时建立,而Session销毁时销毁。
    Session会维护一个Map容器,并保留与目前Session发生关系的资料,当您透过主键来加载数据时,Session会先依据所要加载的类别与所给定的主键,看看Map中是否已有数据,如果有的话就返回,若没有就对数据库进行查询,并在加载数据后在Map中维护。
    可以透过==来比较两个名称是否参考至同一个对象,以检验这个事实:
    Session session = sessionFactory.openSession();
    User user1 = (User) session.load(User.class, new Integer(1));
    User user2 = (User) session.load(User.class, new Integer(1));
    System.out.println(user1 == user2);
    session.close();
    第二次查询数据时,由于在快取中找到数据对象,于是直接返回,这与第一次查询到的数据对象是同一个实例,所以会显示true的结果。
    可以透过evict()将某个对象从快取中移去,例如:
    Session session = sessionFactory.openSession();
    User user1 = (User) session.load(User.class, new Integer(1));
    session.evict(user1);
    User user2 = (User) session.load(User.class, new Integer(1));
    System.out.println(user1 == user2);
    session.close();
    由于user1所参考的对象被从快取中移去了,在下一次查询时,Session在Map容器中找不到对应的数据,于是重新查询数据库并再封装一个对象,所以user1与user2参考的是不同的对象,结果会显示false。
    也可以使用clear()清除快取中的所有对象,例如:
    Session session = sessionFactory.openSession();
    User user1 = (User) session.load(User.class, new Integer(1));
    session.clear();
    User user2 = (User) session.load(User.class, new Integer(1));
    System.out.println(user1 == user2);
    session.close();
    同样的道理,这次也会显示false。
    Session level的快取随着Session建立与销毁,看看下面这个程序片段:
    Session session1 = sessionFactory.openSession(); 
    User user1 = (User) session1.load(User.class, new new Integer(1)); 
    session1.close(); Session session2 = sessionFactory.openSession(); 
    User user2 = (User)session2.load(User.class, new Integer(1)); 
    session2.close(); System.out.println(user1 == user2);
    第一个Session在关闭后,快取也关闭了,在第二个Session的查询中并无法用到第一个Session的快取,两个Session阶段所查询到的并不是同一个对象,结果会显示false。
    在加载大量数据时,Session level 快取的内容会太多,记得要自行执行clear()清除快取或是用evict()移去不使用对象,以释放快取所占据的资源。
    Session在使用save()储存对象时,会将要储存的对象纳入Session level快取管理,在进行大量数据储存时,快取中的实例大量增加,最后会导致OutOfMemoryError,可以每隔一段时间使用Session的 flush()强制储存对象,并使用clear()清除快取,例如:
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();while(....) { // 大量加载对象时的循环示意
        ....
        session.save(someObject);
        if(count % 100 == 0) { // 每100笔资料
            session.flush(); // 送入数据库
            session.clear(); // 清除快取
        }
    }tx.commit();
    session.close();
    在SQL Server、Oracle等数据库中,可以在Hibernate设定文件中设定属性hibernate.jdbc.batch_size来控制每多少笔数据就送至数据库,例如:
    ....
    <hibernate-configuration>
        <session-factory>
            ....
            <property name="hibernate.jdbc.batch_size">100</property>
            ....
        </session-factory>
    <hibernate-configuration>
    在MySQL中则不支持这个功能。
      

  9.   

    事务是一组原子(Atomic)操作(一组SQL执行)的工作单元,这个工作单元中的所有原子操作在进行期间,与其它事务隔离,免于数据来源的交相更新而发生混乱,事务中的所有原子操作,不是全部执行成功,就是全部失败(即使只有一个失败,所有的原子操作也要全部撤消)。 
    在JDBC中,可以用Connection来管理事务,可以将Connection的AutoCommit设定为false,在下达一连串的SQL语句后,自行呼叫Connection的commit()来送出变更,如果中间发生错误,则撤消所有的执行,例如:
    try { 
        ..... 
        connection.setAutoCommit(false); 
        .....     // 一连串SQL操作     connection.commit(); 
    } catch(Exception) { 
        // 发生错误,撤消所有变更 
        connection.rollback(); 
    }
    Hibernate本身没有事务管理功能,它依赖于JDBC或JTA的事务管理功能,预设是使用JDBC事务管理,可以在配置文件中加上hibernate.transaction.factory_class属性来指定Transaction的工厂类别,例如:
    hibernate.cfg.xml
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
      "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
      "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
      <hibernate-configuration>
        <session-factor....        
          <!-- 设定事务管理的工厂类  -->
          <property name="hibernate.transaction.factory_class">
            org.hibernate.transaction.JDBCTransactionFactory         
          </property>
          <!-- 对象与数据库表格映像文件 -->
          <mapping resource="onlyfun/caterpillar/User.hbm.xml"/>
        </session-factory>
      </hibernate-configuration>
    基于JDBC的事务管理是最简单的方式,事实上,Hibernate基于JDBC的事务管理只是对JDBC作了个简单的封装: 
    try { 
        session = sessionFactory.openSession();  
        Transaction tx = session.beginTransaction(); 
    ....
    tx.commit();  // 必须commit才会更新数据库
    } catch(HibernateException e) { 
        tx.rollback(); 
    }
    在一开始的openSession()取得Session时,JDBC的Connection实例之AutoCommit就被设定为false,在 beginTransaction()时,会再度检查Connection实例的AutoCommit为false,在操作过程中,最后要commit (),否则的话对数据库的操作不会有作用,如果操作过程中因发生例外,则最后commit()不会被执行,之前的操作取消,执行rollback()可撤消之前的操作,一个实际的程序如下所示
    FirstHibernate2.java
    package onlyfun.caterpillar;import org.hibernate.HibernateException;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;public class FirstHibernate2 {
        public static void main(String[] args) {
            Configuration config = new Configuration().configure();
            SessionFactory sessionFactory = config.buildSessionFactory();        User user = new User();
            user.setName("momor");
            user.setAge(new Integer(26));        Session session = null;
            Transaction tx = null;        try {
                session = sessionFactory.openSession();
                tx = session.beginTransaction();
                session.save(user);
                tx.commit();
            } catch (Exception e) {
                e.printStackTrace();            if (tx != null) {
                    try {
                        tx.rollback();
                    } catch (HibernateException ee) {
                        ee.printStackTrace();
                    }
                }
            } finally {
                if (session != null) {
                    try {
                        session.close();
                    } catch (HibernateException e) {
                        e.printStackTrace();
                    }
                }
            }        sessionFactory.close();
        }
    }
    PS. 要使用MySQL中的事务处理,必须建立事务表类型的表格,例如InnoDB的表格:
    CREATE TABLE user ( 
    ..... 
    .... 
    ) TYPE = InnoDB;
      

  10.   

    Session是Hibernate运作的中心,对象的生命周期、事务的管理、数据库的存取,都与Session息息相关,就如同在编写JDBC时需关心 Connection的管理,以有效的方法创建、利用与回收Connection,以减少资源的消耗,增加系统执行效能一样,有效的Session管理,也是Hibernate应用时需关注的焦点。 
    Session是由SessionFactory所创建,SessionFactory是执行绪安全的(Thread-safe),您可以让多个执行绪同时存取SessionFactory而不会有数据共享的问题,然而Session则不是设计为执行绪安全的,所以试图让多个执行绪共享一个 Session,将会发生数据共享而发生混乱的问题。 
    在Hibernate参考手册中的 Quickstart with Tomcat 中,示范了一个HibernateUtil,它使用了ThreadLocal类别来建立一个Session管理的辅助类,这是Hibernate的Session管理一个广为应用的解决方案,ThreadLocal是*Thread-Specific Storage 模式*的一个运作实例。
    由于Thread-Specific Stroage模式可以有效隔离执行绪所使用的数据,所以避开Session的多执行绪之间的数据共享问题,以下列出Hibernate参考手册中的HibernateUtil类:
    HibernateUtil.java
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.hibernate.*;
    import org.hibernate.cfg.*;public class HibernateUtil {
        private static Log log = LogFactory.getLog(HibernateUtil.class);
        private static final SessionFactory sessionFactory;
        static {
            try {
                // Create the SessionFactory
                sessionFactory = new Configuration().configure()
                                                    .buildSessionFactory();
            } catch (Throwable ex) {
                // Make sure you log the exception, as it might be swallowed
                log.error("Initial SessionFactory creation failed.", ex);
                throw new ExceptionInInitializerError(ex);
            }
        }    public static final ThreadLocal session = new ThreadLocal();
        public static Session currentSession() {
            Session s = (Session) session.get();
            // Open a new Session, if this Thread has none yet
            if (s == null) {
                s = sessionFactory.openSession();
                session.set(s);
            }        return s;
        }    public static void closeSession() {
            Session s = (Session) session.get();        if (s != null) {
                s.close();
            }        session.set(null);
        }
    }
    在同一个执行绪中,Session被暂存下来了,但无须担心数据库连结Connection持续占用问题,Hibernate会在真正需要数据库操作时才(从连接池中)取得Connection。 
    在程序中可以这么使用HibernateUtil:
    Session session = HibernateUtil.currentSession();
    User user = (User) session.load(User.class, new Integer(1));
    System.out.println(user.getName());
    HibernateUtil.closeSession();
    在Web应用程序中,可以藉助Filter来进行Session管理,在需要的时候开启Session,并在Request结束之后关闭Session,这个部份,在 JavaWorld 技术论坛 的 Wiki 上有篇 在filter中关闭session 可以参考。
      

  11.   

    我们现在的项目,关于DB操作分domain,dao,manager三层,
    分别对应映射类, dao操作,以及业务逻辑操作
    有一个HibernateUtil类class HibernateUtil{
      public UserTransaction beginTransaction(){...}
      public void  commitTransaction(UserTransaction tx){.../*session be closed*/}
      public void rollbackTransaction(UserTransaction tx);
    }
    在manager类里面的业务处理代替是这样一个结构class Manager{
      public void business(){
         try{
            UserTransaction tx = HibernateUtil.beginTransaction();
             //dao operations
            HibernateUtil.commitTransaction(tx);
         }catch(Exception e){
            HibernateUtil.rollbackTransaction(tx);//问题1:commitTransaction已经把session关闭了,怎么还能rollback?要么在commit中出错抛异常的情况下session没有去关闭?
         }
      }
    }
    问题2:在业务逻辑处理过程中,很容易有manager1.business()调用manager2.business()的情况,这样就出现了下面的结构(这个问题我在另一个帖子也问了,可能有人也看到了)class Manager1{
        public void business(){
            Manager2.business();
        }
    }
    beginTransaction
        beginTransaction
        commitTransaction
    commitTransaction也就是出现了事务嵌套的情况,但是从设计上来讲,manager自己处理一个business,包含在一个beginTransaction和commitTransaction中也没错吧这个设计很让我迷惑,感觉很矛盾,各位指点一下吧