随笔-9  评论-168  文章-266  trackbacks-0
DAO开发

注:
(1)以下两者都需在Spring XML配置文件中,注册Bean(实现类)来依赖注入SessionFactory.
(2.1)Spring 中进行事务管理的通常方式是利用AOP(面向切片编程)的方式,为普通java类封装事务控制,它是通过动态代理实现的,由于接口是
        延迟实例化的, spring在这段时间内通过拦截器,加载事务切片。原理就是这样,具体细节请参考jdk中有关动态代理的文档。本文主要讲解
        如何在spring中进行事务控制。
(2.2)动态代理的一个重要特征是,它是针对接口的,所以我们的DAO要通过动态代理来让spring接管事务,就必须在DAO前面抽象出一个接口.  当然
       如果没有这样的接口,那么spring会使用CGLIB来解决问题,但这不是spring推荐的方式.

(一)直接使用Hibernate API (不推荐使用)
public class DaoImp implate Dao{
         private SessionFactory sessionFactory;
         private static String hql = "from User u where u.username=? ";

          public void setSessionFactory(SessionFactory sessionFactory){
                    this.sessionFactory=sessionFactory;
          }

           public boolean isValidUser(String username) { 
                try{
                     List userList = sessionFactory.getCurrentSession().creatQuery(hql).setParameter(0,username).list();
                     if (userList.size() > 0) {
                     return true; 
                 } catch (HibernateException ex){
                     throw converHibernaterAccessException(ex);
                  }   
             } 
}
 
优点:与Spring框架完全分离
缺点:(1)无法使用Spring框架封装所提供的额外功能.如,直接使用Hibernate API 需用try...catch()处理HibernateException异常.
         (2)需在实现类中加入setSessionFactory(SessionFactory sessionFactory)属性,接收依赖注入的SessionFactory.

(二)继承 Spring 的 HibernateDaoSupport 使用 HibernateTemplate (不推荐使用getSession())
public class DaoImp extend HibernateDaoSupport implates Dao{
         //private SessionFactory sessionFactory;
         private static String hql = "from User u where u.username=? ";

          //public void setSessionFactory(SessionFactory sessionFactory){
          //          this.sessionFactory=sessionFactory;
          //}


