Spring备忘——DAO支持

4DAO支持

Spring中的DAO(数据访问对象)支持主要的目标是便于以标准的方式使用数据访问技术, 如JDBCHibernate或者JDO。它不仅可以让你在这些技术间相当容易的切换,而且让你在编码的时候不需要考虑捕获各种技术中特定的异常。

4.1 一致的异常层次

Spring提供了一个简便的把某种技术特定的异常如SQLException 转化为它自身的异常层次中的基类异常DataAccessException的方法。这些异常包装了原始的异常,所以你不必担心会丢失任何可能造成错误的异常信息。

除了对JDBC异常的包装外,Spring也可以包装Hibernate的异常,把它们从专有的, checked exceptions转化为一系列抽象的runtime exceptions。 同样的情况也适用于JDO的异常。它可以让你处理大多数持久的异常而不需要讨厌的样板式catches/throws代码块和异常声明,这些异常是不可恢复的,只在一些适当的层出现.你仍然可以在需要的地方捕获并处理这些异常。像我们上面提到的一样,JDBC的异常(包括不同数据库特定的方言)也可以转化至同样的异常层次, 这意味着你可以在一致的编程模型下使用JDBC执行某些操作。

上述的情况适合于Template版本的ORM存取框架(JdbcTemplateHibernateTemplateJtaTemplate)。如果你使用基于拦截器的类(HibernateInterceptor),应用中就必须小心的处理HibernateExceptionsJDOExceptions,最好选择通过SessionFactoryUtils 中的convertHibernateAccessExceptionconvertJdoAccessException方法代理。 这些方法可以把异常转化为与兼容org.springframework.dao异常层次的异常。JDOException属于unchecked exception,它们则被简单的抛出,尽管这在异常处理方面牺牲了通用的DAO抽象。

4.3 一致的DAO支持抽象类

为了便于以一致的方式使用不同的数据访问技术如JDBCJDOHibernateSpring提供了一套抽象的DAO类供你继承。这些抽象类提供一些方法来设置数据源,以及你正在使用的技术中专有的一些配置设定。

Dao支持类:

·        JdbcDaoSupport -JDBC数据访问对象的基类。需要设置数据源,同时为子类提供JdbcTemplate

·        HibernateDaoSupport -Hibernate数据访问对象的基类。需要设置SessionFactory,同时为子类提供HibernateTemplate。可以选择直接通过HibernateTemplate来初始化,这样就可以重用后者的设置,例如SessionFactoryflush的方式,异常解释器等等。

·        JdoDaoSupport -JDO数据访问对象的基类。需要设置PersistenceManagerFactory,同时为子类提供JdoTemplate

4.4使用ORM工具进行数据访问

Spring在资源管理,DAO实现支持以及实物策略等方面提供了与Hibernate, JDOiBATIS SQL映射的集成。 对HibernateSpring使用了很多IoC的方便的特性提供了一流的支持,帮助你处理很多典型的Hibernate整合的问题。所有的这些都遵守Spring通用的事务和DAO异常体系.

使用Spring构建你的ORM应用的好处包括:

·        避免绑定特殊的技术,允许mix-and-match的实现策略。虽然Hibernate非常强大,灵活,开源而且免费,但它还是使用了自己的特定的API。此外有人也许会争辩:iBatis更轻便而且在不需要复杂的O/R映射策略的应用中使用也很优秀。能够选择的话,使用标准或抽象的API来实现主要的应用需求,通常是更好的。尤其,当你可能会因为功能,性能或其他方面的原因而需要切换到另一个实现的时候。举例来说,SpringHibernate事务和异常的抽象,以及能够让你轻松交换mapperDAO对象(实现数据访问功能)的IoC机制,这两个特性可以让你在不牺牲Hibernate性能的情况下,在你的应用程序中隔离Hibernate的相关代码。处理DAO的高层次的service代码不需要知道DAO的具体实现。这个方法可以很容易使用mix-and-match方案互不干扰地实现数据访问层(比如在一些地方用Hibernate,一些地方使用JDBC,其他地方使用iBatis),mix-and-match有利于处理遗留下来的代码以及利用各种技术(JDBC,Hibernate,iBatis)的长处.

