Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
Spring+iBatis+DBUnit ½øÐе¥Ôª²âÊÔ
 
×÷Õߣº·è×Óliu À´Ô´£º²®ÀÖÔÚÏß ·¢²¼ÓÚ 2015-8-27
  3862  次浏览      27
 

Ôںܶà³É¹¦µÄÈí¼þÏîÄ¿ÖУ¬²âÊÔ×Ô¶¯»¯ÍùÍùÊǹؼüµÄ²ãÃæ¡£DBUnitÔÊÐí¿ª·¢ÈËÔ±ÔÚ²âÊÔ֮ǰ¸øÄ¿±êÊý¾Ý¿âÖ²Èë²âÊÔÊý¾Ý£¬ÔÚ²âÊÔÍê±Ïºó£¬ÔÙ½«Êý¾Ý¿â»Ö¸´µ½²âÊÔǰµÄ״̬¡£ÔÚ×î½üµÄÒ»¸öÏîÄ¿ÖУ¬ÎÒ³¢ÊÔʹÓÃÓÃDBUnit¶ÔSpring+iBatisµÄ¼Ü¹¹½øÐвâÊÔ£¬ÏÂÃæ¼Ç¼ÁËDBUnitµÄʹÓùý³ÌºÍÓöµ½µÄһЩÎÊÌâ¡£

²âÊÔ»·¾³

Ê×ÏÈ£¬ÎÒÃǽ¨Á¢Ò»¸ö²âÊÔ»·¾³£¨»ùÓÚMaven 2ºÍOracleÊý¾Ý¿â*£©¡£Êý¾Ý±íÃûAccount¡£

Êý¾Ý¿â

ÏȽ¨Á¢Ò»¸ö²âÊÔÊý¾Ý±í£¨Êý¾Ý¿âΪOracle*£©

Account.sql

CREATE TABLE Account
("ID" NUMBER,
"USERNAME" VARCHAR2(256 BYTE) NOT NULL ENABLE,
"PASSWORD" VARCHAR2(256 BYTE),
CONSTRAINT "ACCOUNT_UK_ID" UNIQUE ("ID"),
CONSTRAINT "ACCOUNT_PK" PRIMARY KEY ("USERNAME")
)

ÕâÀïÎÒÔÝʱ²»ÏëÉæ¼°Sequence£¬ËùÒÔÖ÷¼ü**ÊÇusername£¬¶ø²»ÊÇID£¬²¢ÇÒIDÔÊÐíΪNULL¡£ÕâÊÇÒòΪSequenceµÄµÝÔöÊDz»¿É»Ö¸´µÄ£¬Èç¹ûÏîÄ¿¶Ô¼Ç¼IDÊÇ·ñÁ¬Ðø²»ÊÇÌØ±ðÔÚÒâµÄ»°£¬¿ÉÒÔÔÚ×Ô¼ºµÄÏîÄ¿Öн¨Á¢£¬Ö»ÒªÉÔ΢ÐÞ¸ÄÒ»ÏÂiBatisÅäÖÃÎļþÖеÄSQLÓï¾ä¾Í¿ÉÒÔÁË¡£ÕâÀïÎÒÃÇÏÈÆÁ±ÎÕâ¸öÎÊÌâ¡£

DBUnit²âÊÔOracleÊý¾Ý¿âʱ£¬ÕÊ»§×îºÃ²»ÒªÓµÓÐDBAȨÏÞ£¬·ñÔò»á³öÏÖorg.dbunit.database.AmbiguousTableNameException: COUNTRIES ´íÎó¡£Èç¹ûÕÊ»§±ØÐë¾ß±¸DBAȨÏÞ£¬ÄÇô¾ÍÐèÒªÔÚÖ´ÐÐnew DatabaseConnectionʱ£¬Ã÷È·¸ø¶¨SCHEMA£¨Ãû³Æ±ØÐë´óд£©£¬Ïêϸ˵Ã÷²Î¿¼ÏÂÎĶദ´úÂë×¢Êͺ͡°org.dbunit.database.AmbiguousTableNameExceptionÒì³£¡±Õ½ڡ£

±í±ØÐë´æÔÚÖ÷¼ü£¬·ñÔò·µ»Øorg.dbunit.dataset.NoPrimaryKeyException´íÎó¡£

SpringÅäÖÃÎļþ

ApplicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:database.properties</value>
</list>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.connection.driver_class}"/>
<property name="url" value="${database.connection.url}"/>
<property name="username" value="${database.connection.username}"/>
<property name="password" value="${database.connection.password}"/>
</bean>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>SqlMapConfig.xml</value>
</property>
<property name="dataSource" ref="dataSource"/>
</bean>

<bean id="accountManager" class="com.wang.dbunit.AccountManager">
<property name="sqlMapClient" ref="sqlMapClient"/>
</bean>
</beans>


database.properties
database.connection.driver_class=oracle.jdbc.driver.OracleDriver
database.connection.url=jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:test
database.connection.username=username
database.connection.password=password

iBatisÅäÖÃÎļþ

SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig
PUBLIC"-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<settings
useStatementNamespaces="false"
cacheModelsEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="true"
maxRequests="32"
maxSessions="10"
maxTransactions="5"
/>
<sqlMap resource="Account.xml"/>
</sqlMapConfig>

