DAOのためのSpringのサポート

DAOの、春のコンセプト

ほとんどの場合、データがデータベースに保存されているが、DAO(データアクセスオブジェクト)は、データにアクセスするために使用されるオブジェクトであるが、これが唯一のオプションではありません、あなたはまた、ファイルまたはLDAPにデータを保存することができます。DAO異なるエンドシールドのみデータ記憶媒体、および、異なる特定の実装技術を遮蔽します。

初期の、データベースへのJDBCアクセスが主流の選択肢です。近年では、データの永続化技術はかなりの発展を得て、Hibernateは、MyBatisの、JPAは、JDOの実装技術が紛争に入れ素晴らしさの持続性になります。限りデータアクセスDAO明確に定義されたインターフェース、およびインターフェースDAOの機能を実現する具体的な手法の使用など、スムーズ異なる実装技術との間で切り替えることができます。

図はDAOの典型的な応用例で、インタフェースメソッド、ビジネス層UserDao操作データ、及び特定の持続技術UserDaoインターフェース方法の使用をUserDaoユーザーデータオブジェクトへのアクセスを定義し、サービス層と特定の永続化技術となるようデカップリングを実現しています。

抽象化のDAO層は、いくつかの利点を提供することができる:まず、あなたが簡単にモックオブジェクトを構築することができ、ユニットテストを運ぶこと容易;セクションを使用した場合第二に、より多くのオプションがあるでしょう、あなたはJDKのダイナミックプロキシを使用するかは、使用することができますCGLIB動的プロキシ。

基本的に均一な方法で、つまり、基盤となる永続化技術を統合する統一的な方法で希望を春とトランザクション管理を呼び出し、ビジネス層のコードに特定の実装の侵入を防ぎます。各技術は、異常系の独自の永続性を持っているので、スプリングは、統一された例外の階層を提供するので、異なるシステムのインピーダンスは、特定の技術に依存しないDAOのインターフェースを定義し、実装するには、異常な簡単排除し、同じトランザクション管理に統合しますシステム。

 

第二に、一貫性のある例外システム

一貫性のある例外システムは、異なる永続化技術の統合の鍵となります。スプリングコンバータにより、異常なDAO層セマンティクスの実装技術に依存しないシステムを提供し、スプリングの異常に異なる異常な永続化技術を変換します。

1.Spring DAO例外システム

多くのオーソドックスなAPIやフレームワークでは、チェック例外は、APIを使用する場合でも、コードが定型コードの多くで満たされ、過度の使用されています。多くの場合、やるべき仕事を外でのtry / catchで例外情報を記録し、あまり実質的に加えました。異常によって引き起こされる問題は、回復不能、データ接続が失敗したような、構文エラーと他のSQL文になる傾向があります。加えて、強制的に捕獲チェック例外は、開発者の自由を制限するが、やりがいのあるものは提供されません。したがって、Springの例外階層は、必要に応じて、開発者が関心の異常を捉えることができ、異常なランタイムに基づいて構築されています。

JDKのAPIの多くは困難を使用する理由は、大きな理由は、そのようなので、上のJavaMail、EJB、JDBCおよびなどチェック例外の増殖です。これらのAPIを使用して、ビジネス・コードに気が散る入り例外処理の山はきれいでエレガントなコードを弱体化させます。

DAO例外エレガントなシステムの包括的なパッケージを提供org.springframework.daoスプリングは、これらの異常はDataAccessExceptionを継承し、ひいてはDataAccessException NestedRuntimeException、NestedRuntimeException異常なネストされたカプセル化されたソース・異常を継承しています。したがって、異なる永続技術固有の例外は、Spring DAO異常系に変換されているが、元の例外情報が失われていないが、あれば、ユーザーが喜んでいるように、簡単にgetCause()メソッドによって、生の例外を得ることができます。

春のDAO例外システムとDAO抽象的な概念の異常なレベルからディレクトリツリーを定義し、特定の実装技術、とは関係ありません。すべての永続化フレームワークでは、そのような豊かなセマンティックフレームワーク異常システムを発見していません。春は間違いなく、特定の異常に集中する開発者を可能にセマンティクスに非常に容易になり、このデザインの独創性です。JDBCのSQLExceptionでは、ユーザは()、getErrorCode()またはgetSQLStateを異常エラーコードを受け取り、これらのコードは、エラーの原因に応じて決定されなければなりません。これは、プログラミングコードの難しさをもたらしただけでなく、getErrorCode()メソッドは、データベースに関連しているため、ポータブルなコードが困難になるにするだけでなく、あまりにも低レベルのAPIです。