·        测试简单.SpringIoC使得很容易替换掉不同的实现,Hibernate SessionFacotory的位置,datasource, 事务管理, 映射对象的实现。这样就很容易隔离测试持久化相关代码的各个部分。

·        通用的资源管理Springapplication context能够处理诸如HibernateSessionFactoryJDBCdatasourceiBatisSQLMaps配置对象以及其他相关资源的定位和配置。这使得这些配置的值很容易被管理和修改。Spring提供了有效,简单和安全的Hibernate Session处理。一般的使用Hibernate的代码则需要使用同一个HibernateSession对象以确保有效和恰当地事务处理。而Spring让我们可以很容易透明地创建和绑定一个session到当前线程;你可以使用以下两种办法之一:声明式的AOP方法拦截器,或通过使用一个外部的template包装类在Java代码层次实现。这样,Spring就解决了在很多Hibernate论坛上出现的使用问题。

·        异常包装Spring能够包装Hibernate异常,把它们从专有的,checked exception变为一组抽象的runtimeexception。这样你就可以仅仅在恰当的层处理大部分的不可恢复的异常,使你避免了很多讨厌的catch/throw以及异常声明。你还是可以在你需要的地方捕捉和处理异常。回想一下JDBC异常(包括与DB相关的方言)被转变为同样的异常体系,这就意味着你可以在一致的编程模型中处理JDBC操作。

·        综合的事务管理 Spring允许你包装你的ORM代码,通过使用声明式的AOP方法拦截器或者在代码级别使用外部的template包装类。不管使用哪一种,事务相关的语义都会为你处理,万一有异常发生也会帮你做适当的事务操作(比如rollback)。就象我们下面要讨论的一样,你能够使用和替换各种transaction managers,却不会使你的Hibernate相关的代码受到影响。更好的是,JDBC相关的代码可以完全和Hibernate代码integrate transactionaly。这对于处理那些没有用HibernateiBatis实现的功能非常有用。

 

4.5 DAO反向控制: 模板和回调的使用

对于可以成为定制的数据访问对象或业务对象的方法来说,基本的模板编程模型看起来像下面所示的代码那样。对于外部对象没有任何实现特定接口的要求,它只需要提供一个HibernateSessionFactory。它可以从任何地方得到,比较适宜的方法是作为从Springapplication context中得到的bean引用: 通过简单的setSessionFactory这个bean属性setter。下面的代码显示了在application context中一个DAO的定义, 它引用了上面定义的SessionFactory,同时展示了一个DAO方法的具体实现。

<beans>
 
    <bean id="myProductDao"  lang="EN-US" style="font-size:9pt">        <property name="sessionFactory">
            <ref bean="mySessionFactory"/>
        </property>
    </bean>
</beans>
public class ProductDaoImpl implements ProductDao {
    private SessionFactory sessionFactory;
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
    public List loadProductsByCategory(final String category) {
        HibernateTemplate hibernateTemplate =
            new HibernateTemplate(this.sessionFactory);
        return (List) hibernateTemplate.execute(
            new HibernateCallback() {
                public Object doInHibernate(Session session) throws HibernateException {
                    List result = session.find(
                        "from test.Product product where product.category=?",
                        category, Hibernate.STRING);
                    // do some further stuff with the result list
                    return result;
                }
            }
        );
    }
}

一个callback的实现能在任何的Hibernate数据访问中有效使用。HibernateTemplate会确保Session正确的打开和关闭,并且会自动参与事务。Template实例是线程安全的,可重用的,因此可以作为外部类的实例变量而被保持。对于简单的一步操作,例如简单的find,load, saveOrUpdate,或者delete调用,HibernateTemplate提供了可选的简单方法可以用来替换这种一行的callback实现。 此外,Spring提供了一个简便的HibernateDaoSupport基类,这个基类提供了setSessionFactory方法来接受一个SessionFactorygetSessionFactory 以及getHibernateTemplate方法是子类使用的。这样对于典型的需求就可以有很简单的DAO实现:

public class ProductDaoImpl extends HibernateDaoSupport implements ProductDao {
 
    public List loadProductsByCategory(String category) {
        return getHibernateTemplate().find(
            "from test.Product product where product.category=?", category,
            Hibernate.STRING);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值