Springアクセスデータベース異常の処理方法
36549 ワード
テキストリンク:http://sarin.javaeye.com/blog/888458
今日はSpringがデータベースにアクセスする異常の処理方法についてお話しします.JDBC APIを使用する場合、javaを放出することを宣言する操作が多いです.sql.SQLException例外は、通常、例外処理ポリシーを設定します.
JDBC APIを使用する場合、javaの放出を宣言する操作が多い.sql.SQLException例外は、通常、例外処理ポリシーを設定します.SpringのJDBCモジュールは私たちに異常処理メカニズムを提供して、この異常システムのベースクラスはDataAccessExceptionで、それはRuntimeExceptionの一種で、それでは強制的に異常を捕まえる必要はありません.Springの異常システムは以下の通りです:
SpringにおけるJDBCモジュールの異常を明確に処理していない.その異常処理メカニズムを理解するには,いくつかのテストを行う.次のテストコードを見てください.
SQL文を修正して、自増プライマリ・キーの特性を使用しないで、ここで重複するプライマリ・キーを設定すると、プログラムを実行すると、フィールド重複の異常が報告されます.この例外をキャプチャします.
エラー・コードとSQLステータスを取得できます(データベース・システムによって異なります):
HSQLデータベースのエラーコードについてはorg.hsqldb.トレースクラスでは、実行結果に負の番号があることに注意して、クラスでは負の番号が定義されていないことを確認します.これにより、104:一意制約検証に失敗したなど、このエラーの具体的な意味がわかります.これが私たちが故意に設定した重複プライマリ・キーの問題です.
SpringのJDBCモジュールはorgに格納されているいくつかのエラーコードを事前に定義しています.springframework.jdbc.supportパッケージのsql-error-codes.xmlファイルでは、HSQLについて説明する内容は次のとおりです.
残りのデータベースのエラーコードの内容もこのファイルから取得できます.次に、例外処理をカスタマイズする方法を見てみましょう.私たちはorgにいることを知っています.springframework.jdbc.supportパッケージの下にsql-error-codesがあります.xmlファイルは、Spring起動時にこのファイルのエラーコードを自動的に読み取り、いくつかのエラーコードを事前に分類し、カスタマイズした例外を使用するために強化することができます.まず、例外クラスを定義し、前の-104エラーをカスタマイズします.HSQLの重複キーの問題です.
その後、sql-error-codesを再作成します.xmlコードをクラスパスのルートディレクトリの下に配置すると、Springはそれを発見し、カスタマイズしたファイルを使用して、構成で以下のように定義します.
HSQLのbeanの名前を変更しないで、useSqlStateForTranslationをfalseに設定すれば、私たちが定義した異常クラスを使用することができます.メイン関数からtry/catchブロックを削除し、プログラムを起動すると、次のように表示されます.
Springは起動情報から私たちがカスタマイズしたsql-error-codesを発見したことがわかります.xmlは、HSQLデータベースの処理部分を置き換え、我々が定義した例外を使用して、プライマリ・キーが繰り返す異常をシミュレートした後、VehicleDuplicateKeyExceptionが投げ出されます.このほか、SQLExceptionTranslatorインタフェースを実装し、JDBCテンプレートに実例を注入して異常制御を実装することもできます.まず、Translatorクラスを作成します.
ここでtranslateメソッドを上書きするには、メソッドには3つのパラメータがあり、taskは現在の操作が行うタスクが何であるかを示し、sqlは実行するsql文であり、exはSQLExceptionを表し、そこから異常情報を取得することができ、その処理コードはエラーコード-104(HSQLデータベース)のエラーのみをキャプチャし、残りの構成情報は必要に応じて自分で追加することができる.Springで再構成するには、次の手順に従います.
DAO実装クラスのコードを調整します.
テストを行うために、他のコードを変更することなく、sql-error-codesを実行し続けることができる.xmlファイルをクラスパスのルートパスから削除すると、次の結果が得られます.
SpringのJDBCモジュールはカスタム例外処理にも非常に柔軟で、自分の好きな方法を選んで実現できます.利用者に役に立つことを願って、交流を歓迎して、次の部分はSpringのORMを紹介します.
今日はSpringがデータベースにアクセスする異常の処理方法についてお話しします.JDBC APIを使用する場合、javaを放出することを宣言する操作が多いです.sql.SQLException例外は、通常、例外処理ポリシーを設定します.
JDBC APIを使用する場合、javaの放出を宣言する操作が多い.sql.SQLException例外は、通常、例外処理ポリシーを設定します.SpringのJDBCモジュールは私たちに異常処理メカニズムを提供して、この異常システムのベースクラスはDataAccessExceptionで、それはRuntimeExceptionの一種で、それでは強制的に異常を捕まえる必要はありません.Springの異常システムは以下の通りです:
SpringにおけるJDBCモジュールの異常を明確に処理していない.その異常処理メカニズムを理解するには,いくつかのテストを行う.次のテストコードを見てください.
public void insert(final Vehicle vehicle) {
String sql = "insert into vehicle (ID,PLATE,CHASSIS,COLOR,WHEEL,SEAT) values (:id,:plate,:chassis,:color,:wheel,:seat)";
SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(vehicle);
getSimpleJdbcTemplate().update(sql, parameterSource);
}
public void insert(final Vehicle vehicle) {
String sql = "insert into vehicle(ID,PLATE,CHASSIS,COLOR,WHEEL,SEAT) values(:id,:plate,:chassis,:color,:wheel,:seat)";
SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(vehicle);
getSimpleJdbcTemplate().update(sql, parameterSource);
}
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:org/ourpioneer/vehicle/spring/applicationContext.xml");
VehicleDAO vehicleDAO = (VehicleDAO) ctx.getBean("vehicleDAO");
Vehicle vehicle = new Vehicle(" B-000000", "1A00000001", "RED", 4, 4);
vehicle.setId(1);
vehicleDAO.insert(vehicle);
}
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:org/ourpioneer/vehicle/spring/applicationContext.xml");
VehicleDAO vehicleDAO = (VehicleDAO) ctx.getBean("vehicleDAO");
Vehicle vehicle = new Vehicle(" B-000000", "1A00000001", "RED", 4, 4);
vehicle.setId(1);
vehicleDAO.insert(vehicle);
}
SQL文を修正して、自増プライマリ・キーの特性を使用しないで、ここで重複するプライマリ・キーを設定すると、プログラムを実行すると、フィールド重複の異常が報告されます.この例外をキャプチャします.
try {
vehicleDAO.insert(vehicle);
} catch (DataAccessException e) {
SQLException sqle = (SQLException) e.getCause();
System.out.println("Error code: " + sqle.getErrorCode());
System.out.println("SQL state: " + sqle.getSQLState());
}
try {
vehicleDAO.insert(vehicle);
} catch (DataAccessException e) {
SQLException sqle = (SQLException) e.getCause();
System.out.println("Error code: " + sqle.getErrorCode());
System.out.println("SQL state: " + sqle.getSQLState());
}
エラー・コードとSQLステータスを取得できます(データベース・システムによって異なります):
HSQLデータベースのエラーコードについてはorg.hsqldb.トレースクラスでは、実行結果に負の番号があることに注意して、クラスでは負の番号が定義されていないことを確認します.これにより、104:一意制約検証に失敗したなど、このエラーの具体的な意味がわかります.これが私たちが故意に設定した重複プライマリ・キーの問題です.
SpringのJDBCモジュールはorgに格納されているいくつかのエラーコードを事前に定義しています.springframework.jdbc.supportパッケージのsql-error-codes.xmlファイルでは、HSQLについて説明する内容は次のとおりです.
<bean id="HSQL" class="org.springframework.jdbc.support.SQLErrorCodes">
<property name="databaseProductName">
<value>HSQL Database Engine</value>
</property>
<property name="badSqlGrammarCodes">
<value>-22,-28</value>
</property>
<property name="duplicateKeyCodes">
<value>-104</value>
</property>
<property name="dataIntegrityViolationCodes">
<value>-9</value>
</property>
<property name="dataAccessResourceFailureCodes">
<value>-80</value>
</property>
</bean>
<bean id="HSQL" class="org.springframework.jdbc.support.SQLErrorCodes">
<property name="databaseProductName">
<value>HSQL Database Engine</value>
</property>
<property name="badSqlGrammarCodes">
<value>-22,-28</value>
</property>
<property name="duplicateKeyCodes">
<value>-104</value>
</property>
<property name="dataIntegrityViolationCodes">
<value>-9</value>
</property>
<property name="dataAccessResourceFailureCodes">
<value>-80</value>
</property>
</bean>
残りのデータベースのエラーコードの内容もこのファイルから取得できます.次に、例外処理をカスタマイズする方法を見てみましょう.私たちはorgにいることを知っています.springframework.jdbc.supportパッケージの下にsql-error-codesがあります.xmlファイルは、Spring起動時にこのファイルのエラーコードを自動的に読み取り、いくつかのエラーコードを事前に分類し、カスタマイズした例外を使用するために強化することができます.まず、例外クラスを定義し、前の-104エラーをカスタマイズします.HSQLの重複キーの問題です.
package org.ourpioneer.vehicle.exception;
import org.springframework.dao.DataIntegrityViolationException;
public class VehicleDuplicateKeyException extends DataIntegrityViolationException {
public VehicleDuplicateKeyException(String msg) {
super(msg);
}
public VehicleDuplicateKeyException(String msg, Throwable cause) {
super(msg, cause);
}
}
package org.ourpioneer.vehicle.exception;
import org.springframework.dao.DataIntegrityViolationException;
public class VehicleDuplicateKeyException extends DataIntegrityViolationException {
public VehicleDuplicateKeyException(String msg) {
super(msg);
}
public VehicleDuplicateKeyException(String msg, Throwable cause) {
super(msg, cause);
}
}
その後、sql-error-codesを再作成します.xmlコードをクラスパスのルートディレクトリの下に配置すると、Springはそれを発見し、カスタマイズしたファイルを使用して、構成で以下のように定義します.
<bean id="HSQL" class="org.springframework.jdbc.support.SQLErrorCodes">
<property name="databaseProductName" value="HSQL Database Engine" />
<property name="useSqlStateForTranslation" value="false" />
<property name="customTranslations">
<list>
<ref local="vehicleDuplicateKeyTranslation" />
</list>
</property>
</bean>
<bean id="vehicleDuplicateKeyTranslation" class="org.springframework.jdbc.support.CustomSQLErrorCodesTranslation">
<property name="errorCodes" value="-104" />
<property name="exceptionClass" value="org.ourpioneer.vehicle.exception.VehicleDuplicateKeyException" />
</bean>
<bean id="HSQL" class="org.springframework.jdbc.support.SQLErrorCodes">
<property name="databaseProductName" value="HSQL Database Engine" />
<property name="useSqlStateForTranslation" value="false" />
<property name="customTranslations">
<list>
<ref local="vehicleDuplicateKeyTranslation" />
</list>
</property>
</bean>
<bean id="vehicleDuplicateKeyTranslation" class="org.springframework.jdbc.support.CustomSQLErrorCodesTranslation">
<property name="errorCodes" value="-104" />
<property name="exceptionClass" value="org.ourpioneer.vehicle.exception.VehicleDuplicateKeyException" />
</bean>
HSQLのbeanの名前を変更しないで、useSqlStateForTranslationをfalseに設定すれば、私たちが定義した異常クラスを使用することができます.メイン関数からtry/catchブロックを削除し、プログラムを起動すると、次のように表示されます.
Springは起動情報から私たちがカスタマイズしたsql-error-codesを発見したことがわかります.xmlは、HSQLデータベースの処理部分を置き換え、我々が定義した例外を使用して、プライマリ・キーが繰り返す異常をシミュレートした後、VehicleDuplicateKeyExceptionが投げ出されます.このほか、SQLExceptionTranslatorインタフェースを実装し、JDBCテンプレートに実例を注入して異常制御を実装することもできます.まず、Translatorクラスを作成します.
package org.ourpioneer.vehicle.exception;
import java.sql.SQLException;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.jdbc.support.SQLExceptionTranslator;
public class VehicleDuplicateKeyTranslator implements SQLExceptionTranslator {
public DataAccessException translate(String task, String sql, SQLException ex) {
if (task == null) {
task = "";
}
if (sql == null) {
}
if (ex.getErrorCode() == -104) {
return new VehicleDuplicateKeyException(buildMessage(task, sql, ex));
} else {
return new UncategorizedSQLException(task, sql, ex);
}
}
private String buildMessage(String task, String sql, SQLException ex) {
return " :" + task + "; SQL [" + sql + "]; " + ex.getMessage();
}
}
package org.ourpioneer.vehicle.exception;
import java.sql.SQLException;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.jdbc.support.SQLExceptionTranslator;
public class VehicleDuplicateKeyTranslator implements SQLExceptionTranslator {
public DataAccessException translate(String task, String sql, SQLException ex) {
if (task == null) {
task = "";
}
if (sql == null) {
}
if (ex.getErrorCode() == -104) {
return new VehicleDuplicateKeyException(buildMessage(task, sql, ex));
} else {
return new UncategorizedSQLException(task, sql, ex);
}
}
private String buildMessage(String task, String sql, SQLException ex) {
return " :" + task + "; SQL [" + sql + "]; " + ex.getMessage();
}
}
ここでtranslateメソッドを上書きするには、メソッドには3つのパラメータがあり、taskは現在の操作が行うタスクが何であるかを示し、sqlは実行するsql文であり、exはSQLExceptionを表し、そこから異常情報を取得することができ、その処理コードはエラーコード-104(HSQLデータベース)のエラーのみをキャプチャし、残りの構成情報は必要に応じて自分で追加することができる.Springで再構成するには、次の手順に従います.
<bean id="vehicleDuplicateKeyTranslator" class="org.ourpioneer.vehicle.exception.VehicleDuplicateKeyTranslator">
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="exceptionTranslator" ref="vehicleDuplicateKeyTranslator" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="vehicleDAO" class="org.ourpioneer.vehicle.dao.VehicleDAOImpl">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
<bean id="vehicleDuplicateKeyTranslator" class="org.ourpioneer.vehicle.exception.VehicleDuplicateKeyTranslator">
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="exceptionTranslator" ref="vehicleDuplicateKeyTranslator" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="vehicleDAO" class="org.ourpioneer.vehicle.dao.VehicleDAOImpl">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
DAO実装クラスのコードを調整します.
public class VehicleDAOImpl extends SimpleJdbcDaoSupport implements VehicleDAO {
… …
public void insert(final Vehicle vehicle) {
String sql = "insert into vehicle(ID,PLATE,CHASSIS,COLOR,WHEEL,SEAT) values(?,?,?,?,?,?)";
getJdbcTemplate().update(sql, vehicle.getId(),vehicle.getPlate(),vehicle.getChassis(),vehicle.getColor(),vehicle.getWheel(),vehicle.getSeat());
}
… …
}
public class VehicleDAOImpl extends SimpleJdbcDaoSupport implements VehicleDAO {
… …
public void insert(final Vehicle vehicle) {
String sql = "insert into vehicle(ID,PLATE,CHASSIS,COLOR,WHEEL,SEAT) values(?,?,?,?,?,?)";
getJdbcTemplate().update(sql, vehicle.getId(),vehicle.getPlate(),vehicle.getChassis(),vehicle.getColor(),vehicle.getWheel(),vehicle.getSeat());
}
… …
}
テストを行うために、他のコードを変更することなく、sql-error-codesを実行し続けることができる.xmlファイルをクラスパスのルートパスから削除すると、次の結果が得られます.
SpringのJDBCモジュールはカスタム例外処理にも非常に柔軟で、自分の好きな方法を選んで実現できます.利用者に役に立つことを願って、交流を歓迎して、次の部分はSpringのORMを紹介します.