Account.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPEsqlMap
PUBLIC"-//iBATIS.com//DTD SQL Map 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="Account">
<resultMap id="accountMap" class="com.wang.dbunit.Account">
<result property="id" column="id" jdbcType="NUMBER" nullValue="0"/>
<result property="userName" column="username" jdbcType="VARCHAR2"/>
<result property="password" column="password" jdbcType="VARCHAR2"/>
</resultMap>
<!--** preserve ************************************** -->
<sql id="id-select">
<![CDATA[
SELECT id_sequence.nextval AS id FROM dual
]]>
</sql>
<!--*************************************************** -->
<sql id="account-select">
<![CDATA[
SELECTid, username
]]>
<dynamic prepend=",">
<isEqual
property="includePassword"
compareValue="true">
password
</isEqual>
</dynamic>
FROMaccount
</sql>
<sql id="account-where">
<![CDATA[
username=#userName:VARCHAR2#
]]>
<dynamic>
<isNotNull
property="password"
prepend="AND ">
<![CDATA[
password=#password:VARCHAR2#
]]>
</isNotNull>
</dynamic>
</sql>
<select id="getAccount"
parameterClass="com.wang.dbunit.Account"
resultMap="accountMap">
<include refid="account-select"/>
<dynamic prepend=" WHERE">
<isNotNull
property="userName">
<include refid="account-where"/>
</isNotNull>
</dynamic>
</select>
<!--**************************************************** -->
<sql id="account-insert">
<![CDATA[
INSERT INTO account(username, password
]]>
<dynamic prepend=",">
<isNotEqual
property="id"
compareValue="0">
<![CDATA[
id
]]>
</isNotEqual>
</dynamic>
)
</sql>

<sql id="account-insert-values">
<![CDATA[
VALUES(#userName:VARCHAR2#, #password:VARCHAR2#
]]>
<dynamic prepend=",">
<isNotEqual
property="id"
compareValue="0">
<![CDATA[
#id:NUMBER#
]]>
</isNotEqual>
</dynamic>
)
</sql>
<insert id="createAccount"
parameterClass="com.wang.dbunit.Account">
<isEqual
property="generateIdFromSequence"
compareValue="true">
<include refid="id-select"/>
</isEqual>
<include refid="account-insert"/>
<include refid="account-insert-values"/>
</insert>
</sqlMap>

£¨Õâ¸öÅäÖÃÎļþÖÐÔ¤ÁôÁËδÀ´Ê¹Óà sequence µÄ¿ÉÄÜ£©

DBUnitÅäÖÃÎļþ

ÎÒÃÇͨ¹ýÒ»¸öxmlÖÖ×ÓÎļþ(seedfile)ΪDBUnitÌṩ²âÊÔÊý¾Ý£¬ÎļþÖеÄÊý¾Ý»á±»DBUnitÔÚ²âÊÔ¿ªÊ¼Ç°×Ô¶¯Ö²ÈëÊý¾Ý±í£¬Õâ¸öÎļþ½á¹¹ºÜ¼òµ¥£º

dataSet.xml

<?xml version='1.0' encoding='UTF-8'?>
<DATASET>
<ACCOUNT id='1'
username='Drew'
password='Smith'/>
<ACCOUNT id='2'
username='Nick'
password='Marquiss'/>
<ACCOUNT id='3'
username='Jose'
password='Whitson'/>
</DATASET>

¡°ACCOUNT¡±¾ÍÊDZíÃû³Æ£¬ËüµÄÊôÐÔ¾ÍÊÇ×Ö¶ÎÄÚÈÝ¡£

´úÂë

¸¨ÖúÀàAccout.java

package com.wang.dbunit;
public class Account
{
private boolean generateIdFromSequence=false;
private boolean includePassword = false;
private long id = 0;
private String userName = null;
private String password = null;
public boolean getGenerateIdFromSequence()
{
return generateIdFromSequence;
}
public void setGenerateIdFromSequence(boolean generateIdFromSequence)
{
this.generateIdFromSequence =generateIdFromSequence;
}
public void setId(long id)
{
this.id =id;
}
public long getId()
{
return this.id;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password =password;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName =userName;
}
public boolean isIncludePassword()
{
return includePassword;
}
public void setIncludePassword(boolean includePassword)
{
this.includePassword =includePassword;
}
}

ÒµÎñÀàAccountManager.java

package com.wang.dbunit;
import com.ibatis.sqlmap.client.SqlMapClient;
public class AccountManager
{
protected SqlMapClient sqlMap = null;
public void setSqlMapClient(SqlMapClient sqlMapClient)
{
this.sqlMap =sqlMapClient;
}
public Account getAccount(String userName, String password, boolean includePassword) throws Exception
{
Account account = new Account();
account.setUserName(userName);
account.setPassword(password);
account.setIncludePassword(includePassword);
Account ret
= (Account)(sqlMap.queryForObject("getAccount", account));
return ret;
}
public void createAccount(String userName, String password) throws Exception
{
Account account = new Account();
account.setUserName(userName);
account.setPassword(password);
sqlMap.insert("createAccount",account);
}
}

