Spring访问数据库异常的处理方法来源:Javaeye博客发布时间:2011-01-2220:45阅读:134次原文链接全屏阅读[收藏]编辑点评:天我们将谈谈Spring访问数据库异常的处理方法,使用JDBCAPI时,很多操作都要声明抛出java.sql.SQLException异常,通常情况下是要制定异常处理策略。使用JDBCAPI时,很多操作都要声明抛出java.sql.SQLException异常,通常情况下是要制定异常处理策略。而Spring的JDBC模块为我们提供了一套异常处理机制,这套异常系统的基类是DataAccessException,它是RuntimeException的一种类型,那么就不用强制去捕捉异常了,Spring的异常体系如下:目前为止我们还没有明确地处理Spring中JDBC模块的异常。要理解它的异常处理机制,我们来做几个测试。看下面的测试代码:1.publicvoidinsert(finalVehiclevehicle){2.Stringsql=insertintovehicle3.(ID,PLATE,CHASSIS,COLOR,WHEEL,SEAT)values4.(:id,:plate,:chassis,:color,:wheel,:seat);5.SqlParameterSourceparameterSource=newBeanPropertySqlParameterSource(6.vehicle);7.getSimpleJdbcTemplate().update(sql,parameterSource);8.}9.publicvoidinsert(finalVehiclevehicle){10.Stringsql=insertintovehicle(ID,PLATE,CHASSIS,COLOR,WHEEL,SEAT)11.values(:id,:plate,:chassis,:color,:wheel,:seat);12.SqlParameterSourceparameterSource=newBeanPropertySqlParameterSource(13.vehicle);14.getSimpleJdbcTemplate().update(sql,parameterSource);15.}publicstaticvoidmain(String[]args){ApplicationContextctx=newClassPathXmlApplicationContext(classpath:org/ourpioneer/vehicle/spring/applicationContext.xml);VehicleDAOvehicleDAO=(VehicleDAO)ctx.getBean(vehicleDAO);Vehiclevehicle=newVehicle(辽B-000000,1A00000001,RED,4,4);vehicle.setId(1);vehicleDAO.insert(vehicle);}publicstaticvoidmain(String[]args){ApplicationContextctx=newClassPathXmlApplicationContext(classpath:org/ourpioneer/vehicle/spring/applicationContext.xml);VehicleDAOvehicleDAO=(VehicleDAO)ctx.getBean(vehicleDAO);Vehiclevehicle=newVehicle(辽B-000000,1A00000001,RED,4,4);vehicle.setId(1);vehicleDAO.insert(vehicle);}修改SQL语句,不使用自增主键的特性,并在这里设置重复的主键,那么运行程序,就会报出字段重复的异常。下面来捕捉这个异常:1.try{2.vehicleDAO.insert(vehicle);3.}catch(DataAccessExceptione){4.SQLExceptionsqle=(SQLException)e.getCause();5.System.out.println(Errorcode:+sqle.getErrorCode());6.System.out.println(SQLstate:+sqle.getSQLState());7.}8.try{9.vehicleDAO.insert(vehicle);10.}catch(DataAccessExceptione){11.SQLExceptionsqle=(SQLException)e.getCause();12.System.out.println(Errorcode:+sqle.getErrorCode());13.System.out.println(SQLstate:+sqle.getSQLState());14.}此时,我们就可以获得错误码和SQL状态(不同的数据库系统会有不同):关于HSQL数据库的错误码可以到org.hsqldb.Trace类中查看,只要注意运行结果会有一个负号,而类中定义的是没有负号的。这样就知道了这个错误的具体含义,比如104:唯一约束验证失败。这就是我们故意设置的重复主键问题。Spring的JDBC模块为我们预定义了一些错误代码,它存储在org.springframework.jdbc.support包下的sql-error-codes.xml文件中,其中描述HSQL的内容为:1.beanid=HSQLclass=org.springframework.jdbc.support.SQLErrorCodes2.propertyname=databaseProductName3.valueHSQLDatabaseEngine/value4./property5.propertyname=badSqlGrammarCodes6.value-22,-28/value7./property8.propertyname=duplicateKeyCodes9.value-104/value10./property11.propertyname=dataIntegrityViolationCodes12.value-9/value13./property14.propertyname=dataAccessResourceFailureCodes15.value-80/value16./property17./bean18.beanid=HSQLclass=org.springframework.jdbc.support.SQLErrorCodes19.propertyname=databaseProductName20.valueHSQLDatabaseEngine/value21./property22.propertyname=badSqlGrammarCodes23.value-22,-28/value24./property25.propertyname=duplicateKeyCodes26.value-104/value27./property28.propertyname=dataIntegrityViolationCodes29.value-9/value30./property31.propertyname=dataAccessResourceFailureCodes32.value-80/value33./property34./bean其余数据库的错误码内容也可以从这个文件之中获得。下面我们来看看如何自定义异常处理。上面我们已经知道在org.springframework.jdbc.support包下有sql-error-codes.xml文件,在Spring启动时会自动读取这个文件中的错误码,它为我们预分类了一些错误码,而我们可以加强它,来使用我们自定义的异常。首先,定义一个异常类,我们就来自定义一下前面的-104错误,就是HSQL的重复键的问题:1.packageorg.ourpioneer.vehicle.exception;2.importorg.springframework.dao.DataIntegrityViolationException;3.publicclassVehicleDuplicateKeyExceptionextends4.DataIntegrityViolationException{5.publicVehicleDuplicateKeyException(Stringmsg){6.super(msg);7.}8.publicVehicleDuplicateKeyException(Stringmsg,Throwablecause){9.super(msg,cause);10.}11.}12.packageorg.ourpioneer.vehicle.exception;13.importorg.springframework.dao.DataIntegrityViolationException;14.publicclassVehicleDuplicateKeyExceptionextends15.DataIntegrityViolationException{16.publicVehicleDuplicateKeyException(Stringmsg){17.super(msg);18.}19.publicVehicleDuplicateKeyException(Stringmsg,Throwablecause){20.super(msg,cause);21.}22.}之后我们重新新建一个sql-error-codes.xml代码,并将它放到类路径的根目录下,这样Spring会发现它并使用我们自定义的文件,在配置中定义如下:1.beanid=HSQLclass=org.springframework.jdbc.support.SQLErrorCodes2.propertyname=databaseProductNamevalue=HSQLDatabaseEngine/3.propertyname=useSqlStateForTranslationvalue=false/4.propertyname=customTranslations5.list6.reflocal=vehicleDuplicateKeyTranslation/7./list8./property9./bean10.beanid=vehicleDuplicateKeyTranslation11.class=org.springframework.jdbc.support.CustomSQLErrorCodesTranslation12.propertyname=errorCodesvalue=-104/13.propertyname=exceptionClass14.value=org.ourpioneer.vehicle.exception.VehicleDuplicateKeyException/15./bean16.beanid=HSQLclass=org.springframework.jdbc.support.SQLErrorCodes17.propertyname=databaseProductNamevalue=HSQLDatabaseEngine/18.propertyname=useSqlStateForTranslationvalue=false/19.propertyname=customTranslations20.list21.reflocal=vehicleDuplicateKeyTranslation/22