           public boolean isValidUser(String username) { 
              //  try{
              //     List userList = sessionFactory.getCurrentSession().creatQuery(hql).setParameter(0,username).list(); 

                     List userList = getHibernateTemplate().find(hql,username); 
                     if (userList.size() > 0) {
                     return true; 
               // } catch (HibernateException ex){
              //     throw converHibernaterAccessException(ex);
             //  }  
 
             }
 
           public boolean isValidUser(String username,String password) throw DataAccessException { 
                     Session session = getSession();                 //不推荐使用,用完后需手动关闭
                     String[] userlist=new String[2];
                     userlist[0]=username;
                     userlist[1]=password;
                 try{
                     List userList = session.find(hql,userlist);       //Hibernate语句; 
                     session.close();
                     if (userList.size() > 0) {
                     return true; 
                  } catch (HibernateException ex){
                     throw converHibernaterAccessException(ex);
                  }   
             } 
}

特点:对HibernateTemplate没有提供的功能,可以直接调用HibernateDaoSuppor对象的getSession()方法(极其不推荐使用)得到Session对象实例用try{ Hibernate API }catch (HibernateException ex )操作.

(三)对 HibernateTemplate 没有提供的功能, 还可以用HibernateCallback 回调的方法管理数据库. (极其推荐)

 /**
  * 使用 hql 语句进行操作
  * @param hql       HSQL 查询语句
  * @param offset   开始取数据的下标
  * @param length   读取数据记录数
  * @return List       结果集
  */
 public List getListForPage ( final String hql , final int offset , final int length ) {

     List list = getHibernateTemplate().executeFind ( new HibernateCallback ( ) {
           public Object doInHibernate ( Session session ) throws HibernateException, SQLException {
                     Query query = session.createQuery ( hql ) ;
                     query.setFirstResult ( offset ) ;
                     query.setMaxResults ( length ) ;
                     List list = query.list ( ) ;
                     return list ;
           }
    }) ;
    return list ;
 }


//---------------------------------------------------------------------------

final String queryString = "from Fourm";                 //必须定义final类型
   List l= getHibernateTemplate().executeFind(new HibernateCallback(){
    public Object doInHibernate ( Session session ) throws HibernateException, SQLException {
                    Query query = session.createQuery ( queryString ) ;
                    query.setFirstResult ( 0 ) ;
                    query.setMaxResults ( 10 ) ;
                    List list = query.list ( ) ;
                    return list ;
          }

//------------------------------------------------------------



为什么不使用getSession(),而使用回调的详细说明:

紫蝶∏飛揚↗
听个SPRING+HIBERNATE开发的问题.
SPRING想调用HIBERNATE的方法有两种,一种是使用getSession();一种是:HibernateCallback回调.
他们有什么不同?
海绵♂宝宝
前者没有事务管控,Spring把Hibernate最原始的Session给你!但是它不被声明式事务管理的服务!
紫蝶∏飛揚↗
...声明式事务不会对他进行事务管理?
海绵♂宝宝
后者也是把Session返给你,但是通过闭包回调的形式给你使用,Spring会在给你之前做一下手脚,例如:添加声明式事务管理中声明的事务属性!
海绵♂宝宝
因为你写的方法通过匿名函数闭包,然后由Spring去负责执行闭包体内的方法!
海绵♂宝宝
Java里的借口回调基本都是借用匿名内部类实现的闭包!
海绵♂宝宝
你看一下Spring的HibernateDaoSupport的源代码就知道运行过程了!
海绵♂宝宝
直接使用getSession()还不享有Spring提供的模板支持,也就是说你得手动关闭连接,否则会一直挂在那儿,直到超时连接池才会回收这个连接!
海绵♂宝宝
这样很容器连接池连接数量溢出!你懂了啊?
紫蝶∏飛揚↗
嗯.
紫蝶∏飛揚↗
new HibernateCallback(){
    public Object doInHibernate ( Session session ) throws HibernateException, SQLException {
必须这样的方式吗?
海绵♂宝宝
建议补习一下编程中的闭包、回调的知识,再看看Spring的那段代码就可以彻底理解了!
海绵♂宝宝
恩!
紫蝶∏飛揚↗
哦.明白了.
海绵♂宝宝
如果你觉得getHibernateTemplate()提供的方法不足以满足你的要求!你就得这么使用!
紫蝶∏飛揚↗
明白.不够用的情况下用回调.
海绵♂宝宝
闭包JavaScript支持的比较好,因为它是以函数为单元的,Java过于强调面向对象,所以只能用匿名内部类来有限的支持闭包!标准的回调都是方法回调,也就是闭包到方法中,而不是类中!所以Java中的闭包和其他的语言有一些区别的,例如访问外部变量必须是final的!
海绵♂宝宝
据说JDK1.7会加入对函数闭包调用的支持!
紫蝶∏飛揚↗
...历害.
紫蝶∏飛揚↗
偶只知道这样用,不知道为什么这样用.
海绵♂宝宝
那可不行啊!呵呵!我最一开始也不大明白,后来仔细研究了闭包、回调的知识就懂了!
其实这种用法在Swing编程里天天都用啊!把一个匿名的监听器实现类注册到事件源,只不过那个时候没有注意到这是闭包和回调罢了!
紫蝶∏飛揚↗
看来有时间得好好看看了...

posted on 2007-11-23 11:30 紫蝶∏飛揚↗ 阅读(5972) 评论(0)  编辑  收藏 所属分类: SpringHibernate

只有注册用户登录后才能发表评论。


网站导航: