当前位置: 首页 > news >正文

SpringJDBC异常抽象

前言

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

SQLErrorCodeSQLExceptionTranslator

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

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

Spring异常是怎么定义的?

springErrorCode:
<?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"><!--- Default SQL error codes for well-known databases.- Can be overridden by definitions in a "sql-error-codes.xml" file- in the root of the class path.-- If the Database Product Name contains characters that are invalid- to use in the id attribute (like a space) then we need to add a property- named "databaseProductName"/"databaseProductNames" that holds this value.- If this property is present, then it will be used instead of the id for- looking up the error codes based on the current database.-->
<beans><bean id="DB2" name="Db2" class="org.springframework.jdbc.support.SQLErrorCodes"><property name="databaseProductName"><value>DB2*</value></property><property name="badSqlGrammarCodes"><value>-007,-029,-097,-104,-109,-115,-128,-199,-204,-206,-301,-408,-441,-491</value></property><property name="duplicateKeyCodes"><value>-803</value></property><property name="dataIntegrityViolationCodes"><value>-407,-530,-531,-532,-543,-544,-545,-603,-667</value></property><property name="dataAccessResourceFailureCodes"><value>-904,-971</value></property><property name="transientDataAccessResourceCodes"><value>-1035,-1218,-30080,-30081</value></property><property name="deadlockLoserCodes"><value>-911,-913</value></property></bean><bean id="Derby" class="org.springframework.jdbc.support.SQLErrorCodes"><property name="databaseProductName"><value>Apache Derby</value></property><property name="useSqlStateForTranslation"><value>true</value></property><property name="badSqlGrammarCodes"><value>42802,42821,42X01,42X02,42X03,42X04,42X05,42X06,42X07,42X08</value></property><property name="duplicateKeyCodes"><value>23505</value></property><property name="dataIntegrityViolationCodes"><value>22001,22005,23502,23503,23513,X0Y32</value></property><property name="dataAccessResourceFailureCodes"><value>04501,08004,42Y07</value></property><property name="cannotAcquireLockCodes"><value>40XL1</value></property><property name="deadlockLoserCodes"><value>40001</value></property></bean><bean id="H2" class="org.springframework.jdbc.support.SQLErrorCodes"><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></bean><!-- http://help.sap.com/saphelp_hanaplatform/helpdata/en/20/a78d3275191014b41bae7c4a46d835/content.htm --><bean id="HDB" name="Hana" class="org.springframework.jdbc.support.SQLErrorCodes"><property name="databaseProductNames"><list><value>SAP HANA</value><value>SAP DB</value></list></property><property name="badSqlGrammarCodes"><value>257,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,368</value></property><property name="permissionDeniedCodes"><value>10,258</value></property><property name="duplicateKeyCodes"><value>301</value></property><property name="dataIntegrityViolationCodes"><value>461,462</value></property><property name="dataAccessResourceFailureCodes"><value>-813,-709,-708,1024,1025,1026,1027,1029,1030,1031</value></property><property name="invalidResultSetAccessCodes"><value>-11210,582,587,588,594</value></property><property name="cannotAcquireLockCodes"><value>131</value></property><property name="cannotSerializeTransactionCodes"><value>138,143</value></property><property name="deadlockLoserCodes"><value>133</value></property></bean><bean id="HSQL" name="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="Informix" class="org.springframework.jdbc.support.SQLErrorCodes"><property name="databaseProductName"><value>Informix Dynamic Server</value></property><property name="badSqlGrammarCodes"><value>-201,-217,-696</value></property><property name="duplicateKeyCodes"><value>-239,-268,-6017</value></property><property name="dataIntegrityViolationCodes"><value>-692,-11030</value></property></bean><bean id="MS-SQL" name="SqlServer" class="org.springframework.jdbc.support.SQLErrorCodes"><property name="databaseProductName"><value>Microsoft SQL Server</value></property><property name="badSqlGrammarCodes"><value>156,170,207,208,209</value></property><property name="permissionDeniedCodes"><value>229</value></property><property name="duplicateKeyCodes"><value>2601,2627</value></property><property name="dataIntegrityViolationCodes"><value>544,8114,8115</value></property><property name="dataAccessResourceFailureCodes"><value>4060</value></property><property name="cannotAcquireLockCodes"><value>1222</value></property><property name="deadlockLoserCodes"><value>1205</value></property></bean><bean id="MySQL" class="org.springframework.jdbc.support.SQLErrorCodes"><property name="badSqlGrammarCodes"><value>1054,1064,1146</value></property><property name="duplicateKeyCodes"><value>1062</value></property><property name="dataIntegrityViolationCodes"><value>630,839,840,893,1169,1215,1216,1217,1364,1451,1452,1557</value></property><property name="dataAccessResourceFailureCodes"><value>1</value></property><property name="cannotAcquireLockCodes"><value>1205</value></property><property name="deadlockLoserCodes"><value>1213</value></property></bean><bean id="Oracle" class="org.springframework.jdbc.support.SQLErrorCodes"><property name="badSqlGrammarCodes"><value>900,903,904,917,936,942,17006,6550</value></property><property name="invalidResultSetAccessCodes"><value>17003</value></property><property name="duplicateKeyCodes"><value>1</value></property><property name="dataIntegrityViolationCodes"><value>1400,1722,2291,2292</value></property><property name="dataAccessResourceFailureCodes"><value>17002,17447</value></property><property name="cannotAcquireLockCodes"><value>54,30006</value></property><property name="cannotSerializeTransactionCodes"><value>8177</value></property><property name="deadlockLoserCodes"><value>60</value></property></bean><bean id="PostgreSQL" name="Postgres" class="org.springframework.jdbc.support.SQLErrorCodes"><property name="useSqlStateForTranslation"><value>true</value></property><property name="badSqlGrammarCodes"><value>03000,42000,42601,42602,42622,42804,42P01</value></property><property name="duplicateKeyCodes"><value>23505</value></property><property name="dataIntegrityViolationCodes"><value>23000,23502,23503,23514</value></property><property name="dataAccessResourceFailureCodes"><value>53000,53100,53200,53300</value></property><property name="cannotAcquireLockCodes"><value>55P03</value></property><property name="cannotSerializeTransactionCodes"><value>40001</value></property><property name="deadlockLoserCodes"><value>40P01</value></property></bean><bean id="Sybase" class="org.springframework.jdbc.support.SQLErrorCodes"><property name="databaseProductNames"><list><value>Sybase SQL Server</value><value>Adaptive Server Enterprise</value><value>ASE</value>  <!-- name as returned by jTDS driver --><value>SQL Server</value><value>sql server</value>  <!-- name as returned by jTDS driver --></list></property><property name="badSqlGrammarCodes"><value>101,102,103,104,105,106,107,108,109,110,111,112,113,116,120,121,123,207,208,213,257,512</value></property><property name="duplicateKeyCodes"><value>2601,2615,2626</value></property><property name="dataIntegrityViolationCodes"><value>233,511,515,530,546,547,2615,2714</value></property><property name="transientDataAccessResourceCodes"><value>921,1105</value></property><property name="cannotAcquireLockCodes"><value>12205</value></property><property name="deadlockLoserCodes"><value>1205</value></property></bean></beans>

