十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
Spring访问数据库异常的处理方法是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
公司主营业务:成都网站建设、网站设计、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。创新互联建站是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。创新互联建站推出文县免费做网站回馈大家。
使用JDBC API时,很多操作都要声明抛出java.sql.SQLException异常,通常情况下是要制定异常处理策略。而Spring的JDBC模块为我们提供了一套异常处理机制,这套异常系统的基类是DataAccessException,它是RuntimeException的一种类型,那么就不用强制去捕捉异常了,Spring的异常体系如下:
目前为止我们还没有明确地处理Spring中JDBC模块的异常。要理解它的异常处理机制,我们来做几个测试。看下面的测试代码:
public void insert(final Vehicle vehicle) {
String sql = "insert into vehicle
(ID,PLATE,CHASSIS,COLOR,WHEEL,SEAT) values
(:id,:plate,:chassis,:color,:wheel,:seat)";
SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(
vehicle);
getSimpleJdbcTemplate().update(sql, parameterSource);
}
public void insert(final Vehicle vehicle) {
String sql = "insert into vehicle(ID,PLATE,CHASSIS,COLOR,WHEEL,SEAT)
values(:id,:plate,:chassis,:color,:wheel,:seat)";
SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(
vehicle);
getSimpleJdbcTemplate().update(sql, parameterSource);
}
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状态(不同的数据库系统会有不同):
关于HSQL数据库的错误码可以到org.hsqldb.Trace类中查看,只要注意运行结果会有一个负号,而类中定义的是没有负号的。这样就知道了这个错误的具体含义,比如104:***约束验证失败。这就是我们故意设置的重复主键问题。
Spring的JDBC模块为我们预定义了一些错误代码,它存储在org.springframework.jdbc.support包下的sql-error-codes.xml文件中,其中描述HSQL的内容为:
HSQL Database Engine -22,-28 -104 -9 -80 HSQL Database Engine -22,-28 -104 -9 -80
其余数据库的错误码内容也可以从这个文件之中获得。下面我们来看看如何自定义异常处理。上面我们已经知道在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会发现它并使用我们自定义的文件,在配置中定义如下:
HSQL的bean的名称不要改,并将useSqlStateForTranslation置为false,就可以使用我们自己定义的异常类了。在主函数中移除try/catch块,启动程序,我们就可以看到如下内容:
从启动信息中可以发现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中重新配置它们:
调整DAO实现类的代码:
public class VehicleDAOImpl extends SimpleJdbcDaoSupport implements VehicleDAO { … … 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()); } … … } public class VehicleDAOImpl extends SimpleJdbcDaoSupport implements VehicleDAO { … … 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()); } … … }
为了进行测试,其它代码可不用修改,这样继续运行测试程序,同时将sql-error-codes.xml文件从类路径的根路径下去除,就可以得到如下结果:
Spring的JDBC模块在自定义异常处理上也非常灵活,可以选择自己喜欢的方式来实现。
关于Spring访问数据库异常的处理方法是什么问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注创新互联行业资讯频道了解更多相关知识。