J'ai eu l'occasion de tester autour de DB dans l'environnement Spring + Mybatis et j'ai étudié comment utiliser DbUnit. (Je le posterai pour ne pas l'oublier) Étant donné que les transactions sont gérées du côté Spring, certains paramètres sont requis pour la liaison avec DbUnit.
MW | Version |
---|---|
Java | 7 |
postgresql | 9.5 |
spring-core | 4.3.7.RELEASE |
mybatis | 3.4.2 |
mybatis-spring | 1.3.1 |
spring-jdbc | 4.3.7.RELEASE |
spring-test | 4.3.7.RELEASE |
dbunit | 2.5.3 |
spring-context | 4.3.7.RELEASE |
postgresql(jdbc Driver) | 42.0.0.jre7 |
Pour lier spring et DbUnit, ajoutez la définition suivante au fichier de définition des beans de spring. DbUnit et spring semblent gérer les transactions de l'autre, comme indiqué ci-dessous Si vous n'encapsulez pas le dataSource dans la classe TransactionAwareDataSourceProxy, l'ensemble de données dans DbUnit ne sera pas restauré.
applicationContext.xml
<!--Paramètres de la source de données(référence) -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/<Nom de la base de données>" />
<property name="username" value="<Dépend de l'environnement>" />
<property name="password" value="<Dépend de l'environnement>" />
</bean>
<!--Lorsque vous utilisez dbunit avec spring, enveloppez la source de données comme suit-->
<bean id="dataSourceTest"
class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
<constructor-arg ref="dataSource" />
</bean>
À propos de la configuration de la source de test de Junit.
Les annotations telles que @RunWith ont les mêmes paramètres que lors de l'utilisation de spring. La classe hérite de DataSourceBasedDBTestCase pour utiliser DbUnit.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
@Transactional
public class DocumentMapperTest extends DataSourceBasedDBTestCase {
Lors de l'héritage de la classe Mapper à tester et de DataSourceBasedDBTestCase, définissez dataSourceTest sur DI by @Autowired pour être utilisé comme valeur de retour de getDataSource () qui doit être implémentée.
@Autowired
DocumentMapper mapper;
@Autowired
DataSource dataSourceTest;
@Rule
public TestName name = new TestName();
Si vous appelez super.setUp () dans @Before, il sera configuré avant le test.
@Before
public void setUp() throws Exception {
// super.setUp()DB peut être configuré avant l'exécution du test en appelant.
// setUp()Si vous n'appelez pas avec, la configuration est requise dans la méthode de test
// super.setUp();
}
Comme mentionné dans la phrase précédente, c'est getDataSource () qui doit être implémenté en héritant de la classe DataSourceBasedDBTestCase. Ici, le dataSourceTest défini par @Autowired est retourné.
@Override
protected DataSource getDataSource() {
return this.dataSourceTest;
}
GetDataSet () qui doit être implémenté dans l'héritage de la classe DataSourceBasedDBTestCase. L'ensemble de données dans le DB sera renvoyé ici. getDataSet () est appelé dans super.setUp (). Ici, le fichier Excel (format xls) qui correspond au nom de la méthode de test est transmis en tant que données DB à partir du chemin de classe. Si vous écrivez null dans le fichier Excel, il sera traité comme une chaîne de caractères au lieu de null, il est donc remplacé par null à l'aide de la classe ReplacementDataSet fournie par DbUnit (la partie qui est nulle dans le fichier Excel est définie par [null]). .. Dans le dernier DbUnit, non seulement le format xls mais aussi le format xlsx peuvent être utilisés.
@Override
protected IDataSet getDataSet() throws Exception {
String pathName = name.getMethodName();
String xlsname = pathName + ".xls";
InputStream is = getClass().getClassLoader().getResourceAsStream(xlsname);
XlsDataSet dataSet = new XlsDataSet(is);
ReplacementDataSet replacement = new ReplacementDataSet(dataSet);
// [null]Remplacé par null
replacement.addReplacementObject("[null]", null);
// [systemtime]Remplacer par la date et l'heure actuelles
replacement.addReplacementObject("[systemtime]", toDateTimeStr(nowTime));
return replacement;
}
Avec les paramètres ci-dessus, vous pourrez tester avec Spring + Mybatis + DbUnit. En fait, il existe déjà une unité de base de données Spring Test, il est donc préférable de l'utiliser sans perdre d'efforts.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sample</groupId>
<artifactId>SpringMybatisDbUnit</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.dbunit/dbunit -->
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>2.5.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.0.0.jre7</version>
</dependency>
</dependencies>
</project>
Document.java
package mng.doc.dao;
import java.lang.reflect.Field;
import java.util.Date;
public class Document {
private Integer id;
private String name;
private String registrant;
private Date registrationtime;
private String editor;
private Date edittime;
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public String getRegistrant() {
return registrant;
}
public String getEditor() {
return editor;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setRegistrant(String registrant) {
this.registrant = registrant;
}
public void setEditor(String editor) {
this.editor = editor;
}
public Date getRegistrationtime() {
return registrationtime;
}
public Date getEdittime() {
return edittime;
}
public void setRegistrationtime(Date registrationtime) {
this.registrationtime = registrationtime;
}
public void setEdittime(Date edittime) {
this.edittime = edittime;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Document [");
Field[] fields = this.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
String name = field.getName();
field.setAccessible(true);
Object value = null;
try {
value = field.get(this);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
sb.append(name + " = " + value);
if (i != (fields.length - 1)) {
sb.append(", ");
}
}
sb.append("]");
return sb.toString();
}
}
DucumentMapper.java
package mng.doc.mapper;
import java.util.Date;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import mng.doc.dao.Document;
public interface DocumentMapper {
public List<Document> selectAll();
public Integer insertDocument(Document doc);
public Integer updateDocument(@Param("editor") String editor, @Param("edittime") Date edittime);
public Integer deleteDocument(Integer id);
}
DocumentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mng.doc.mapper.DocumentMapper">
<resultMap id="baseMap" type="mng.doc.dao.Document">
<id property="id" jdbcType="INTEGER" column="id" />
<result property="name" jdbcType="VARCHAR" column="name" />
<result property="registrant" jdbcType="VARCHAR" column="registrant" />
<result property="registrationtime" jdbcType="TIMESTAMP" column="registration_time" />
<result property="editor" jdbcType="VARCHAR" column="editor" />
<result property="edittime" jdbcType="TIMESTAMP" column="edit_time" />
</resultMap>
<select id="selectAll" resultMap="baseMap">
SELECT
*
FROM
DOCUMENT
</select>
<insert id="insertDocument" parameterType="mng.doc.dao.Document">
INSERT INTO
DOCUMENT
(name, registrant, registration_time)
VALUES
(
#{name},
#{registrant},
#{registrationtime}
)
</insert>
<update id="updateDocument">
UPDATE
DOCUMENT
SET
editor = #{editor},
edit_time = ${edittime}
</update>
<delete id="deleteDocument" parameterType="java.lang.Integer">
DELETE
FROM
DOCUMENT
WHERE
id = #{id}
</delete>
</mapper>
DocumentMapperTest.java
package mng.doc.mapper;
import static org.junit.Assert.*;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.sql.DataSource;
import mng.doc.dao.Document;
import org.dbunit.DataSourceBasedDBTestCase;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ReplacementDataSet;
import org.dbunit.dataset.excel.XlsDataSet;
import org.dbunit.operation.DatabaseOperation;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
@Transactional
public class DocumentMapperTest extends DataSourceBasedDBTestCase {
Long nowTime = System.currentTimeMillis();
@Autowired
DocumentMapper mapper;
@Autowired
DataSource dataSourceTest;
@Rule
public TestName name = new TestName();
@Test
public void testSelectAll() throws Exception {
prepare();
List<Document> documents = this.mapper.selectAll();
for (Document c : documents) {
System.out.println(c.toString());
}
}
@Before
public void setUp() throws Exception {
// super.setUp()La base de données peut être configurée avant l'exécution du test en appelant.
// setUp()Si vous n'appelez pas avec, la configuration est requise dans la méthode de test
// super.setUp();
}
public void prepare() throws Exception {
DatabaseConnection connection = new DatabaseConnection(this.dataSourceTest.getConnection());
DatabaseOperation.CLEAN_INSERT.execute(connection, getDataSet());
}
public void resetSequenceName(String sequenceName) throws Exception {
DatabaseConnection connection = new DatabaseConnection(this.dataSourceTest.getConnection());
connection
.getConnection()
.createStatement()
.executeQuery("select setval('" + sequenceName + "', 1, false)");
}
@Override
protected DataSource getDataSource() {
return this.dataSourceTest;
}
@Override
protected IDataSet getDataSet() throws Exception {
String pathName = name.getMethodName();
String xlsname = pathName + ".xls";
InputStream is = getClass().getClassLoader().getResourceAsStream(xlsname);
XlsDataSet dataSet = new XlsDataSet(is);
ReplacementDataSet replacement = new ReplacementDataSet(dataSet);
// [null]Remplacé par null
replacement.addReplacementObject("[null]", null);
// [systemtime]Remplacer par la date et l'heure actuelles
replacement.addReplacementObject("[systemtime]", toDateTimeStr(nowTime));
return replacement;
}
private String toDateTimeStr(Long time) {
return toDateTimeStr(new Date(time));
}
private String toDateTimeStr(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
String result = sdf.format(date);
System.out.println(result);
return result;
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd">
<!--Paramètres de la source de données-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/<Nom de la base de données>" />
<property name="username" value="<Dépend de l'environnement>" />
<property name="password" value="<Dépend de l'environnement>" />
</bean>
<!--Paramètres du gestionnaire de transactions-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!--Paramètres de SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
<!--Enregistrement de l'interface du mappeur-->
<bean id="sampleMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="mng.doc.mapper.DocumentMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<bean id="dataSourceTest"
class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
<constructor-arg ref="dataSource" />
</bean>
</beans>
document.sql
-- Table: public.document
-- DROP TABLE public.document;
CREATE TABLE public.document
(
id integer NOT NULL DEFAULT nextval('document_id_seq'::regclass),
name text NOT NULL,
registrant character varying(50),
registration_time timestamp without time zone,
editor character varying(50),
edit_time timestamp without time zone,
CONSTRAINT document_pkey PRIMARY KEY (id, name)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.document
OWNER TO postgres;