ºÃÁË£¬ÎÒÃÇÍê³ÉÁËÁËÈ«²¿²âÊÔ»·¾³£¬½ÓÏÂÀ´ÎÒÃÇÒª¿ªÊ¼±àд²âÊÔÓÃÀý¡£

²âÊÔ

DatabaseTestCaseÀà

DBUnitÌṩÁËÒ»¸ö³éÏóÀࣺ DatabaseTestCase£¬Ëü¼Ì³Ð×Ô JUnitµÄ TestCase£¬Õâ¸öÀàÓÐÁ½¸ö·½·¨ÐèÒªÖØÔØ£º

protecte abstract IDatabaseConnection getConnection() throws Exception;
protected abstract IDataSet getDataSet() throws Exception;

getConnectionÓÃÓÚ¸æËß²âÊÔÓÃÀýÈçºÎÕÒµ½Êý¾Ý¿âÁ¬½Ó£»getDataSetÓÃÓÚ¸æËß²âÊÔÓÃÀýÈçºÎ»ñÈ¡²âÊÔÊý¾ÝÎļþ£¨dataSet.xml£©¡£ÏÂÃæÎÒÃÇÏȼ̳ÐÕâ¸ö³éÏóÀà±àд²âÊÔÓÃÀý£º

package com.wang.dbunit;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;
import javax.sql.DataSource;
import com.wang.dbunit.Account;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.dbunit.DatabaseTestCase;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.operation.DatabaseOperation;
public class HelloDBUnit extends DatabaseTestCase
{
static Logger logger
= LogManager.getLogger(HelloDBUnit.class.getName());
privatestatic ApplicationContext context;
protected Properties props = new Properties();
public HelloDBUnit() throws IOException
{
super();
props.load(Resources.getResourceAsStream(
"database.properties"));
context = newClassPathXmlApplicationContext(
"classpath:ApplicationContext.xml");
}
////////////////////////////////////////////////
@Override
protected IDatabaseConnection getConnection() throws Exception
{
DataSourcedataSource
= (DataSource)context.getBean("dataSource");
Connectionconnection = dataSource.getConnection();
// Èç¹ûËùÓòâÊÔÕÊ»§ÊÇ DBA£¬ÎªÁ˱ÜÃâ³öÏÖ AmbiguousTableNameException
// Òì³££¬ÏÂÃæ±ØÐë¸ÄдΪ newDatabaseConnection(connection, SCHEMA)
// ÐÎʽ¡£×¢ÒâSCHEMA Òª´óд**
return new DatabaseConnection(connection);
}
@Override
protected IDataSet getDataSet()throws Exception
{
return new FlatXmlDataSet(
new FileInputStream("bin/dataSet.xml"));
}
///////////////////////////////////////////////
@Override
protected DatabaseOperation getSetUpOperation() throws Exception
{
return DatabaseOperation.REFRESH;
}
@Override
protected DatabaseOperation getTearDownOperation() throws Exception
{
return DatabaseOperation.NONE;
}
////////////////////////////////////////////////////
public void testSelectAccount()
{
AccountManager manager
= (AccountManager)context.getBean("accountManager");
try
{
Accountaccount
= manager.getAccount("Nick", "Marquiss", true);
assertNotNull(account);
}
catch (Exceptione)
{
logger.error(e.getMessage(),e);
}
}
public void testCreateAccount()
{
AccountManager manager
= (AccountManager)context.getBean("accountManager");
try
{
manager.createAccount("TEST", "test");
}
catch(Exception e)
{
logger.error(e.getMessage(),e);
}
}
}

ÔÚgetConnection·½·¨ÖУ¬ÎÒÃÇͨ¹ýSpringÅäÖÃÎļþ»ñµÃÊý¾ÝÁ¬½Ó¡£

³ýÁËÇ°ÃæÄÇÁ½¸ö·½·¨Í⣬ÎÒÃÇ»¹ÖØÔØÁË getSetUpOperation ºÍ getTearDownOperation ·½·¨£ºDatabaseOperation.REFRESH ¸æËßDBUnitÔÚ²âÊÔ¿ªÊ¼Ç°±È½ÏÊý¾Ý¿âºÍÅäÖÃÎļþ£¬Èç¹û·¢ÏÖ²âÊÔÊý¾Ý²»´æ»ò²»Ò»ÖÂÔÚÔò²åÈë»ò¸üÐÂ***¡£DatabaseOperation.NONE±íʾʲôҲ²»×ö¡£

Õâ¸öCASEÓ¦¸Ã¿ÉÒÔÔËÐеĺܺ㬵«ÊÇÈç¹ûÎÒÃÇ°Ñ getTearDownOperation¸Ä³É£º

@Override
protected DatabaseOperation getTearDownOperation() throws Exception
{
return DatabaseOperation.DELETE_ALL;
}

¾Í»á·¢Éújava.sql.SQLException: Closed ConnectionÒì³£¡£ÕâÊÇÎªÊ²Ã´ÄØ£¿ÎÊÌâ³öÔÚDatabaseTestCaseÖС£

²ÎÊýº¬Òå

