Spring+Hibernate DAO 持久层开发, Spring 用 Hibernate 访问数据库的三种方法.推荐使用回调(转)...

 

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 ;

}

spring+hibernate架构中Dao访问数据库的几种方法

在spring+hibernate的架构中,访问数据库有几种方法,按spring依赖注入来区分有3种,在这之前先再来了解一下spring的依赖注入,spring主要的两大核心就是IOC(控制反转)和AOP(面向切面编程),控制反转就是控制转移,从以往由Bean去控制要调用的接口或其他资源转移给容器,由容器来寻找并实例化要调用的接口,也可以解释成依赖注入,即在spring配置文件中把要调用的接口、设置、构造子配置给Bean。这边是以依赖注入来区分为sessionFactory、hibernateTemplate、jdbcTemplate,本质上划分只有hibernateTemplate和jdbcTemplate这两种。1、注入sessionFactory

在spring配置文件中,对Dao注入sessionFactory,即:

<bean id="classDao" class="cn.jmu.data.dao.impl.ClassImpl">

<property name="sessionFactory">

   <ref local="sessionFactory" />

</property>

</bean>

这边sessionFactory依赖注入的不是给Dao层中的类,而是给HibernateDaoSupport,见spring源文件org/springframework/orm/hibernate3/support/HibernateDaoSupport.java里面,就有sessionFactory的set、get操作:public final void setSessionFactory(SessionFactory sessionFactory) {

   this.hibernateTemplate = createHibernateTemplate(sessionFactory);//通过sessionFactory来生成hibernateTemplate

}public final SessionFactory getSessionFactory() {

   return (this.hibernateTemplate != null ? this.hibernateTemplate.getSessionFactory() : null);

}所以在Dao层中类继承HibernateDaoSupport,即可通过this.getHibernateTemplate()来对数据库进行操作,

   更新数据:this.getHibernateTemplate().update(bo);

   查询数据:this.getHibernateTemplate().find(bo);

   添加数据:this.getHibernateTemplate().save(bo) ;

   删除数据:this.getHibernateTemplate().delete(bo);

从上面可以看出spring+hibernate的强大威力,存取数据不用像以往jdbc那样,要写一大串try,catch语句,还要连接数据库,用完再关闭数据库连接,而用一条语句就可以搞定。

这里sessionFactory由spring自动自动连接、关闭,当然你也可以手动来连接、关闭,如下面采用的方法:

Session session=this.getHibernateTemplate().getSessionFactory().openSession();

Transaction tx=session.beginTransaction();

/*--------------查询数据------------------------*/

String str="hql";

Query query=session.createQuery(str);

List list=query.list();

/*--------------删除数据------------------------*/

session.load(bo,ID);

   session.delete(bo);

/*--------------添加数据------------------------*/

session.save(bo);  

/*--------------修改数据-----------------------*/

session.load(bo,ID);

   session.update(bo);

/*--------------end---------------------------*/

tx.commit();

session.close();

初学Hebernate的人对这些代码应该很熟悉,没有spring提供hibernateTemplate,在单单的Hibernate中就得用这种方面去访问存取数据了。

2、注入hibernateTemplate

这种方法本质跟上面注入sessionFactory一样,只不过再进行一层包装,这样最大的好处就是Dao中的类就不用再继承HibernateDaoSupport(在java中是单继承的,这唯一一次的继承就被HibernateDaoSupport剥夺去就岂不可惜?)不过在这之前要先要配置好hibernateTemplate,即:

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">

        <property name="sessionFactory">

            <ref bean="sessionFactory"/>

        </property>

    </bean>

再对要用到hibernateTemplate的Dao进行注入依赖,即:

<bean id="ClassDao" class="cn.jmu.data.dao.impl.ClassImpl">

<property name="hibernateTemplate">

   <ref bean="hibernateTemplate"/>

</property>

</bean>

在Dao层的类就要添加hibernateTemplate对象,来对应配置文件中所注入的依赖:

private HibernateTemplate hibernateTemplate;

public HibernateTemplate getHibernateTemplate() {

return hibernateTemplate;

}

public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {

this.hibernateTemplate = hibernateTemplate;

}

hibernateTemplate对数据的增删查给就跟上面的一样,即:

   更新数据:hibernateTemplate().update(bo);

   查询数据:hibernateTemplate().find(bo);

   添加数据:hibernateTemplate().save(bo) ;

   删除数据:hibernateTemplate().delete(bo);

3、注入jdbcTemplate如果对以前的jdbc的SQL还念念不忘,又对Hibernate的HQL没有好感的话,就可以采用jdbcTemplate来增删查改数据库了。在某些情况下采用jdbcTemplate还比较方便,甚至还能提高查询效率。在这之前也要像注入hibernateTemplate那样,先配置好jdbcTemplate,<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">

   <property name="dataSource">

    <ref bean="dataSource" />

   </property>

</bean>如果jdbcTemplate和hibernateTemplate配置时都指向同一个dataSource,那就可以共用同一个事务了。再对要用到jdbcTemplate的Dao进行注入依赖,即:<bean id="classDao" class="cn.jmu.data.dao.impl.ClassImpl">

   <property name="jdbctemplate">

    <ref bean="jdbcTemplate" />

   </property>

</bean>在Dao层的类就要添加jdbctemplate对象,来对应配置文件中所注入的依赖:protected JdbcTemplate jdbctemplate;public JdbcTemplate getJdbctemplate() {

   return jdbctemplate;

}public void setJdbctemplate(JdbcTemplate jdbctemplate) {

   this.jdbctemplate = jdbctemplate;

}现在就可以通过jdbctemplate存取数据了:查询数据:

/*------------查询单列-------------------*/

String SQL= "select name from table";

    List   list= jdbctemplate.queryForList(SQL);

/*------------查询多列------------------*/

Hashtable hash = new Hashtable();

jdbctemplate.query(SQL,

     new RowCallbackHandler() {

       public void processRow(ResultSet rs) throws SQLException {

            hash.put(rs.getString(1),rs.getString(2));

      }

   });

/*----------查询后填充到vo里面-----------*/

String SQL="select * from table where id=?";

String[] obj = new String[1];

   obj[0] = N;

VO vo= new VO();            //这边暂用VO来表示,VO的本质不是这样的

List list = jdbcTemplate.query(SQL,obj,vo);

VO要实现RowMapper接口中的mapRow方法,把结果集填充到bo里面:class VO implements RowMapper{

public Object mapRow(ResultSet rs, int index) throws SQLException {

    Bo bo = new Bo();     

   bo.setProperty(rs.getString(1));

     bo.setProperty(rs.getString(2));

     bo.setProperty(rs.getString(3));

     return bo;

    }

}/*----------------更新数据------------------*/

String SQL="update table set name=?";

String[] obj=new String[1];

obj[1]="new name";

jdbcTemplate.update(SQL,obj);

/*----------------删除数据------------------*/

String SQL="delete from table where id='"+ID+"'";

jdbcTemplate.execute(SQL);

/*----------------添加数据------------------*/

String SQL="insert into table (property1,property2) values ('"+property1+"','"+property1+"')";

jdbcTemplate.execute(SQL);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值