下面列出了怎么用org.springframework.test.context.jdbc.SqlConfig.TransactionMode的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Construct a {@code MergedSqlConfig} instance by merging the configuration
* from the supplied local (potentially method-level) {@code @SqlConfig} annotation
* with class-level configuration discovered on the supplied {@code testClass}.
* <p>Local configuration overrides class-level configuration.
* <p>If the test class is not annotated with {@code @SqlConfig}, no merging
* takes place and the local configuration is used "as is".
*/
MergedSqlConfig(SqlConfig localSqlConfig, Class<?> testClass) {
Assert.notNull(localSqlConfig, "Local @SqlConfig must not be null");
Assert.notNull(testClass, "testClass must not be null");
// Get global attributes, if any.
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
testClass, SqlConfig.class.getName(), false, false);
// Override global attributes with local attributes.
if (attributes != null) {
for (String key : attributes.keySet()) {
Object value = AnnotationUtils.getValue(localSqlConfig, key);
if (value != null) {
// Is the value explicit (i.e., not a 'default')?
if (!value.equals("") && value != TransactionMode.DEFAULT && value != ErrorMode.DEFAULT) {
attributes.put(key, value);
}
}
}
}
else {
// Otherwise, use local attributes only.
attributes = AnnotationUtils.getAnnotationAttributes(localSqlConfig, false, false);
}
this.dataSource = attributes.getString("dataSource");
this.transactionManager = attributes.getString("transactionManager");
this.transactionMode = getEnum(attributes, "transactionMode", TransactionMode.DEFAULT, TransactionMode.INFERRED);
this.encoding = attributes.getString("encoding");
this.separator = getString(attributes, "separator", ScriptUtils.DEFAULT_STATEMENT_SEPARATOR);
this.commentPrefix = getString(attributes, "commentPrefix", ScriptUtils.DEFAULT_COMMENT_PREFIX);
this.blockCommentStartDelimiter = getString(attributes, "blockCommentStartDelimiter",
ScriptUtils.DEFAULT_BLOCK_COMMENT_START_DELIMITER);
this.blockCommentEndDelimiter = getString(attributes, "blockCommentEndDelimiter",
ScriptUtils.DEFAULT_BLOCK_COMMENT_END_DELIMITER);
this.errorMode = getEnum(attributes, "errorMode", ErrorMode.DEFAULT, ErrorMode.FAIL_ON_ERROR);
}
/**
* Construct a {@code MergedSqlConfig} instance by merging the configuration
* from the supplied local (potentially method-level) {@code @SqlConfig} annotation
* with class-level configuration discovered on the supplied {@code testClass}.
* <p>Local configuration overrides class-level configuration.
* <p>If the test class is not annotated with {@code @SqlConfig}, no merging
* takes place and the local configuration is used "as is".
*/
MergedSqlConfig(SqlConfig localSqlConfig, Class<?> testClass) {
Assert.notNull(localSqlConfig, "Local @SqlConfig must not be null");
Assert.notNull(testClass, "testClass must not be null");
// Get global attributes, if any.
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
testClass, SqlConfig.class.getName(), false, false);
// Override global attributes with local attributes.
if (attributes != null) {
for (String key : attributes.keySet()) {
Object value = AnnotationUtils.getValue(localSqlConfig, key);
if (value != null) {
// Is the value explicit (i.e., not a 'default')?
if (!value.equals("") && value != TransactionMode.DEFAULT && value != ErrorMode.DEFAULT) {
attributes.put(key, value);
}
}
}
}
else {
// Otherwise, use local attributes only.
attributes = AnnotationUtils.getAnnotationAttributes(localSqlConfig, false, false);
}
this.dataSource = attributes.getString("dataSource");
this.transactionManager = attributes.getString("transactionManager");
this.transactionMode = getEnum(attributes, "transactionMode", TransactionMode.DEFAULT, TransactionMode.INFERRED);
this.encoding = attributes.getString("encoding");
this.separator = getString(attributes, "separator", ScriptUtils.DEFAULT_STATEMENT_SEPARATOR);
this.commentPrefix = getString(attributes, "commentPrefix", ScriptUtils.DEFAULT_COMMENT_PREFIX);
this.blockCommentStartDelimiter = getString(attributes, "blockCommentStartDelimiter",
ScriptUtils.DEFAULT_BLOCK_COMMENT_START_DELIMITER);
this.blockCommentEndDelimiter = getString(attributes, "blockCommentEndDelimiter",
ScriptUtils.DEFAULT_BLOCK_COMMENT_END_DELIMITER);
this.errorMode = getEnum(attributes, "errorMode", ErrorMode.DEFAULT, ErrorMode.FAIL_ON_ERROR);
}
/**
* Construct a {@code MergedSqlConfig} instance by merging the configuration
* from the supplied local (potentially method-level) {@code @SqlConfig} annotation
* with class-level configuration discovered on the supplied {@code testClass}.
* <p>Local configuration overrides class-level configuration.
* <p>If the test class is not annotated with {@code @SqlConfig}, no merging
* takes place and the local configuration is used "as is".
*/
MergedSqlConfig(SqlConfig localSqlConfig, Class<?> testClass) {
Assert.notNull(localSqlConfig, "Local @SqlConfig must not be null");
Assert.notNull(testClass, "testClass must not be null");
// Get global attributes, if any.
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(testClass,
SqlConfig.class.getName(), false, false);
// Override global attributes with local attributes.
if (attributes != null) {
for (String key : attributes.keySet()) {
Object value = AnnotationUtils.getValue(localSqlConfig, key);
if (value != null) {
// Is the value explicit (i.e., not a 'default')?
if (!value.equals("") && (value != TransactionMode.DEFAULT) && (value != ErrorMode.DEFAULT)) {
attributes.put(key, value);
}
}
}
}
else {
// Otherwise, use local attributes only.
attributes = AnnotationUtils.getAnnotationAttributes(localSqlConfig, false, false);
}
this.dataSource = attributes.getString("dataSource");
this.transactionManager = attributes.getString("transactionManager");
this.transactionMode = getEnum(attributes, "transactionMode", TransactionMode.DEFAULT, TransactionMode.INFERRED);
this.encoding = attributes.getString("encoding");
this.separator = getString(attributes, "separator", ScriptUtils.DEFAULT_STATEMENT_SEPARATOR);
this.commentPrefix = getString(attributes, "commentPrefix", ScriptUtils.DEFAULT_COMMENT_PREFIX);
this.blockCommentStartDelimiter = getString(attributes, "blockCommentStartDelimiter",
ScriptUtils.DEFAULT_BLOCK_COMMENT_START_DELIMITER);
this.blockCommentEndDelimiter = getString(attributes, "blockCommentEndDelimiter",
ScriptUtils.DEFAULT_BLOCK_COMMENT_END_DELIMITER);
this.errorMode = getEnum(attributes, "errorMode", ErrorMode.DEFAULT, ErrorMode.FAIL_ON_ERROR);
}
/**
* Execute the SQL scripts configured via the supplied {@link Sql @Sql}
* annotation for the given {@link ExecutionPhase} and {@link TestContext}.
* <p>Special care must be taken in order to properly support the configured
* {@link SqlConfig#transactionMode}.
* @param sql the {@code @Sql} annotation to parse
* @param executionPhase the current execution phase
* @param testContext the current {@code TestContext}
* @param classLevel {@code true} if {@link Sql @Sql} was declared at the class level
*/
private void executeSqlScripts(Sql sql, ExecutionPhase executionPhase, TestContext testContext, boolean classLevel)
throws Exception {
if (executionPhase != sql.executionPhase()) {
return;
}
MergedSqlConfig mergedSqlConfig = new MergedSqlConfig(sql.config(), testContext.getTestClass());
if (logger.isDebugEnabled()) {
logger.debug(String.format("Processing %s for execution phase [%s] and test context %s.",
mergedSqlConfig, executionPhase, testContext));
}
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.setSqlScriptEncoding(mergedSqlConfig.getEncoding());
populator.setSeparator(mergedSqlConfig.getSeparator());
populator.setCommentPrefix(mergedSqlConfig.getCommentPrefix());
populator.setBlockCommentStartDelimiter(mergedSqlConfig.getBlockCommentStartDelimiter());
populator.setBlockCommentEndDelimiter(mergedSqlConfig.getBlockCommentEndDelimiter());
populator.setContinueOnError(mergedSqlConfig.getErrorMode() == ErrorMode.CONTINUE_ON_ERROR);
populator.setIgnoreFailedDrops(mergedSqlConfig.getErrorMode() == ErrorMode.IGNORE_FAILED_DROPS);
String[] scripts = getScripts(sql, testContext, classLevel);
scripts = TestContextResourceUtils.convertToClasspathResourcePaths(testContext.getTestClass(), scripts);
List<Resource> scriptResources = TestContextResourceUtils.convertToResourceList(
testContext.getApplicationContext(), scripts);
for (String stmt : sql.statements()) {
if (StringUtils.hasText(stmt)) {
stmt = stmt.trim();
scriptResources.add(new ByteArrayResource(stmt.getBytes(), "from inlined SQL statement: " + stmt));
}
}
populator.setScripts(scriptResources.toArray(new Resource[0]));
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL scripts: " + ObjectUtils.nullSafeToString(scriptResources));
}
String dsName = mergedSqlConfig.getDataSource();
String tmName = mergedSqlConfig.getTransactionManager();
DataSource dataSource = TestContextTransactionUtils.retrieveDataSource(testContext, dsName);
PlatformTransactionManager txMgr = TestContextTransactionUtils.retrieveTransactionManager(testContext, tmName);
boolean newTxRequired = (mergedSqlConfig.getTransactionMode() == TransactionMode.ISOLATED);
if (txMgr == null) {
Assert.state(!newTxRequired, () -> String.format("Failed to execute SQL scripts for test context %s: " +
"cannot execute SQL scripts using Transaction Mode " +
"[%s] without a PlatformTransactionManager.", testContext, TransactionMode.ISOLATED));
Assert.state(dataSource != null, () -> String.format("Failed to execute SQL scripts for test context %s: " +
"supply at least a DataSource or PlatformTransactionManager.", testContext));
// Execute scripts directly against the DataSource
populator.execute(dataSource);
}
else {
DataSource dataSourceFromTxMgr = getDataSourceFromTransactionManager(txMgr);
// Ensure user configured an appropriate DataSource/TransactionManager pair.
if (dataSource != null && dataSourceFromTxMgr != null && !dataSource.equals(dataSourceFromTxMgr)) {
throw new IllegalStateException(String.format("Failed to execute SQL scripts for test context %s: " +
"the configured DataSource [%s] (named '%s') is not the one associated with " +
"transaction manager [%s] (named '%s').", testContext, dataSource.getClass().getName(),
dsName, txMgr.getClass().getName(), tmName));
}
if (dataSource == null) {
dataSource = dataSourceFromTxMgr;
Assert.state(dataSource != null, () -> String.format("Failed to execute SQL scripts for " +
"test context %s: could not obtain DataSource from transaction manager [%s] (named '%s').",
testContext, txMgr.getClass().getName(), tmName));
}
final DataSource finalDataSource = dataSource;
int propagation = (newTxRequired ? TransactionDefinition.PROPAGATION_REQUIRES_NEW :
TransactionDefinition.PROPAGATION_REQUIRED);
TransactionAttribute txAttr = TestContextTransactionUtils.createDelegatingTransactionAttribute(
testContext, new DefaultTransactionAttribute(propagation));
new TransactionTemplate(txMgr, txAttr).execute(status -> {
populator.execute(finalDataSource);
return null;
});
}
}
/**
* @see SqlConfig#transactionMode()
*/
TransactionMode getTransactionMode() {
return this.transactionMode;
}
@Test
@SqlGroup(@Sql(scripts = "data-add-dogbert.sql", config = @SqlConfig(transactionMode = TransactionMode.ISOLATED)))
public void methodLevelScripts() {
assertNumUsers(1);
}
@Sql(scripts = "foo.sql", config = @SqlConfig(transactionMode = TransactionMode.ISOLATED))
public void foo() {
}
/**
* Execute the SQL scripts configured via the supplied {@link Sql @Sql}
* annotation for the given {@link ExecutionPhase} and {@link TestContext}.
* <p>Special care must be taken in order to properly support the configured
* {@link SqlConfig#transactionMode}.
* @param sql the {@code @Sql} annotation to parse
* @param executionPhase the current execution phase
* @param testContext the current {@code TestContext}
* @param classLevel {@code true} if {@link Sql @Sql} was declared at the class level
*/
private void executeSqlScripts(Sql sql, ExecutionPhase executionPhase, TestContext testContext, boolean classLevel)
throws Exception {
if (executionPhase != sql.executionPhase()) {
return;
}
MergedSqlConfig mergedSqlConfig = new MergedSqlConfig(sql.config(), testContext.getTestClass());
if (logger.isDebugEnabled()) {
logger.debug(String.format("Processing %s for execution phase [%s] and test context %s.",
mergedSqlConfig, executionPhase, testContext));
}
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.setSqlScriptEncoding(mergedSqlConfig.getEncoding());
populator.setSeparator(mergedSqlConfig.getSeparator());
populator.setCommentPrefix(mergedSqlConfig.getCommentPrefix());
populator.setBlockCommentStartDelimiter(mergedSqlConfig.getBlockCommentStartDelimiter());
populator.setBlockCommentEndDelimiter(mergedSqlConfig.getBlockCommentEndDelimiter());
populator.setContinueOnError(mergedSqlConfig.getErrorMode() == ErrorMode.CONTINUE_ON_ERROR);
populator.setIgnoreFailedDrops(mergedSqlConfig.getErrorMode() == ErrorMode.IGNORE_FAILED_DROPS);
String[] scripts = getScripts(sql, testContext, classLevel);
scripts = TestContextResourceUtils.convertToClasspathResourcePaths(testContext.getTestClass(), scripts);
List<Resource> scriptResources = TestContextResourceUtils.convertToResourceList(
testContext.getApplicationContext(), scripts);
for (String stmt : sql.statements()) {
if (StringUtils.hasText(stmt)) {
stmt = stmt.trim();
scriptResources.add(new ByteArrayResource(stmt.getBytes(), "from inlined SQL statement: " + stmt));
}
}
populator.setScripts(scriptResources.toArray(new Resource[0]));
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL scripts: " + ObjectUtils.nullSafeToString(scriptResources));
}
String dsName = mergedSqlConfig.getDataSource();
String tmName = mergedSqlConfig.getTransactionManager();
DataSource dataSource = TestContextTransactionUtils.retrieveDataSource(testContext, dsName);
PlatformTransactionManager txMgr = TestContextTransactionUtils.retrieveTransactionManager(testContext, tmName);
boolean newTxRequired = (mergedSqlConfig.getTransactionMode() == TransactionMode.ISOLATED);
if (txMgr == null) {
Assert.state(!newTxRequired, () -> String.format("Failed to execute SQL scripts for test context %s: " +
"cannot execute SQL scripts using Transaction Mode " +
"[%s] without a PlatformTransactionManager.", testContext, TransactionMode.ISOLATED));
Assert.state(dataSource != null, () -> String.format("Failed to execute SQL scripts for test context %s: " +
"supply at least a DataSource or PlatformTransactionManager.", testContext));
// Execute scripts directly against the DataSource
populator.execute(dataSource);
}
else {
DataSource dataSourceFromTxMgr = getDataSourceFromTransactionManager(txMgr);
// Ensure user configured an appropriate DataSource/TransactionManager pair.
if (dataSource != null && dataSourceFromTxMgr != null && !dataSource.equals(dataSourceFromTxMgr)) {
throw new IllegalStateException(String.format("Failed to execute SQL scripts for test context %s: " +
"the configured DataSource [%s] (named '%s') is not the one associated with " +
"transaction manager [%s] (named '%s').", testContext, dataSource.getClass().getName(),
dsName, txMgr.getClass().getName(), tmName));
}
if (dataSource == null) {
dataSource = dataSourceFromTxMgr;
Assert.state(dataSource != null, () -> String.format("Failed to execute SQL scripts for " +
"test context %s: could not obtain DataSource from transaction manager [%s] (named '%s').",
testContext, txMgr.getClass().getName(), tmName));
}
final DataSource finalDataSource = dataSource;
int propagation = (newTxRequired ? TransactionDefinition.PROPAGATION_REQUIRES_NEW :
TransactionDefinition.PROPAGATION_REQUIRED);
TransactionAttribute txAttr = TestContextTransactionUtils.createDelegatingTransactionAttribute(
testContext, new DefaultTransactionAttribute(propagation));
new TransactionTemplate(txMgr, txAttr).execute(status -> {
populator.execute(finalDataSource);
return null;
});
}
}
/**
* @see SqlConfig#transactionMode()
*/
TransactionMode getTransactionMode() {
return this.transactionMode;
}
@Test
@SqlGroup(@Sql(scripts = "data-add-dogbert.sql", config = @SqlConfig(transactionMode = TransactionMode.ISOLATED)))
public void methodLevelScripts() {
assertNumUsers(1);
}
@Sql(scripts = "foo.sql", config = @SqlConfig(transactionMode = TransactionMode.ISOLATED))
public void foo() {
}
/**
* @see SqlConfig#transactionMode()
*/
TransactionMode getTransactionMode() {
return this.transactionMode;
}
@Sql(scripts = "foo.sql", config = @SqlConfig(transactionMode = TransactionMode.ISOLATED))
public void foo() {
}
@Test
@SqlGroup(@Sql(scripts = "data-add-dogbert.sql", config = @SqlConfig(transactionMode = TransactionMode.ISOLATED)))
public void methodLevelScripts() {
assertNumUsers(1);
}
@Test
@Sql(scripts = {"/import_senior_employees.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = TransactionMode.ISOLATED))
public void testLoadDataForTestCase() {
assertEquals(5, employeeRepository.findAll()
.size());
}