`
sarin
  • 浏览: 1758045 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
E3b14d1f-4cc5-37dd-b820-b6af951740bc
Spring数据库访问系列...
浏览量:173793
C2083dc5-6474-39e2-993e-263652d27795
Android学习笔记
浏览量:368255
5f40a095-b33c-3e8e-8891-606fcf3b8d27
iBatis开发详解
浏览量:189386
B272a31d-e7bd-3eff-8cc4-c0624ee75fee
Objective-C学习...
浏览量:99957
社区版块
存档分类
最新评论

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 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());
		}

    此时,我们就可以获得错误码和SQL状态(不同的数据库系统会有不同):

    关于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>

    其余数据库的错误码内容也可以从这个文件之中获得。下面我们来看看如何自定义异常处理。上面我们已经知道在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);
	}
}

    之后我们重新新建一个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>

    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();
	}
}

    其中,要覆盖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>

    调整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());
	}
…	…
}

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

    Spring的JDBC模块在自定义异常处理上也非常灵活,可以选择自己喜欢的方式来实现。希望对使用者有用,欢迎交流,下一部分开始介绍Spring的ORM。
  • 大小: 49 KB
  • 大小: 69.1 KB
  • 大小: 75 KB
  • 大小: 68.6 KB
23
7
分享到:
评论
4 楼 去香山看枫叶 2015-06-01  
不错,不错
3 楼 tan135830778 2014-07-09  
请问报错了我只想捕获异常,代码继续运行,该如何修改?
2 楼 抢街饭 2011-02-11  
   
1 楼 pk3589 2011-01-24  
8错8错8错8错8错

相关推荐

    Spring数据库访问(HSQL)(三)

    在"Spring数据库访问(HSQL)(三)"这个主题中,博主可能详细讲解了如何配置Spring与HSQL的集成,以及如何利用Spring的数据访问组件进行数据库操作。 首先,我们需要了解Spring的JdbcTemplate和HibernateTemplate...

    Spring数据库访问(HSQL)(四)

    在本篇博文中,我们将深入探讨Spring框架在数据库访问方面的应用,特别关注使用HSQL内存数据库的实践。Spring是Java领域最广泛使用的轻量级框架之一,它为开发者提供了全面的事务管理、数据访问集成以及IoC...

    基于Spring与Hibernate的数据库访问技术研究

    ### 基于Spring与Hibernate的数据库访问技术研究 #### 引言 在现代企业级应用开发中,数据持久层的设计至关重要,它涉及到如何高效、安全地存储和检索数据。随着互联网技术的发展,传统的两层架构(客户端/服务器...

    Spring Framework 开发参考手册,数据库系统的JDBC驱动程序

    Spring的JDBC抽象层对JDBC的异常进行了封装,比如SqlExceptionTranslator可以将数据库特有的异常转换为Spring的DataAccessException子类,便于统一处理。 8. **批处理** 对于大量数据的操作,JdbcTemplate提供了...

    dwr与spring数据库环境集成

    在数据库集成方面,Spring JDBC模块提供了一组高级的JDBC抽象层,帮助开发者处理诸如事务管理、异常翻译和结果集处理等繁琐任务。此外,Spring还支持JPA、Hibernate等ORM框架,使得数据库操作更加便捷。 在Spring中...

    SpringBoot集成Spring Security实现异常处理+自定义表单登录使用Filter验证【完整源码+数据库】

    在本项目中,我们主要关注的是如何将Spring Boot与Spring Security进行集成,以实现一个具有异常处理和自定义表单登录验证的安全系统。Spring Security是一个强大的安全框架,它提供了多种安全控制,包括用户认证、...

    Spring 数据库动态切换

    数据库的动态切换在很多项目当中都有应用,经我查阅了多篇文档,整合思路最终成功实现数据源的动态切换功能,并稳定运行了一段时间未发现异常。 我的数据源切换时根据域名并配合spring来切换的,不同的域名访问...

    初级JDBC需要的jar包,spring数据库开发

    标题中的"初级JDBC需要的jar包,spring数据库开发"表明了这个压缩包包含了与Spring框架集成JDBC操作数据库相关的库文件。在Java世界里,JDBC(Java Database Connectivity)是Java程序连接和操作数据库的标准接口,...

    【完整源码+数据库】 SpringBoot集成Spring Security实现异常处理+自定义表单登录使用Filter验证

    在本项目中,我们主要关注的是如何将Spring Boot与Spring Security进行集成,以实现一个具有异常处理和自定义表单登录验证的安全系统。Spring Security是一个强大的安全框架,它提供了多种安全控制,包括用户认证、...

    spring+dbunit测试访问数据库代码

    标题中的“spring+dbunit测试访问数据库代码”指的是在Java开发中使用Spring框架与DBUnit进行集成,以实现对数据库的测试。DBUnit是用于数据库单元测试的工具,它可以加载和验证数据库的数据状态,确保测试的隔离性...

    spring连数据库实例`

    Spring的AOP(面向切面编程)可以用于事务管理和异常处理。 8. **单元测试** Spring Test模块提供了测试支持,包括测试环境的配置、模拟数据源、事务管理等,使得数据库相关的单元测试变得容易。 9. **Spring ...

    spring连接数据库aop-jdbc

    Spring 鼓励使用DAO模式来组织数据库访问代码。通过创建DAO接口和实现类,可以将数据库操作与业务逻辑分离,同时利用Spring的依赖注入,使测试和替换数据源变得更加容易。 7. **数据库连接池**: Spring支持多种...

    springMVC例子(数据库)

    【Spring MVC 框架详解】 Spring MVC 是一个基于 Java 的模型-视图-控制器(MVC)架构,用于构建 Web 应用程序...随着经验的积累,可以进一步探索更高级的功能,如拦截器、AOP、异常处理等,以满足更复杂的业务需求。

    Spring数据访问策略

    其中,数据访问策略是Spring的重要组成部分,它为开发者提供了多种处理数据存储和检索的方法。本文将深入探讨Spring的数据访问策略,包括其核心概念、工作原理以及实际应用。 一、JDBC模板与数据访问 在早期的...

    Spring基于线程池的定时任务线挰异常实践

    这篇博文“Spring基于线程池的定时任务线程异常实践”深入探讨了如何在Spring中结合线程池来执行定时任务,并且特别关注了在实际应用中可能出现的异常情况以及如何处理。 首先,我们需要了解Spring的TaskExecutor...

    spring操作MySQL数据库.zip

    在本项目"spring操作MySQL数据库.zip"中,主要展示了如何使用Spring框架与MySQL数据库进行集成,实现对数据库...通过这个项目,开发者可以深入理解Spring如何在实际应用中处理数据库操作,并且能够运用到自己的项目中。

    Spring Security 基于数据库的权限管理配置

    在基于数据库的权限管理配置中,Spring Security 允许我们存储、管理和验证用户的访问权限,这使得权限控制更加灵活和可扩展。下面将详细阐述如何进行Spring Security的数据库权限管理配置。 1. **配置数据源** 在...

    STS创建Spring Boot项目实战(Rest接口、数据库、用户认证、分布式Token JWT、Redis操作、日志和统一异常处理)

    创建一个全面的Spring Boot应用,涵盖了多个关键领域,包括RESTful接口、数据库交互、用户认证、分布式Token的实现(JWT)、Redis缓存操作、日志记录以及统一异常处理。下面将详细阐述这些知识点。 1. **Spring ...

    spring mvc + mybitis + mysql集成例子,带数据库

    7. **错误和异常处理**:使用Spring的@ControllerAdvice和@ExceptionHandler注解可以全局处理错误和异常,提高用户体验。 通过这个集成例子,开发者可以学习到如何将这三个组件有效地整合在一起,创建一个功能完善...

Global site tag (gtag.js) - Google Analytics