分類に春のアプローチは、ほとんどのアプリケーションのために、分裂の異常な種類の適切な粒度で、この例外カテゴリーを異常なカテゴリーを確立しました。一の態様では、開発者は鍼麻酔として微細として根底にある技術的な詳細から逸脱するように、一方、関心のプロセスは、この異常な意味的に豊富なシステムからの例外を選択することができます。

次の図は、各異常な例外クラスの下のサブカテゴリの数が多いことがあり、スプリングDAO例外クラスに位置し、これらの異常なシステムの最初のレベルを示しています。

春のDAO例外階層クラスがちょうどDataAccessExceptionの例外クラスの下にサブクラスに名前を付けるために、非常に豊富です。あなたは簡単に例外クラスの名前が表す意味的な異常を把握することができます。次のパスの下でこれらの異常の表の簡単な説明。

それは、図に示すように、2つのサブクラスの一つである以下、10の以上InvalidDataAccessResourceUsageExceptionサブクラスを有するように、さらに問題ドメインエラーを洗練するために、例外クラスの春は、細分化のサブクラスです。

異常InvalidDataAccessResourceUsageExceptionのために、永続化技術は、異なる対応するサブ例外クラスを持っています。BadSqlGrammarExceptionは、対応するHibemate HibernateQueryException実装技術クエリ構文の例外ながら、異常な達成するためにSQLステートメントの構文エラーJDBC技術に対応したよう。

Spring 的这个异常体系具有高度的可扩展性,当 Spring 需要对一种新的持久化技术提供支持时,只要为其定义一个对应的子异常就可以了,这种更改完全满足设计模式中的“开一闭原则”。

虽然 Spring 定义了如此丰富的异常类,但作为开发人员,仅需对感兴趣的异常进行处理即可。假设某个项目要求在发生乐观锁异常时,尝试再次获取乐观锁,而不是直接返回错误;那么,只需在代码中显式捕捉 ConcunencyFailureException 异常,然后在 catch 代码块中编写满足需求的逻辑即可。其他众多的异常则可以简单地交由框架自动处理,如发生运行期异常时自动回滚事务。

2.JDBC的异常转换器

传统的 JDBC API 在发生几乎所有的数据操作问题时都会抛出相同的 SQLException,它将异常的细节性信息封装在异常属性中。所以,如果希望了解异常的具体原因,则必须分析异常对象的信息。

SQLException 拥有两个代表异常具体原因的属性:错误码和 SQL 状态码。前者是数据库相关的,可通过 getErrorCode() 方法返回,其值的类型是 int;而后者是一个标准的错误代码,可通过 getSQLState() 方法返回,是一个 String 类型的值,由 5 个字符组成。

Spring 根据错误码和 SQL 状态码信息将 SQLException 译成 Spring DAO 的异常体系所对应的异常。在 org.springframework.jdbc.support 包中定义了 SQLExceptionTranslator 接口,该接口的两个实现类 SQLErrorCodeSQLExceptionTranslator 和 SQLStateSQLExceptionTranslator 分别负责处理 SQLException 中错误码和 SQL 状态码的翻译工作。将 SQLException 翻译成 SpringDAO 异常体系的工作是比较困难的,但 Spring 框架替我们完成了这项艰巨的工作并保证了转换的正确性,我们有充分的理由依赖这个转换的正确性。

3.其他持久化技术的异常转换器

由于各种框架级的持久化技术都拥有一个语义明确的异常体系,所以将这些异常转换为 Spring DAO 的体系相对轻松一些。下面将学习不同持久化技术的异常转换器。

Spring4.0 移除了对 Hibernate 低版本的支持,只支持 Hibernate3.6 之后的版本。另外,Spring4.0 移除了对 TopLink 的支持。在 org.springframework.orm 包中,分别为 Spring 所支持的 ORM 持久化技术定义了一个子包,在这些子包中提供相应 ORM 技术的整合类。Spring 为 各种 ORM 持久化技术所提供的异常转换器在下表说明。

这些工具类除了具有异常转换的功能,在进行事务管理时,还提供了从事务上下文中返回相同会话的功能。

Spring 也支持 MyBatis ORM 持久化技术,由于 MyBatis 抛出的异常是和 JDBC 相同的 SQLException 异常,所以直接采用和 JDBC 相同的异常转换器。

 

三、统一数据访问模板