DatabaseOperation.CLEAN_INSERT; ÏÈɾ³ý±íÖÐËùÓУ¬ÔÙ²åÈë×¼±¸µÄÊý¾Ý

DatabaseOperation.REFRESH; ʹÓÃ×¼±¸Êý¾Ý¸üÐÂ±í£¬´æÔÚÔòupdate£¬²»´æÔÚÔòinsert

DatabaseOperation.DELETE; ֻɾ³ý×¼±¸µÄÊý¾Ý

DatabaseOperation.DELETE_ALL Çå³ýËùÓмǼ

DatabaseOperation.NONE; ɶ¶¼²»×ö

java.sql.SQLException: Closed ConnectionÒì³£

À´¿´Ò»ÏÂDatabaseTestCaseµÄÒ»¸ö¹Ø¼ü³ÉÔ±±äÁ¿testerºÍÓйصÄһЩ·½·¨£º

public abstract class DatabaseTestCase extends TestCase
{
......
private IDatabaseTester tester;
......
protected IDatabaseTester getDatabaseTester() throws Exception {
if (this.tester == null) {
this.tester = newDatabaseTester();
}
return this.tester;
}
......
protected IDatabaseTester newDatabaseTester() throws Exception{
logger.debug("newDatabaseTester()- start");
// ÖØÔØµÄ getConnection ·½·¨£¬ÔÚ IDatabaseTester ÀïÓÐÒ»¸öͬÃû·½·¨¡£
// ×¢ÒâÇø·Ö¡£
final IDatabaseConnection connection = getConnection();
final IDatabaseTester tester
= new DefaultDatabaseTester(connection);
return tester;
}
......
protected void setUp() throws Exception
{
logger.debug("setUp()- start");
super.setUp();
final IDatabaseTester databaseTester = getDatabaseTester();
assertNotNull("DatabaseTesteris not set", databaseTester);
databaseTester.setSetUpOperation(getSetUpOperation());
databaseTester.setDataSet(getDataSet());
databaseTester.onSetup();
}
......
}

¿É¼û DatabaseTestCase ÄÚ²¿ÓÐÒ»¸ö IDatabaseTester ½Ó¿ÚµÄʵÀý£¨tester£©£¬Êµ¼ÊÉÏËùÓеIJâÊÔ¹¤×÷ÊÇÓÉËüÍê³ÉµÄ¡£¶øDatabaseTestCaseµÄnewDatabaseTester·½·¨ÔÚÉú³ÉÕâ¸öʵÀýµÄʱºòÓõÄÊÇDefaultDatabaseTester¡£´«ÈëÒ»¸öÓÉÖØÔØµÄgetConnection·½·¨·µ»ØµÄIDatabaseConnectionʵÀý¡£

DefaultDatabaseTester¼Ç¼ÁËÕâ¸öÁ¬½ÓʵÀýºó£¬ÌṩÁËÒ»¸öͬÃûµÄgetConnection()·½·¨£¨²»ÊÇDatabaseTestCaseÖб»ÖØÔصÄÄǸögetConnection£©£¬ÓÃÀ´·µ»ØËü£º

public class DefaultDatabaseTester extends AbstractDatabaseTester
{
final IDatabaseConnection connection;
public DefaultDatabaseTester(final IDatabaseConnection connection){
this.connection= connection;
}
public IDatabaseConnection getConnection() throws Exception {
return this.connection;
}
}

ÒòΪËùÓеÄIDatabaseTesterʵÏÖ£¨°üÀ¨DefaultDatabaseTester£©¶¼¼Ì³Ð×ÔAbatractDatabaseTester£¬Õâ¸ö³éÏóÀàÓÐÒ»¸öͳһµÄÖ´ÐÐÊý¾Ý¿â²Ù×÷µÄ·½·¨executeOperation£¬Ô­´úÂëÈçÏ£º

private void executeOperation(DatabaseOperation operation) throws Exception
{
logger.debug("executeOperation(operation={})- start", operation);
if(operation != DatabaseOperation.NONE ){
// IDatabaseTester µÄ getConnection ·½·¨£¬²»ÊÇÖØÔØµÄÄǸö¡£
IDatabaseConnection connection = getConnection();
try{
operation.execute(connection, getDataSet() );
}
finally{
closeConnection(connection);
}
}
}

ÎÒÃÇ¿´µ½Ã¿Ö´ÐÐÍêÒ»´Î²Ù×÷£¬Êý¾Ý¿âÁ¬½Ó¶¼»á±»¹Ø±Õ£¬ËùÒÔÈç¹û¼Ì³ÐDefaultDatabaseTester£¬½«µ¼ÖÂÖ»ÄÜÖ´ÐÐÒ»´ÎÊý¾Ý¿â²Ù×÷¡£

Èç¹ûÏ£ÍûÔÚÒ»¸öTestCaseÀïÖ´ÐÐÁ½´Î²Ù×÷£¬ÎÒÃÇ¿ÉÒÔʹÓÃÁíÒ»¸ö»ùÀà

DBTestCaseÀà