可以从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

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="MySQL" class="org.springframework.jdbc.support.SQLErrorCodes"><property name="databaseProductNames"><list><value>MySQL</value><value>MariaDB</value></list></property><property name="badSqlGrammarCodes"><value>1054,1064,1146</value></property><property name="duplicateKeyCodes"><value>1062</value></property><property name="dataIntegrityViolationCodes"><value>630,839,840,893,1169,1215,1216,1217,1364,1451,1452,1557</value></property><property name="dataAccessResourceFailureCodes"><value>1</value></property><property name="cannotAcquireLockCodes"><value>1205,3572</value></property><property name="deadlockLoserCodes"><value>1213</value></property><!--自定义异常配置--><property name="customTranslations"><bean class="org.springframework.jdbc.support.CustomSQLErrorCodesTranslation"><property name="errorCodes" value="1062" /><property name="exceptionClass"value="com.springwork.high.common.MyCustomDuplicatedKeyException" /></bean></property></bean>
</beans>
第三步、测试
@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异常码

相关文章:

SpringJDBC异常抽象

前言spring会将所有的常见数据库的操作异常抽象转换成他自己的异常&#xff0c;这些异常的基类是DataAccessException。DataAccessException是RuntimeException的子类&#xff08;运行时异常&#xff09;,是一个无须检测的异常,不要求代码去处理这类异常SQLErrorCodeSQLExcepti…...

