我的Spring项目在Eclipse上使用TestNG进行DAO的测试,也就是增删改查的过程中,发现可以正常从access数据库查询数据,但是无法正常插入和删除数据。console中没有报错,直接进入数据库看,确实没有修改的痕迹。可以正常查询说明JdbcTemplate的操作本身没有问题,但是不能修改数据库。
这是为什么?
遇到这个问题说明自己基础知识差。
我当时的思路是这样的:
可以查询但是不能删除和新增,说明我的sql语句没有提交(commit)。
这种思路源于直接使用java语言特性编写JDBC代码的经验,因为你需要在POJO中手动显式的调用下面的语句
setAutoCommit(false);
commit();
我当时的想法是,我的sql语句没有被手动提交或者自动提交,因此没有生效
这个想法是愚蠢的,因为,你并没有直接写POJO,你使用的是Spring提供的JdbcTemplate,你根本不用担心“提交”这个问题,因为Spring封装的JdbcTemplate让这个问题对你透明了。
然后我觉得,一定和“事务”有关。
很可能是我写的代码,使用了Spring的“事务”,但是事务本身没有被提交。
这样想,就接近了问题的起因了。
我们捋顺一下:
1.access数据库本身是不存在“事务”支持的(不同于Mysql的Innodb引擎)
2.Spring代码的事务支持
我查看自己的Spring配置文件,确实添加了事务管理器,如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
classpath:/org/springframework/beans/factory/xml/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
classpath:/org/springframework/context/config/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 -->
<context:component-scan base-package="com.infotech.access.dao"/>
<!-- 配置ucanaccess数据源 -->
<bean id="dsmysql" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="net.ucanaccess.jdbc.UcanaccessDriver"
p:url="jdbc:ucanaccess://\\\\172.16.30.106\\share\\data_be.mdb"
p:username="admin"
p:password="" />
<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dsmysql" />
<!-- 配置JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
p:dataSource-ref="dsmysql" />
</beans>
我们的Spring配置文件中,配置了一个dbcp管理的access数据库的数据源,而且,为这个数据源配置了JdbcTemplate和事务管理器。
那么我们为什么要进行这种配置呢?
因为我们想使用Spring的JdbcTemplate访问access数据库,那么为什么要配置事务管理器呢?
哈哈,这就是问题的实质了,原因是我们写完代码以后要使用TestNG进行测试。让我们重新看一看测试代码:
package com.infotech.access.dao;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests;
import org.testng.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import com.infotech.access.domain.CheckedList;
import static org.testng.Assert.*;
@ContextConfiguration("classpath*:/ruku-context.xml")
public class CheckedlistDaoTest extends <u>AbstractTransactionalTestNGSpringContextTests</u>{
private CheckedlistDao cld;
@Autowired
public void setCheckedlistDao(CheckedlistDao cldlocal){
this.cld = cldlocal;
}
@Test
public void testAcess() {
}
}
上面就是TestNG的测试代码,测试代码中首先导入Spring配置文件ruku-congtext.xml,然后让这个测试类extends AbstractTransactionalTestNGSpringContextTests
也就是让我们的测试类拥有事务。
http://www.iteye.com/problems/100963
这篇博文介绍了TestNG中有关于事务的内容。
继承AbstractTransactionalTestNGSpringContextTests类,test方法中的测试数据不会真的提交数据库,他将在test方法执行完毕后进行回滚。如果你希望控制测试代码的事务提交,可以通过一些annotation来完成。
如下代码:
@Rollback(false)
@Test
public void testAcess() {
}
在你的TestNG测试类中将测试方法标注如上所示的annotation,测试事务就提交了,就可以进行数据的插入和删除了哦