ÈçÉÏÃæËù¿´µ½µÄ£¬ÎÊÌâ³öÔÚDatabaseTestCaseµÄnewDatabaseTester·½·¨·µ»ØÁËÒ»¸öÎÞ·¨Öظ´ÀûÓõÄDefaultDatabaseTesterʵÀý£¬ËùÒÔDBTestCaseµÄnewDatabaseTester·½·¨´úÂë±ä¸üÈçÏ£º

protected IDatabaseTester newDatabaseTester() throws Exception {
return new PropertiesBasedJdbcDatabaseTester();
}

ËüÓÃÀ´Éú³ÉʵÀýµÄÊÇ PropertiesBasedJdbcDatabaseTester À࣬¶ø²»ÊÇ DefaultDatabaseTester ¡£Õâ¸öÀàµÄ¸¸Àà JdbcDatabaseTester£¨Ò²¼Ì³Ð×Ô AbstractDatabaseTester£©µÄ getConnection ·½·¨£º

public IDatabaseConnection getConnection() throws Exception
{
logger.debug("getConnection() - start");
if(!initialized ){
// ×¢ÒâÕâ¸ö·½·¨£¬µÈÒ»ÏÂÏê½â
initialize();
}
assertNotNullNorEmpty("connectionUrl", connectionUrl);
Connection conn = null;
if(username == null && password == null ){
conn = DriverManager.getConnection(connectionUrl);
}else{
Conn = DriverManager.getConnection(connectionUrl,username,password);
}
return new DatabaseConnection( conn, getSchema() );
}

¿ÉÒÔ¿´µ½Ã¿´Îµ÷ÓÃÕâ¸ö·½·¨£¬¶¼»áн¨Ò»¸öÁ¬½Ó£¬¶ø²»ÊǼòµ¥µÄ·µ»ØÎÒÃÇÖØÔØµÄ getConnection Öзµ»ØµÄÁ¬½ÓµÄÒýÓá£ÕâÑù¾Í±ÜÃâÁË DefaultDatabaseTester ½ö½öÊǼòµ¥·µ»ØÖ®Ç°µÄÁ¬½Ó¶øµ¹ÖõÄÎÊÌâ¡£²»¹ýÕâÒ²Òâζ×ÅÓà DBTestCase ¾Í²»ÓÃÎÒÃÇ×Ô¼ºÈ¥ÖØÔØ getConnection ÁË£¬ÒòΪ DBTestCase ÒѾ­ÊµÏÖÁËÕâ¸ö·½·¨£¨DatabaseTestCaseûÓÐʵÏÖ£©£º

protected IDatabaseConnection getConnection() throws Exception {
logger.debug("getConnection() - start");
final IDatabaseTester databaseTester = getDatabaseTester();
assertNotNull( "DatabaseTester is not set",databaseTester);
return databaseTester.getConnection();
}

ÎÒÃÇ¿´µ½DBTestCaseµÄgetConnection¼òµ¥µÄ°ÑÕâ¸ö·½·¨×ª¸øJdbcDatabaseTester£¨IDatabaseTester£© µÄgetConnection¡£¶øJdbcDatabaseTesterµÄʵÏÖÎÒÃÇÔÚÇ°ÃæÒѾ­¿´µ½ÁË¡£

ÏÖÔÚÎÒÃǰÑDatabaseTestCaseÌæ»»³ÉDBTestCase£¬²¢ÇÒ×¢Ê͵ôHelloDBUnitÖÐÖØÔØµÄgetConnection£¨²»ÔÙÐèÒªÁË£¬¸¸ÀàDBTestCaseÖÐÒѾ­ÊµÏÖÁ˸÷½·¨¡££©È»ºóÖ´ÐУ¬ÎÒÃÇÓÖÓöµ½Ò»¸öÒì³££º

org.dbunit.AbstractDatabaseTester$AssertionFailedError:driverClass is null

ÕâÊÇÒòΪPropertiesBasedJdbcDatabaseTesterµÄinitialize·½·¨£¨¼ûÉÏÃæ´úÂ룩ÓÃÀ´³õʼ»¯Êý¾Ý¿âÁ¬½Ó²ÎÊý£º

protected void initialize() throwsException
{
logger.debug("initialize() - start");
setDriverClass(System.getProperty(DRIVER_CLASS));
setConnectionUrl(System.getProperty(CONNECTION_URL));
setUsername(System.getProperty(USERNAME));
setPassword(System.getProperty(PASSWORD));
// Èç¹ûËùÓòâÊÔÕÊ»§ÊÇ DBA£¬ÎªÁ˱ÜÃâ³öÏÖ AmbiguousTableNameException
// Òì³££¬±ØÐëÃ÷È·¸ø³ö SCHEMA¡£×¢Òâ SCHEMAÒª´óд**
// setSchema(System.getProperty(SCHEMA));
super.initialize();
}

´ÓÕâÀïÎÒÃÇ¿´µ½DBTestCaseÐèÒª´Óϵͳ±äÁ¿ÖлñµÃÁ¬½Ó²ÎÊý£¬ËùÒÔÎÒÃDZØÐëÐÞ¸ÄHelloDBUnitµÄ¹¹Ô캯Êý£¬½«ÅäÖòÎÊý¶ÁÈëϵͳ±äÁ¿£º

