目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

X

Spring JDBC 异常抽象

统一异常DataAccessException

 Spring会将常见的数据库操(mysql、oracle、db2…)作异常转换为自己的异常DataAccessException,因此无论使用何种数据访问方式,都能使用一样的异常。

定制错误码

sql-error-codes.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>

    <bean id="H2" class="org.springframework.jdbc.support.SQLErrorCodes">
        <!-- 复制spring官方sql-error-codes.xml 中 描述 H2 相关的错误码定义 -->
        <property name="badSqlGrammarCodes">
            <value>42000,42001,42101,42102,42111,42112,42121,42122,42132</value>
        </property>
        <property name="duplicateKeyCodes">
            <value>23001,23505</value>
        </property>
        <property name="dataIntegrityViolationCodes">
            <value>22001,22003,22012,22018,22025,23000,23002,23003,23502,23503,23506,23507,23513</value>
        </property>
        <property name="dataAccessResourceFailureCodes">
            <value>90046,90100,90117,90121,90126</value>
        </property>
        <property name="cannotAcquireLockCodes">
            <value>50200</value>
        </property>

        <!-- 自定义错误码解析逻辑 -->
        <property name="customTranslations">
            <bean class="org.springframework.jdbc.support.CustomSQLErrorCodesTranslation">
                <property name="errorCodes" value="23001,23505" />
                <!-- 当遇到"23001,23505" 这样的错误码时候,会抛出CustomDuplicatedKeyException异常-->
                <property name="exceptionClass"
                          value="geektime.spring.data.errorcodedemo.CustomDuplicatedKeyException" />
            </bean>
        </property>
    </bean>

</beans>

自定义异常 (违反唯一性约束的异常)
 CustomDuplicatedKeyException 必须是DuplicateKeyException的子类,否则Spring会报错。错误类型方向必须一致,异常的细节可以自定义。

package geektime.spring.data.errorcodedemo;

import org.springframework.dao.DuplicateKeyException;

public class CustomDuplicatedKeyException extends DuplicateKeyException {
    public CustomDuplicatedKeyException(String msg) {
        super(msg);
    }

    public CustomDuplicatedKeyException(String msg, Throwable cause) {
        super(msg, cause);
    }
}

测试类

package geektime.spring.data.errorcodedemo;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ErrorCodeDemoApplicationTests {
	@Autowired
	private JdbcTemplate jdbcTemplate;

	//预期异常CustomDuplicatedKeyException.class
	@Test(expected = CustomDuplicatedKeyException.class)
	public void testThrowingCustomException() {
		//插入两条数据,主键相同,模拟 DuplicatedKeyException 异常
		jdbcTemplate.execute("INSERT INTO FOO (ID, BAR) VALUES (1, 'a')");
		jdbcTemplate.execute("INSERT INTO FOO (ID, BAR) VALUES (1, 'b')");
	}
}

测试结果

Tests passed

作者:Soulboy