我在字节的这两年

前言 作为脉脉和前端技术社区的活跃分子&#xff0c;我比较幸运的有了诸多面试机会并最终一路升级打怪如愿来到了这里。正式入职时间为2021年1月4日&#xff0c;也就是元旦后的第一个工作日。对于这一天&#xff0c;我印象深刻。踩着2020年的尾巴接到offer,属实是过了一个快乐…...

Button(按钮)与ImageButton(图像按钮)

今天给大家介绍的Android基本控件中的两个按钮控件,Button普通按钮和ImageButton图像按钮; 其实ImageButton和Button的用法基本类似,至于与图片相关的则和后面ImageView相同,所以本节只对Button进行讲解,另外Button是TextView的子类,所以TextView上很多属性也可以应用到B…...

Chrome插件开发-右键菜单开启页面编辑

开发一个执行js脚本改变页面DOM的Chrome插件&#xff0c;manifest_version版本为3。 Chrome插件基本知识 Chrome插件通常由以下几部分组成&#xff1a; manifest.json 该文件为必须项&#xff0c;其它文件都是可选的。该文件相当于插件的meta信息&#xff0c;包含manifest版…...

指针进阶(上)

内容小复习&#x1f431;&#xff1a; 字符指针:存放字符的数组 char arr1[10]; 整型数组:存放整型的数组 int arr2[5]; 指针数组:存放的是指针的数组 存放字符指针的数组(字符指针数组) char* arr3[5]; 存放整型指针的数组(整型指针数组) int* arr[6]; 下面进入学习了哦~&…...

Python每日一练(20230318)

目录 1. 排序链表 ★★ 2. 最长连续序列 ★★ 3. 扰乱字符串 ★★★ &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 排序链表 给你链表的头结点 head &#xff0c;请将其按 升序 …...

多层多输入的CNN-LSTM时间序列回归预测(卷积神经网络-长短期记忆网络)——附代码

目录 摘要&#xff1a; 卷积神经网络(CNN)的介绍&#xff1a; 长短期记忆网络&#xff08;LSTM&#xff09;的介绍&#xff1a; CNN-LSTM&#xff1a; Matlab代码运行结果&#xff1a; 本文Matlab代码数据分享&#xff1a; 摘要&#xff1a; 本文使用CNN-LSTM混合神经网…...

mybatis中获取参数的两种方式:${}和#{}

目录 1.#{} 2.${} 3.总结 1.#{} 本质是占位符赋值 示例及执行结果&#xff1a; 结论&#xff1a;通过执行结果可以看到&#xff0c;首先对sql进行了预编译处理&#xff0c;然后再传入参数&#xff0c;有效的避免了sql注入的问题&#xff0c;并且传参方式也比较简单&#xf…...

复制带随机指针的复杂链表

目录一、题目题目链接二、题目分析三、解题思路四、解题步骤4.1 复制结点并链接到对应原节点的后面4.2 处理复制的结点的随机指针random4.3 分离复制的链表结点和原链表结点并重新链接成为链表五、参考代码六、总结一、题目题目链接 ​​​​ ​ 题目链接&#xff1a;https://…...

【基于协同过滤算法的推荐系统项目实战-2】了解协同过滤推荐系统

本文目录1、推荐系统的关键元素1.1 数据1.2 算法1.3 业务领域1.4 展示信息2、推荐算法的主要分类2.1 基于关联规则的推荐算法基于Apriori的算法基于FP-Growth的算法2.2 基于内容的推荐算法2.3 基于协同过滤的推荐算法3、推荐系统常见的问题1、冷启动2、数据稀疏3、不断变化的用…...

