Spring JDBC 异常抽象
统一异常 DataAccessException
Spring 会将常见的数据库操(mysql、Oracle、db2…)作异常转换为自己的异常 DataAccessException,因此无论使用何种数据访问方式,都能使用一样的异常。
定制错误码
sql-error-codes.xml
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
3
4<beans>
5
6 <bean id="H2" class="org.springframework.jdbc.support.SQLErrorCodes">
7 <!-- 复制spring官方sql-error-codes.xml 中 描述 H2 相关的错误码定义 -->
8 <property name="badSqlGrammarCodes">
9 <value>42000,42001,42101,42102,42111,42112,42121,42122,42132</value>
10 </property>
11 <property name="duplicateKeyCodes">
12 <value>23001,23505</value>
13 </property>
14 <property name="dataIntegrityViolationCodes">
15 <value>22001,22003,22012,22018,22025,23000,23002,23003,23502,23503,23506,23507,23513</value>
16 </property>
17 <property name="dataAccessResourceFailureCodes">
18 <value>90046,90100,90117,90121,90126</value>
19 </property>
20 <property name="cannotAcquireLockCodes">
21 <value>50200</value>
22 </property>
23
24 <!-- 自定义错误码解析逻辑 -->
25 <property name="customTranslations">
26 <bean class="org.springframework.jdbc.support.CustomSQLErrorCodesTranslation">
27 <property name="errorCodes" value="23001,23505" />
28 <!-- 当遇到"23001,23505" 这样的错误码时候,会抛出CustomDuplicatedKeyException异常-->
29 <property name="exceptionClass"
30 value="geektime.spring.data.errorcodedemo.CustomDuplicatedKeyException" />
31 </bean>
32 </property>
33 </bean>
34
35</beans>
自定义异常 (违反唯一性约束的异常)
CustomDuplicatedKeyException 必须是 DuplicateKeyException 的子类,否则 Spring 会报错。错误类型方向必须一致,异常的细节可以自定义。
1package geektime.spring.data.errorcodedemo;
2
3import org.springframework.dao.DuplicateKeyException;
4
5public class CustomDuplicatedKeyException extends DuplicateKeyException {
6 public CustomDuplicatedKeyException(String msg) {
7 super(msg);
8 }
9
10 public CustomDuplicatedKeyException(String msg, Throwable cause) {
11 super(msg, cause);
12 }
13}
测试类
1package geektime.spring.data.errorcodedemo;
2
3import org.junit.Test;
4import org.junit.runner.RunWith;
5import org.springframework.beans.factory.annotation.Autowired;
6import org.springframework.boot.test.context.SpringBootTest;
7import org.springframework.jdbc.core.JdbcTemplate;
8import org.springframework.test.context.junit4.SpringRunner;
9
10@RunWith(SpringRunner.class)
11@SpringBootTest
12public class ErrorCodeDemoApplicationTests {
13 @Autowired
14 private JdbcTemplate jdbcTemplate;
15
16 //预期异常CustomDuplicatedKeyException.class
17 @Test(expected = CustomDuplicatedKeyException.class)
18 public void testThrowingCustomException() {
19 //插入两条数据,主键相同,模拟 DuplicatedKeyException 异常
20 jdbcTemplate.execute("INSERT INTO FOO (ID, BAR) VALUES (1, 'a')");
21 jdbcTemplate.execute("INSERT INTO FOO (ID, BAR) VALUES (1, 'b')");
22 }
23}
测试结果
1Tests passed