public HelloDBUnit() throws IOException
{
super();
props.load(Resources.getResourceAsStream("database.properties"));
if(null == context)
{
context = new ClassPathXmlApplicationContext(
"classpath:ApplicationContext.xml");
}
System.setProperty(
PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS,
props.getProperty("database.connection.driver_class"));
System.setProperty(
PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL,
props.getProperty("database.connection.url"));
System.setProperty(
PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME,
props.getProperty("database.connection.username"));
System.setProperty(
PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD,
props.getProperty("database.connection.password"));
}

ÏÖÔÚ¿ÉÒÔÕýÈ·Ö´ÐÐÁË¡£²»¹ý£¬ÕâÒÀÈ»´æÔÚÒź¶£¬¼ÈÈ»ÎÒÃÇʹËùÓÐÅäÖòÎÊý¶¼Îı¾»¯ÁË£¬¾Í²»Ï£Íû¿´µ½

 System.setProperty(
PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS,
props.getProperty("database.connection.driver_class"));

ÕâÑùµÄ´úÂ룬ÒòΪÈç¹ûÎÒÃÇÓжà¸öÊý¾ÝÔ´£¬»ò¸Ä±äÁËÅäÖÃÎļþ£¬ÎÒÃDz»µÃ²»»¹ÐèÒª¸Ä±ä²âÊÔÓÃÀýµÄ´úÂë¡£¿ÉÒÔÓÃDataSourceBasedDBTestCase À´½â¾öÕâ¸öÎÊÌâ¡£

DataSourceBasedDBTestCaseÀà DataSourceBasedDBTestCase ³éÏóÀàÒªÇó×ÓÀàʵÏÖ getDataSource ·½·¨ÒÔ»ñÈ¡ÍⲿÊý¾ÝÔ´¡£

Ê×ÏÈ£¬¸Ä±ä¸¸ÀàΪ DataSourceBasedDBTestCase ¡£È»ºóÒÆ³ý¹¹Ô캯ÊýÖйØÓÚϵͳ±äÁ¿µÄÉèÖá£×îºó¼ÓÈëÒÔÏ´úÂ룺

@Override
protected DataSource getDataSource(){
return(DataSource)context.getBean("dataSource");
}

org.dbunit.database.AmbiguousTableNameExceptionÒì³£

ºÜÒź¶£¬ DataSourceBasedDBTestCase ûÓÐÌṩÉèÖà SCHEMA µÄ·½·¨£¬ËäÈ»ËüµÄ³ÉÔ±±äÁ¿ DataSourceBasedDBTester ͨ¹ý¼Ì³ÐÁË AbstractDatabaseTester ¶øÌṩÁË setSchema ·½·¨£¬µ«ÊÇÒòΪËùÓÐµÄ IDatabaseTester ¶¼ÊÇ Private ±äÁ¿£¬Òò´Ëʵ¼ÊÉÏÎÒÃÇÎÞ·¨·ÃÎʵ½ËüµÄ setSchema¡£ËùÒÔÈç¹ûʹÓà DataSourceBasedDBTestCase £¬³ý·ÇÖØÔØ setUp ºÍtearDown·½·¨£¬·ñÔò¾Í²»ÄÜÓÐDBAȨÏÞ¡£

protected void setUp() throws Exception
{
DataSource dataSource = getDataSource();
Connection connection = dataSource.getConnection();
IDatabaseConnection dbUnitCon
= new DatabaseConnection(connection, "SYSTEM");
if(getDataSet() != null)
{
try
{
getSetUpOperation().execute(dbUnitCon, getDataSet());
}
finally
{
if(connection!= null)
connection.close();
}
}
}
protected void tearDown() throws Exception
{
DataSource dataSource = getDataSource();
Connection connection = dataSource.getConnection();
IDatabaseConnection dbUnitCon
= new DatabaseConnection(connection, "SYSTEM");
if(getDataSet()!= null)
{
try
{
getTearDownOperation().execute(dbUnitCon,getDataSet());
}
finally
{
if(connection!= null)
connection.close();
}
}
}

Ö§³ÖÊÂÎñ»Ø¹ö

ËäÈ»DBUnitÌṩÁËһЩ·½·¨ÈÃÎÒÃÇ¿ÉÒÔÔÚ²âÊÔ¿ªÊ¼ºÍ½áÊøÊ±ÇåÀíÊý¾Ý¿â£¬µ«ÊÇÓÐʱºòÒÀÈ»²»ÄÜÂú×ãÐèÇ󣬱ÈÈçÔÚÉÏÃæµÄ´úÂëÖУ¬ÎÒÃÇÔÚÖ´Ðн׶βåÈëÁËÒ»Ìõ¼Ç¼£¨¼ûtestCreateAccount·½·¨£©£¬ÕâÖÖ²»ÊÇÔÚÖÖ×ÓÎļþÖеĶîÍâÊý¾Ý£¬²âÊÔ½áÊøºó³ý·ÇÔÚtearDownÖзµ»ØDatabaseOperation.DELETE_ALL£¬·ñÔòÊDz»»á±»×Ô¶¯É¾³ýµÄ£¬¿ÉÊÇÈç¹ûɾ³ýÈ«²¿Êý¾Ý£¬ÄÇôÓÖÓпÉÄÜɾµôÁ˲»Ï£ÍûɾµôµÄÊý¾Ý¡£SpringÌṩÁËÒ»¸öAbstractTransactionalDataSourceSpringContextTests²âÊÔÀ࣬Õâ¸öÀà¿ÉÒÔÔÚ²âÊÔ½áÊøºó»Ø¹öÊý¾Ý¿â£¬¿ÉÊÇDBUnitûÓÐÌṩÀàËÆµÄ»úÖÆ£¬ËùÒÔÎÒÃÇÒª½øÒ»²½ÊÖ¹¤À©Õ¹²âÊÔÓÃÀý£¬ÒÔ¼ÓÈëÀàËÆ¹¦ÄÜ¡£

