看我写的数据库操作public   class HQLSession {
HibernateSessionFactory sessionFactory;
public List query(String hql){
List list=new ArrayList();
org.hibernate.Session session=sessionFactory.getSessionFactory().openSession();

try{
Transaction tx = session.beginTransaction();
Query q=session.createQuery(hql);
tx.commit();
list=q.list();
session.close();
}
catch(Exception e)
{
session.close();
e.printStackTrace();
}
return list;
}
         public void update(BaseObject baseBean){
org.hibernate.Session session=sessionFactory.getSession();
Transaction tx = session.beginTransaction();
try{
session.update(baseBean);
tx.commit();
session.close();
}
catch(Exception e){
session.close();
e.printStackTrace();
}
}
}在业务中直接调用
          HQLSession session=new HQLSession ();
              String hql="from Bean";
                    session.query(hql);这样每次都实例化HQLSession 是不是很有些问题?
问题严重吗?多人访问的时候会出现什么问题?

解决方案 »

  1.   

    如果只是常规使用(偶发性操作),我觉得倒没有太大的问题,但
    org.hibernate.Session session
    建议是按事务来调用,你这样做,就难以管理事务了。而且,当需要一次性执行大量SQL的时候,频繁创建Session就会有些问题。对hibernate不是很精通,仅供参考。
    学习一下有没有更深刻的看法。
      

  2.   

    HibernateSessionFactory sessionFactory; 
    怎么没有看到初始化?sessinFactory不能频繁初始化。session使用前打开,使用完立即关闭,在简单的应用里影响不大,况且有连接池缓存如果用spring的话,一般把事务控制在service的方法,一个事务开始前打开session,提交后关闭
      

  3.   

    HibernateSessionFactory  就是MyEclipse创建 Hibernate 时候自动创建的 方法。应该是容器自动加载的。
    我的业务就是大概每天不足10个人去往数据库中写数据,不足100人查询数据库。
    没有使用以前公司的架构,自己写的这个简单,虽然不是很好,但是觉得这样简单,开发速度快。只要不会出现严重的bug就好了。
      

  4.   

    你在Dao里直接控制事务在Biz里应该会有bug,事务应该在Biz里控制,不然对于数据库操作失败,你的事务回滚是不对的,你回滚的时候只是回滚最后一次数据操作,之前的操作都会成功。还有就是在发生异常时应该有rollback();。建议SessionFactory不要在这里创建,可以写一个Util类,用单例或者在静态初块里对SessionFactiory初始化。
      

  5.   


    你这个只能算是单一的了解学习Hibernate的代码,当然代码运行是没问题的,但我觉得用到业务里这就显得很寡.
    个人观点:
    1.你的业务逻辑已经变相移到了dao层,这样在添加个很小的新的业务时,你都会很麻烦,要编写大量重复代码;
    2.按理来说事务的支持是一定要放在biz层统一管理的,这样会避免对数据库操作时的错误,例如想要统一执行一系列操作时,有的成功有的失败;
    3.楼上仁兄说的写一个Util类,也没什么意义,因为在HibernateSessionFactory里就已经在静态块里初始化了,所以个人认为频繁实例化没太大影响.
      

  6.   

    不建议你这样写,你这样写每次实例化一个SessionFactory
    sessinFactory不能频繁初始化,因为sessionFactory是线程安全的
    一个数据库只能针对一个SessionFactory
      

  7.   

        最好这样写:
        一个Session一个事务
        一个线程一个Session
      

  8.   

    sessinFactory不能频繁初始化,因为sessionFactory是线程安全的 
    一个数据库只能针对一个SessionFactory.
     你应该在写一个factory来得到 SessionFactory;
       
      

  9.   

    楼主参考我的处理方式
    我在处理这种情况时
    习惯在dao层建立一个抽象类AbstractDao,
    用来实现了基本的增,删,改,查以及对session 的管理
    只能给你贴部分了(正在用着呢)
    public abstract class AbstractDao implements IDao { private SessionFactory sessionFactory; private Class clazz; private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); public SessionFactory getSessionFactory() {
    return sessionFactory;
    } public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
    } protected static void closeSession() throws HibernateException {
    Session session = threadLocal.get();
    threadLocal.set(null); if (session != null) {
    session.close();
    }
    } protected Session getSession() {
    Session session = threadLocal.get(); if (session == null || !session.isOpen()) {
    session = sessionFactory.openSession();
    threadLocal.set(session);
    }
    return session;
    } public Class getClazz() {
    return clazz;
    } public void setClazz(Class clazz) {
    this.clazz = clazz;
    }
            ..........
      

  10.   

    没得问题的,只要不经常开关sessionFactory就行了
      

  11.   

    楼主代码其实很不错的,只要注意sessionFactory不能频繁创建和销毁即可,因为这个比较耗资源。一般而言,sessionFactory和应用的声明周期一致,即应用开始时,就建立好一个或者借个sessionFactory,某些类如果需要就将它作为参数传入即可。还有一般情况下,一个数据库实例对应一个sessionFactory。
      

  12.   

    有的说好有的说坏。。
    以前都是直接使用 公司架构师设计好的架子直接用,自己做项目的时候感觉虽然考虑问题很全面但是也很繁琐,本来JAVA开发速度就慢,在加上这些乱其八糟的出了问题都不知道怎么解决。所以自己写了一个不管性能、不管以后维护是否简单、不管分层,只要不会出现错误就行了。以前我用的较多的架子都跟10楼的比较相像不过比他那个还复杂一些,看着就头痛。
      

  13.   

    这个利用Myeclipse工具添加Hibernate框架自动会创建一个sessionFactory
    import org.hibernate.HibernateException;
    import org.hibernate.Session;
    import org.hibernate.cfg.Configuration;/**
     * Configures and provides access to Hibernate sessions, tied to the
     * current thread of execution.  Follows the Thread Local Session
     * pattern, see {@link http://hibernate.org/42.html }.
     */
    public class HibernateSessionFactory {    /** 
         * Location of hibernate.cfg.xml file.
         * Location should be on the classpath as Hibernate uses  
         * #resourceAsStream style lookup for its configuration file. 
         * The default classpath location of the hibernate config file is 
         * in the default package. Use #setConfigFile() to update 
         * the location of the configuration file for the current session.   
         */
        private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
    private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
        private  static Configuration configuration = new Configuration();
        private static org.hibernate.SessionFactory sessionFactory;
        private static String configFile = CONFIG_FILE_LOCATION;    private HibernateSessionFactory() {
        }

    /**
         * Returns the ThreadLocal Session instance.  Lazy initialize
         * the <code>SessionFactory</code> if needed.
         *
         *  @return Session
         *  @throws HibernateException
         */
        public static Session getSession() throws HibernateException {
            Session session = (Session) threadLocal.get(); if (session == null || !session.isOpen()) {
    if (sessionFactory == null) {
    rebuildSessionFactory();
    }
    session = (sessionFactory != null) ? sessionFactory.openSession()
    : null;
    threadLocal.set(session);
    }        return session;
        } /**
         *  Rebuild hibernate session factory
         *
         */
    public static void rebuildSessionFactory() {
    try {
    configuration.configure(configFile);
    sessionFactory = configuration.buildSessionFactory();
    } catch (Exception e) {
    System.err
    .println("%%%% Error Creating SessionFactory %%%%");
    e.printStackTrace();
    }
    } /**
         *  Close the single hibernate session instance.
         *
         *  @throws HibernateException
         */
        public static void closeSession() throws HibernateException {
            Session session = (Session) threadLocal.get();
            threadLocal.set(null);        if (session != null) {
                session.close();
            }
        } /**
         *  return session factory
         *
         */
    public static org.hibernate.SessionFactory getSessionFactory() {
    return sessionFactory;
    } /**
         *  return session factory
         *
         * session factory will be rebuilded in the next call
         */
    public static void setConfigFile(String configFile) {
    HibernateSessionFactory.configFile = configFile;
    sessionFactory = null;
    } /**
         *  return hibernate configuration
         *
         */
    public static Configuration getConfiguration() {
    return configuration;
    }}然后DAO直接用就可以了
    import java.util.List;import org.hibernate.Query;
    import org.hibernate.Session;import com.bookshop.hibernate.HibernateSessionFactory;
    import com.bookshop.hibernate.dao.IBookDao;
    import com.bookshop.hibernate.pojo.Book;
    import com.bookshop.hibernate.pojo.BookType;public class BookDao implements IBookDao { public void delete(Book book) {
    // TODO 自动生成方法存根

    } public void deleteByHql(String hql) {
    // TODO 自动生成方法存根

    } public void deleteById(int id) {
    // TODO 自动生成方法存根

    } public void insert(Book book) {
    Session session=HibernateSessionFactory.getSession();
    session.save(book);
    session.beginTransaction().commit();
    HibernateSessionFactory.closeSession();
    } public List queryByType(BookType type) {
    Session session=HibernateSessionFactory.getSession();
    String hql="from Book as b where b.bookType.id="+type.getId();
    Query query=session.createQuery(hql);
    List books=query.list();
    HibernateSessionFactory.closeSession();
    return books;
    } public Book queryByObject(Book book) {
    Session session=HibernateSessionFactory.getSession();
    book=(Book)session.get(Book.class, book.getId());
    HibernateSessionFactory.closeSession();
    return book;
    } public void update(Book book) {
    Session session=HibernateSessionFactory.getSession();
    session.update(book);
    session.beginTransaction().commit();
    HibernateSessionFactory.closeSession();
    }}
    你参考一下吧
      

  14.   

    16楼和我的基本一样,不过你的没有处理异常,也没有处理事务的回滚。这样做如果查询的时候出现异常你的session就不正常关闭了吧?
      

  15.   

    你为什么不自己写一个单例工厂啊,你每次去创建内存点用量很大的,你要在大型项目中我建议你去用一下ibatis这个框架很好啊,比这个hibernate强多了,速度也快多了,