到一个餐馆用餐,大抵会经历这样一个流程:进入餐馆-->迎宾小姐问候并引到适合的位置-->拿起菜单点菜-->用餐-->埋单-->离开餐馆。之所以我们喜欢时不时到餐馆用餐,就是因为我们只要点菜-->用餐-->埋单就可以了,幕后的烹饪制作、刷锅洗盘等工作完全不用关心,一切已经由餐馆服务人员按照服务流程按部就班、有条不紊地执行了。衡量一个餐馆服务质量好坏的一个重要标准是我们无须关心他们所负责的流程:不用催问菜为什么还没有上好(不但快而且服务态度佳),不用关心盘子为什么不干净(不但干净而且已经进行了消毒)。

从某种角度看,与其说餐馆为我们提供了服务,还不如说我们参与到餐馆的流程中:不管什么顾客点的菜都由相同的厨师烹制,不管什么顾客都按单付钱。在幕后,餐馆拥有一个服务模板,模板中定义的流程可以用于应付所有的顾客,只要为顾客提供几个专有需求(点的菜可不一样,座位可以自由选择),其他一切都按模板化的方式处理。

在直接使用具体的持久化技术时,大多需要处理整个流程,并没有享受餐馆用餐式的便捷。Spring 为支持的持久化技术分别提供了模板访问的方式,降低了使用各种持久化技术的难度,因此可以大幅度地提高开发效率。

1.使用模板和回调机制

下面是一段使用 JDBC 进行数据访问操作的简单代码,我们已经尽可能地简化了整个过程的处理,但以下步骤都是不可或缺的,如下面代码所示。

public void saveCustomer(Customer customer)throws Exception{
    Connection con = null;
    PreparedStatement stmt = null;
    try{
        //①获取资源
        con = getConnection();
        
        //②启动事务
        con.setAutoCommit(false);
    
        //③具体的数据访问操作和处理
        stmt = con.prepareStatment("insert into CUSTMOERS(ID,NAME) values(?,?)");
        stmt.setLong(1,customerId);
        stmt.setString(2,customer.getName());
        stmt.execute();
        ...
        stmt.execute();
        
        //④提交事务
        con.commit();
    
    }catch(Exception e){
        try{
            //⑤回滚事务
            con.rollback();
        }catch(SQLException sqlex){
            sqlex.printStackTrace(System.out);
        }
        throw e;
    }finally{
        //⑥释放资源
        try{
            stmt.close();
            con.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

如上述代码所示,JDBC 数据访问操作按以下流程进行:
(1)准备资源。
(2)启动事务。
(3)在事务中执行具体的数据访问操作。
(4)提交/回滚事务。
(5)关闭资源,处理异常。

按照传统的方式,在编写任何带事务的数据访问程序时,都需要重复编写上面的代码,而其中只有粗体部分所示的代码是业务相关的,其他代码都是在例行公事,因而导致大量八股文式的代码充斥着整个程序。

Spring 将这个相同的数据访问流程固化到模板类中,并将数据访问中固定和变化的部分分开,同时保证模板类是线程安全的,以便多个数据访问线程共享同一个模板实例。固定的部分在模板类中已经准备好,而变化的部分通过回调接口开放出来,用于定义具体数据访问和结果返回的操作。下图描述了模板类拆分固定和变化部分的逻辑。

这样,只要编写好回调接口,并调用模板类进行数据访问,就可以得到预想的结果:数据访问成功执行,前置和后置的样板化工作也按顺序正确执行,在提高开发效率的同时保证了资源使用的正确性,彻底消除了因忘记进行资源释放而引起的资源泄露问题。

2.Spring 为不同持久化技术所提供的模板类

Spring 为各种支持的持久化技术都提供了简化操作的模板和回调,在回调中编写具体的数据操作逻辑,使用模板执行数据操作,在 Spring 中,这是典型的数据操作模式。下面来了解一下 Spring 为不同的持久化技术所提供的模板类,如下表所示。

如果直接使用模板类,则一般需要在 DAO 中定义一个模板对象并提供数据资源。

Spring 为每种持久化技术都提供了支持类,支持类中已经完成了这样的功能。这样,只需扩展这些支持类,就可以直接编写实际的数据访问逻辑,因此更加方便。

不同持久化技术的支持类如下表所示。

这些支持类都继承于 dao.support.DaoSupport 类,DaoSupport 类实现了 ImtializingBean接口,在 afterPropertiesSet() 接口方法中检查模板对象和数据源是否被正确设置,否则将抛出异常。

所有的支持类都是 abstract 的,其目的是希望被继承使用,而非直接使用。

おすすめ

転載: www.cnblogs.com/jwen1994/p/11235210.html