ÐÞ¸ÄApplicationContext.xml

Ê×ÏÈ£¬ÐÞ¸ÄSpringµÄÅäÖÃÎļþApplicationContext.xml£¬¼ÓÈëÒÔÏÂÅäÖãº

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

Èç¹ûÏ£ÍûÒµÎñÀàÒ²Ö§³ÖÊÂÎñ´¦Àí¿ÉÒÔ¼ÓÈëÒÔÏÂÅäÖ㬷ñÔò¿ÉÒÔÂÔ¹ý£º

<bean id="accountManagerTarget" class="com.wang.dbunit.AccountManager">
<property name="sqlMapClient" ref="sqlMapClient"/>
</bean>
<bean id="accountManager" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>
com.wang.dbunit.IAccountManager
</value>
</property>
<property name="interceptorNames">
<list>
<idref local="transactionInterceptor" />
<idref local="accountManagerTarget" />
</list>
</property>
</bean>

ÒÔÉÏÅäÖÃÖ»×÷ÓÃÓÚʹҵÎñÀ࣬ÒòΪÎÒÃǵIJâÊÔÓÃÀýÀà¡°HelloDBUnit.java¡±Ã»ÓгöÏÖÔÚÅäÖÃÎļþÖУ¬¸üûÓÐÉèÖÃÈκÎÀ¹½ØÆ÷£¬ËùÒÔ²âÊÔÓÃÀý¶ÔÊý¾Ý¿âµÄËùÓвÙ×÷£¨²åÈë¡¢Çå³ý²âÊÔÊý¾Ý£©Ä¿Ç°¶¼²»ÔÚÀ¹½Ø·¶Î§¡£ÎÒÃDZØÐëÔÚ²âÊÔÓÃÀýÖÐÊÖ¹¤ÎªËü¼ÓÈëÊÂÎñ´¦Àí£¬²Å¿ÉÒÔ´ïµ½ÎÒÃǵÄÄ¿µÄ¡£

Ìí¼ÓÊÂÎñ¹ÜÀí´úÂë

Ìí¼ÓÒÔÏÂÊôÐԺͷ½·¨£º

private TransactionStatus ts = null;
private DataSourceTransactionManager transactionManager = null;
......
protected void setUpTransaction()
{
transactionManager
=(DataSourceTransactionManager)context.getBean(
"transactionManager");
TransactionDefinition td = new DefaultTransactionDefinition();
ts = transactionManager.getTransaction(td);
}
protected void tearDownTransaction(boolean commit)
{
if(commit)
{
transactionManager.commit(ts);
}
else
{
transactionManager.rollback(ts);
}
}

ÐÞ¸ÄsetUpºÍtearDown·½·¨£º

protected void setUp() throws Exception
{
setUpTransaction();
DataSourced ataSource = getDataSource();
// Ìæ»» Connection connection = dataSource.getConnection();
Connection connection = DataSourceUtils.getConnection(dataSource);
IDatabaseConnection dbUnitCon
= new DatabaseConnection(connection, "SYSTEM");
if(getDataSet()!= null)
{
try
{
getSetUpOperation().execute(dbUnitCon, getDataSet());
}
finally
{
if(connection!= null)
{
// Ìæ»» connection.close();
DataSourceUtils.releaseConnection(
connection, dataSource);
}
}
}
}
protected void tearDown() throws Exception
{
DataSource dataSource = getDataSource();
// Ìæ»» Connection connection = dataSource.getConnection();
Connection connection = DataSourceUtils.getConnection(dataSource);
IDatabaseConnection dbUnitCon
= new DatabaseConnection(connection, "SYSTEM");
if(getDataSet() != null)
{
try
{
// Èç¹û²»Ï£Íû»Ø¹öÊý¾Ý£¬´«Èë true ²ÎÊý¡£
tearDownTransaction(false);
getTearDownOperation().execute(dbUnitCon, getDataSet());
}
finally
{
if(connection!= null)
{
// Ìæ»» connection.close();
DataSourceUtils.releaseConnection(
connection, dataSource);
}
}
}
}

×îºóÐÞ¸ÄgetTearDownOperation£¬Óà DELETE Ìæ»» DELETE_ALL£º

protected DatabaseOperation getTearDownOperation() throws Exception
{
return DatabaseOperation.DELETE;
}

