iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Spring访问数据库异常的处理方法是什么
  • 522
分享到

Spring访问数据库异常的处理方法是什么

2023-06-17 13:06:57 522人浏览 安东尼
摘要

spring访问数据库异常的处理方法是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。使用JDBC api时,很多操作都要声明抛出java.sql.SQLExceptio

spring访问数据库异常的处理方法是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

使用JDBC api时,很多操作都要声明抛出java.sql.SQLException异常,通常情况下是要制定异常处理策略。而Spring的JDBC模块为我们提供了一套异常处理机制,这套异常系统的基类是DataAccessException,它是RuntimeException的一种类型,那么就不用强制去捕捉异常了,Spring的异常体系如下:
Spring访问数据库异常的处理方法是什么

目前为止我们还没有明确地处理Spring中JDBC模块的异常。要理解它的异常处理机制,我们来做几个测试。看下面的测试代码:

  1.  public void insert(final Vehicle vehicle) {      

  2. String sql = "insert into vehicle  

  3. (ID,PLATE,CHASSIS,COLOR,WHEEL,SEAT) values  

  4. (:id,:plate,:chassis,:color,:wheel,:seat)";      

  5.     SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(      

  6.             vehicle);      

  7.     getSimpleJdbcTemplate().update(sql, parameterSource);      

  8. }     

  9.     public void insert(final Vehicle vehicle) {  

  10.         String sql = "insert into vehicle(ID,PLATE,CHASSIS,COLOR,WHEEL,SEAT) 

  11. values(:id,:plate,:chassis,:color,:wheel,:seat)";  

  12.         SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(  

  13.                 vehicle);  

  14.         getSimpleJdbcTemplate().update(sql, parameterSource);  

  15.     } 


     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状态(不同的数据库系统会有不同):

Spring访问数据库异常的处理方法是什么

关于HSQL数据库的错误码可以到org.hsqldb.Trace类中查看,只要注意运行结果会有一个负号,而类中定义的是没有负号的。这样就知道了这个错误的具体含义,比如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访问数据库异常的处理方法是什么

从启动信息中可以发现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方法,方法有三个参数,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 {          &hellip;   &hellip;          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());          }      &hellip;   &hellip;      }     public class VehicleDAOImpl extends SimpleJdbcDaoSupport implements VehicleDAO {      &hellip;   &hellip;      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());      }  &hellip;   &hellip;  }

为了进行测试,其它代码可不用修改,这样继续运行测试程序,同时将sql-error-codes.xml文件从类路径的根路径下去除,就可以得到如下结果:

Spring访问数据库异常的处理方法是什么

Spring的JDBC模块在自定义异常处理上也非常灵活,可以选择自己喜欢的方式来实现。

关于Spring访问数据库异常的处理方法是什么问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网精选频道了解更多相关知识。

--结束END--

本文标题: Spring访问数据库异常的处理方法是什么

本文链接: https://www.lsjlt.com/news/289486.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++ 生态系统中流行库和框架的贡献指南
    作为 c++++ 开发人员,通过遵循以下步骤即可为流行库和框架做出贡献:选择一个项目并熟悉其代码库。在 issue 跟踪器中寻找适合初学者的问题。创建一个新分支,实现修复并添加测试。提交...
    99+
    2024-05-14
    框架 c++ 流行库 git
  • C++ 生态系统中流行库和框架的社区支持情况
    c++++生态系统中流行库和框架的社区支持情况:boost:活跃的社区提供广泛的文档、教程和讨论区,确保持续的维护和更新。qt:庞大的社区提供丰富的文档、示例和论坛,积极参与开发和维护。...
    99+
    2024-05-14
    生态系统 社区支持 c++ overflow 标准库
  • c++中if elseif使用规则
    c++ 中 if-else if 语句的使用规则为:语法:if (条件1) { // 执行代码块 1} else if (条件 2) { // 执行代码块 2}// ...else ...
    99+
    2024-05-14
    c++
  • c++中的继承怎么写
    继承是一种允许类从现有类派生并访问其成员的强大机制。在 c++ 中,继承类型包括:单继承:一个子类从一个基类继承。多继承:一个子类从多个基类继承。层次继承:多个子类从同一个基类继承。多层...
    99+
    2024-05-14
    c++
  • c++中如何使用类和对象掌握目标
    在 c++ 中创建类和对象:使用 class 关键字定义类,包含数据成员和方法。使用对象名称和类名称创建对象。访问权限包括:公有、受保护和私有。数据成员是类的变量,每个对象拥有自己的副本...
    99+
    2024-05-14
    c++
  • c++中优先级是什么意思
    c++ 中的优先级规则:优先级高的操作符先执行,相同优先级的从左到右执行,括号可改变执行顺序。操作符优先级表包含从最高到最低的优先级列表,其中赋值运算符具有最低优先级。通过了解优先级,可...
    99+
    2024-05-14
    c++
  • c++中a+是什么意思
    c++ 中的 a+ 运算符表示自增运算符,用于将变量递增 1 并将结果存储在同一变量中。语法为 a++,用法包括循环和计数器。它可与后置递增运算符 ++a 交换使用,后者在表达式求值后递...
    99+
    2024-05-14
    c++
  • c++中a.b什么意思
    c++kquote>“a.b”表示对象“a”的成员“b”,用于访问对象成员,可用“对象名.成员名”的语法。它还可以用于访问嵌套成员,如“对象名.嵌套成员名.成员名”的语法。 c++...
    99+
    2024-05-14
    c++
  • C++ 并发编程库的优缺点
    c++++ 提供了多种并发编程库,满足不同场景下的需求。线程库 (std::thread) 易于使用但开销大;异步库 (std::async) 可异步执行任务,但 api 复杂;协程库 ...
    99+
    2024-05-14
    c++ 并发编程
  • 如何在 Golang 中备份数据库?
    在 golang 中备份数据库对于保护数据至关重要。可以使用标准库中的 database/sql 包,或第三方包如 github.com/go-sql-driver/mysql。具体步骤...
    99+
    2024-05-14
    golang 数据库备份 mysql git 标准库
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作