SpringJDBC异常抽象
创始人
2025-05-31 01:29:44

前言

spring会将所有的常见数据库的操作异常抽象转换成他自己的异常,这些异常的基类是DataAccessException。DataAccessException是RuntimeException的子类(运行时异常),是一个无须检测的异常,不要求代码去处理这类异常

SQLErrorCodeSQLExceptionTranslator

开发中会使用到H2,mysql、oracle等数据库,每个厂商定义了不同的错误码;spring通过SQLErrorCodeSQLExceptionTranslator将收集起来的不同数据库错误码进行解析

spring错误码路径:org/springframework/jdbc/support/sql-error-codes.xml

Spring异常是怎么定义的?

springErrorCode:


DB2*-007,-029,-097,-104,-109,-115,-128,-199,-204,-206,-301,-408,-441,-491-803-407,-530,-531,-532,-543,-544,-545,-603,-667-904,-971-1035,-1218,-30080,-30081-911,-913Apache Derbytrue42802,42821,42X01,42X02,42X03,42X04,42X05,42X06,42X07,42X082350522001,22005,23502,23503,23513,X0Y3204501,08004,42Y0740XL14000142000,42001,42101,42102,42111,42112,42121,42122,4213223001,2350522001,22003,22012,22018,22025,23000,23002,23003,23502,23503,23506,23507,2351390046,90100,90117,90121,9012650200SAP HANASAP DB257,259,260,261,262,263,264,267,268,269,270,271,272,273,275,276,277,278,278,279,280,281,282,283,284,285,286,288,289,290,294,295,296,297,299,308,309,313,315,316,318,319,320,321,322,323,324,328,329,330,333,335,336,337,338,340,343,350,351,352,362,36810,258301461,462-813,-709,-708,1024,1025,1026,1027,1029,1030,1031-11210,582,587,588,594131138,143133HSQL Database Engine-22,-28-104-9-80Informix Dynamic Server-201,-217,-696-239,-268,-6017-692,-11030Microsoft SQL Server156,170,207,208,2092292601,2627544,8114,81154060122212051054,1064,11461062630,839,840,893,1169,1215,1216,1217,1364,1451,1452,1557112051213900,903,904,917,936,942,17006,65501700311400,1722,2291,229217002,1744754,30006817760true03000,42000,42601,42602,42622,42804,42P012350523000,23502,23503,2351453000,53100,53200,5330055P034000140P01Sybase SQL ServerAdaptive Server EnterpriseASE  SQL Serversql server  101,102,103,104,105,106,107,108,109,110,111,112,113,116,120,121,123,207,208,213,257,5122601,2615,2626233,511,515,530,546,547,2615,2714921,1105122051205

可以从xml看到为不同的数据库都定义了一个bean,里面的错误码对应SQLErrorCodes类中定义的异常

SQLErrorCodes里定义了一些databaseProductNames(数据库名称)、badSqlGrammarCodes(语法错误)、duplicateKeyCodes(重复组件)、dataIntegrityViolationCodes(唯一性约束)cannotAcquireLockCodes(无法获取锁)等异常

怎样自定义jdbc异常

比如自定义一个重复组件异常:

第一步、写一个异常类继承DuplicateKeyException
package com.springwork.high.common;import org.springframework.dao.DuplicateKeyException;/*** @author 打工仔* @version 1.0.0* @date 2023/3/19 20:07*/
public class MyCustomDuplicatedKeyException extends DuplicateKeyException {public MyCustomDuplicatedKeyException(String msg) {super(msg);}public MyCustomDuplicatedKeyException(String msg, Throwable cause) {super(msg, cause);}
}
第二步、定制自己的sql-error-codes.xml

自己定义文件路径:Classpath下的 sql-error-codes.xml (会覆盖官方定义的配置)

自定义的错误码转换类CustomSQLErrorCodesTranslation


MySQLMariaDB1054,1064,11461062630,839,840,893,1169,1215,1216,1217,1364,1451,1452,155711205,35721213
第三步、测试
@SpringBootTest
@RunWith(SpringRunner.class)
public class MyCustomDuplicatedKeyExceptionTests {@Resourceprivate JdbcTemplate jdbcTemplate;@Test(expected = MyCustomDuplicatedKeyException.class)public void testThrowingCustomException() {jdbcTemplate.execute("INSERT INTO `user_info` (`id`, `name`, `age`) VALUES (222222, '张三', 18)");jdbcTemplate.execute("INSERT INTO `user_info` (`id`, `name`, `age`) VALUES (222222, '李四', 18)");}
}

这里有一个小坑提醒一下

解决方法将@Autowired换成@Resource。两个注解的区别是一个是@Autowired是Spring,@Resource是J2EE的,使用@Resource能减少Spring耦合度

@AutoWried按by type自动注入,而@Resource默认按byName自动注入。

@Resource的查询注入顺序是,去Bean中查找Name,如果查不到就去查Class,其次再从属性去查找,如果我们定义的类中有相同的Name可能会报错,因为查询到了多个。

当然还有其他解决方法:http://t.csdn.cn/bhazS

测试结果

抛出期望的MyCustomDuplicatedKeyException异常

以上就是自定义jdbc异常码

相关内容

热门资讯

当事人有争议!成都路桥近530... 微成都报道 11月21日晚间,成都路桥(002628.SZ)发布公告称,原本定于本月24日至25日期...
薛鹤翔:财政加码护航经济回升 ... 薛鹤翔、陈梦赟(薛鹤翔系申银万国期货研究所所长、中国首席经济学家论坛成员)摘要9月就业数据表现分化。...
沈建光:2025年中央经济工作... 原创 沈建光 FT中文网 2025年11月19日考虑到去年四季度高基数和政策效应减弱,四季度经济面临...
王老吉WALOVI国际罐马来西... 11月17日,在马来西亚吉隆坡举行的2025年《财富》创新论坛上,王老吉WALOVI国际罐马来西亚上...
尚德2025年前三季度净利润逾... 业务转型以来,成人在线教育企业尚德机构(NYSE: STG)用持续的盈利证明,选择老年教育赛道是个正...