线程安全(重点)

文章目录一.线程安全的概念1.1 线程安全的概念1.2 线程不安全的原因1.3 解决线程不安全二.synchronized-monitor lock(监视器锁)2.1 synchronized的特性(1)互斥(2)刷新内存(3)可重入2.2 synchronied使用方法1.直接修饰普通方法:2.修饰静态方法:3.修饰代码块:三.死锁3.1死锁的情…...

软件测试面试找工作你必须知道的面试技巧(帮助超过100人成功通过面试)

目录 问题一&#xff1a;“请你自我介绍一下” 问题二&#xff1a;“谈谈你的家庭情况” 问题三&#xff1a;“你有什么业余爱好?” 问题四&#xff1a;“你最崇拜谁?” 问题五&#xff1a;“你的座右铭是什么?” 问题六&#xff1a;“谈谈你的缺点” 问题七&#xff…...

Python快速入门:类、文件操作、正则表达式

类、文件操作、正则表达式1. 类2. 文件操作3. 正则表达式1. 类 类是用来描述具有相同的属性和方法的集合&#xff0c;定义了该集合中每个对象共有的属性和方法&#xff0c;对象是类的实例&#xff0c;可以调用类的方法。 定义类时&#xff0c;如有父类&#xff0c;则写在类名…...

java-day01

程序就是有序指令的集合 cmd执行java程序&#xff0c;javac Test.java&#xff0c;java Test java技术平台&#xff1a; javaSE标准版&#xff0c;javaEE企业版&#xff0c;javaME小型版 java语言面向对象的&#xff08;oop&#xff09;&#xff0c;java跨平台性的&#xff08;…...

玩转 Node.js 集群

一、介绍 Node 在 v0.8 时直接引入了 cluster 模块&#xff0c;用以解决多核 CPU 的利用率问题&#xff0c;同时也提供了较完善的 API&#xff0c;用以处理进程的健壮性问题。 cluster 模块调用 fork 方法来创建子进程&#xff0c;该方法与 child_process 中的 fork 是同一个…...

Day909.MySQL 不同的自增 id 达到上限以后的行为 -MySQL实战

MySQL 不同的自增 id 达到上限以后的行为 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于MySQL 不同的自增 id 达到上限以后的行为的内容。 MySQL 里有很多自增的 id&#xff0c;每个自增 id 都是定义了初始值&#xff0c;然后不停地往上加步长。 虽然自然数是没有…...

JVM学习.01 内存模型

1、前言对于C、C程序员来说&#xff0c;在内存管理领域&#xff0c;他们拥有对象的“所有权”。从对象建立到内存分配&#xff0c;不仅需要照顾到对象的生&#xff0c;还得照顾到对象的消亡。背负着每个对象生命开始到结束的维护和管理责任。对于JAVA程序来说&#xff0c;因为J…...

R+VIC模型应用及未来气候变化模型预测

RVIC模型融合实践技术应用及未来气候变化模型预测在气候变化问题日益严重的今天&#xff0c;水文模型在防洪规划&#xff0c;未来预测等方面发挥着不可替代的重要作用。目前&#xff0c;无论是工程实践或是科学研究中都存在很多著名的水文模型如SWAT/HSPF/HEC-HMS等。虽然&…...

搞懂vue 的 render 函数, 并使用

render函数是什么 简单的说&#xff0c;在vue中我们使用模板HTML语法组建页面的&#xff0c;使用render函数我们可以用js语言来构建DOM 因为vue是虚拟DOM&#xff0c;所以在拿到template模板时也要转译成VNode(虚拟节点)的函数&#xff0c;而用render函数构建DOM&#xff0c;vu…...

【Linux】GDB的安装与使用

安装安装gdb的具体步骤如下&#xff1a;1、查看当前gdb安装情况rpm -qa | grep gdb如果有&#xff0c;则可以先删除&#xff1a;rpm -e --nodeps 文件名如果没有&#xff0c;则进行下一步。2、下载gdb源码包或者直接apt安装。apt命令安装&#xff1a;sudo apt install gdb源码包…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...