ÏÖÔÚÔÚ±íÖÐËæ±ãÌí¼ÓһЩ¼Ç¼£¬È»ºóÖ´ÐÐÎÒÃǵIJâÊÔÓÃÀý£¬Ö´ÐÐÍêºó£¬ÊÖ¹¤Ìí¼ÓµÄÊý¾ÝûÓÐÊܵ½ÈκÎÓ°Ïì¡£

×îºóÒ»µãÌáʾ:

ÒòΪÿһ¸ö testXxx ·½·¨Ê±¶¼»á³õʼ»¯Ò»¸ö²âÊÔÓÃÀý£¬ËùÒÔÿִÐÐÒ»´Î testXxxx ·½·¨¶¼»áµ¼Ö setUp ºÍ tearDown ·½·¨±»µ÷ÓÃÒ»´Î£¬¶ø±¾ÀýµÄÊÂÎñ¶¨ÒåÒ²¶¼ÓÉ setUp ¿ªÊ¼£¬ tearDown ½áÊø£¬Ò²¾ÍÒâζ×Ų»Í¬²âÊÔ·½·¨£¨Í¬Ò»²âÊÔÓÃÀý£©Ö®¼ä´¦ÓÚ²»Í¬µÄÊÂÎñ·¶Î§£¬µ¼ÖÂÊý¾Ý²Ù×÷½á¹ûÎÞ·¨¹²Ïí£¨Èç¹ûÿ´Î tearDown ¶¼»Ø¹öÊý¾Ý£©¡£±ÈÈçÔÚ testInsert ·½·¨ÖвåÈëÊý¾Ý£¬ÔÚ testSelect ÎÞ·¨»ñµÃ¡£Òª½â¾öÕâ¸öÎÊÌ⣬¾ÍÒªÊʵ±µÄÐÞ¸Ä¶Ô setUpTransaction ºÍ dearDownTransaction µÄµ÷Óã¬Ê¹µÃÊÂÎñ¿ÉÒÔÔÚÈ«¾Ö·¶Î§ÄÚ±»¶à¸ö test ·½·¨¹²Ïí¡£

E:\work\bpm2_v1_00\test.xml:171: org.dbunit.dataset.NoSuchTableException: VERSION_INFO

DBunit ÒªÇóschema ´óд

   
3862 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

΢·þÎñ²âÊÔÖ®µ¥Ôª²âÊÔ
һƪͼÎÄ´øÄãÁ˽â°×ºÐ²âÊÔÓÃÀýÉè¼Æ·½·¨
È«ÃæµÄÖÊÁ¿±£ÕÏÌåϵ֮»Ø¹é²âÊÔ²ßÂÔ
È˹¤ÖÇÄÜ×Ô¶¯»¯²âÊÔ̽Ë÷
Ïà¹ØÎĵµ

×Ô¶¯»¯½Ó¿Ú²âÊÔʵ¼ù֮·
jenkins³ÖÐø¼¯³É²âÊÔ
ÐÔÄܲâÊÔÕï¶Ï·ÖÎöÓëÓÅ»¯
ÐÔÄܲâÊÔʵÀý
Ïà¹Ø¿Î³Ì

³ÖÐø¼¯³É²âÊÔ×î¼Ñʵ¼ù
×Ô¶¯»¯²âÊÔÌåϵ½¨ÉèÓë×î¼Ñʵ¼ù
²âÊԼܹ¹µÄ¹¹½¨ÓëÓ¦ÓÃʵ¼ù
DevOpsʱ´úµÄ²âÊÔ¼¼ÊõÓë×î¼Ñʵ¼ù
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

LoadRunnerÐÔÄܲâÊÔ»ù´¡
Èí¼þ²âÊÔ½á¹û·ÖÎöºÍÖÊÁ¿±¨¸æ
ÃæÏò¶ÔÏóÈí¼þ²âÊÔ¼¼ÊõÑо¿
Éè¼Æ²âÊÔÓÃÀýµÄËÄÌõÔ­Ôò
¹¦ÄܲâÊÔÖйÊÕÏÄ£Ð͵Ľ¨Á¢
ÐÔÄܲâÊÔ×ÛÊö

ÐÔÄܲâÊÔ·½·¨Óë¼¼Êõ
²âÊÔ¹ý³ÌÓëÍŶӹÜÀí
LoadRunner½øÐÐÐÔÄܲâÊÔ
WEBÓ¦ÓõÄÈí¼þ²âÊÔ
ÊÖ»úÈí¼þ²âÊÔ
°×ºÐ²âÊÔ·½·¨Óë¼¼Êõ

ij²©²ÊÐÐÒµ Êý¾Ý¿â×Ô¶¯»¯²âÊÔ
IT·þÎñÉÌ Web°²È«²âÊÔ
IT·þÎñÉÌ ×Ô¶¯»¯²âÊÔ¿ò¼Ü
º£º½¹É·Ý µ¥Ôª²âÊÔ¡¢Öع¹
²âÊÔÐèÇó·ÖÎöÓë²âÊÔÓÃÀý·ÖÎö
»¥ÁªÍøweb²âÊÔ·½·¨Óëʵ¼ù
»ùÓÚSeleniumµÄWeb×Ô¶¯»¯²âÊÔ