/*
* Copyright 2010 The myBatis Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mybatis.spring;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.fail;
import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.junit.After;
import org.junit.Test;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.TransientDataAccessResourceException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import com.mockrunner.mock.jdbc.MockDataSource;
import com.mockrunner.mock.jdbc.MockPreparedStatement;
/**
* @version $Id$
*/
public final class MyBatisSpringTest extends AbstractMyBatisSpringTest {
private SqlSession session;
@After
public void validateSessionClose() {
// assume if the Executor is closed, the Session is too
if ((session != null) && !executorInterceptor.isExecutorClosed()) {
session = null;
fail("SqlSession is not closed");
} else {
session = null;
}
}
// ensure MyBatis API still works with SpringManagedTransaction
@Test
public void testMyBatisAPI() {
session = sqlSessionFactory.openSession();
session.getMapper(TestMapper.class).findTest();
session.close();
assertNoCommit();
assertSingleConnection();
assertExecuteCount(1);
}
@Test
public void testMyBatisAPIWithCommit() {
session = sqlSessionFactory.openSession();
session.getMapper(TestMapper.class).findTest();
session.commit(true);
session.close();
assertCommit();
assertSingleConnection();
assertExecuteCount(1);
}
@Test
public void testMyBatisAPIWithRollback() {
session = sqlSessionFactory.openSession();
session.getMapper(TestMapper.class).findTest();
session.rollback(true);
session.close();
assertRollback();
assertSingleConnection();
assertExecuteCount(1);
}
// basic tests using SqlSessionUtils instead of using the MyBatis API directly
@Test
public void testSpringAPI() {
session = SqlSessionUtils.getSqlSession(sqlSessionFactory);
session.getMapper(TestMapper.class).findTest();
SqlSessionUtils.closeSqlSession(session, sqlSessionFactory);
assertNoCommit();
assertSingleConnection();
assertExecuteCount(1);
}
@Test
public void testSpringAPIWithCommit() {
session = SqlSessionUtils.getSqlSession(sqlSessionFactory);
session.getMapper(TestMapper.class).findTest();
session.commit(true);
SqlSessionUtils.closeSqlSession(session, sqlSessionFactory);
assertCommit();
assertSingleConnection();
}
@Test
public void testSpringAPIWithRollback() {
session = SqlSessionUtils.getSqlSession(sqlSessionFactory);
session.getMapper(TestMapper.class).findTest();
session.rollback(true);
SqlSessionUtils.closeSqlSession(session, sqlSessionFactory);
assertRollback();
assertSingleConnection();
}
@Test
public void testSpringAPIWithMyBatisClose() {
// This is a programming error and could lead to connection leak if there is a transaction
// in progress. But, the API allows it, so make sure it at least works without a tx.
session = SqlSessionUtils.getSqlSession(sqlSessionFactory);
session.getMapper(TestMapper.class).findTest();
session.close();
assertNoCommit();
assertSingleConnection();
}
// Spring API should work with a MyBatis TransactionFactories, as long as there is not a Spring
// TX is progress
@Test
public void testWithNonSpringTransactionFactory() {
Environment original = sqlSessionFactory.getConfiguration().getEnvironment();
Environment nonSpring = new Environment("non-spring", new JdbcTransactionFactory(), dataSource);
sqlSessionFactory.getConfiguration().setEnvironment(nonSpring);
try {
session = SqlSessionUtils.getSqlSession(sqlSessionFactory);
session.getMapper(TestMapper.class).findTest();
SqlSessionUtils.closeSqlSession(session, sqlSessionFactory);
// users need to manually call commit, rollback and close, just like with normal MyBatis
// API usage
assertNoCommit();
assertSingleConnection();
} finally {
sqlSessionFactory.getConfiguration().setEnvironment(original);
}
}
@Test(expected = TransientDataAccessResourceException.class)
public void testNonSpringTxFactoryWithTx() throws Exception {
Environment original = sqlSessionFactory.getConfiguration().getEnvironment();
Environment nonSpring = new Environment("non-spring", new JdbcTransactionFactory(), dataSource);
sqlSessionFactory.getConfiguration().setEnvironment(nonSpring);
TransactionStatus status = null;
try {
status = txManager.getTransaction(new DefaultTransactionDefinition());
session = SqlSessionUtils.getSqlSession(sqlSessionFactory);
fail("should not be able to get an SqlSession using non-Spring tx manager when there is an active Spring tx");
} finally {
// rollback required to close connection
txManager.rollback(status);
sqlSessionFactory.getConfiguration().setEnvironment(original);
}
}
// TODO should this pass?
/*
* this is an edge case - completely separate DataSource, non-Spring TXManager but with an
* existing Spring TX. Technically, this could be allowed, but the current implementation fails
* because DataSourceUtils.getConnection(DataSource) pulls _any_ Connection into the current tx.
* To fix, however, SqlSessionTemplate.execute() would need to run more checks
* (DataSourceUtils.isConnectionTransactional() and unwrapping TransactionAwareDataSourceProxy)
* which would increase the code path for all transactions.
*/
@Test(expected = TransientDataAccessResourceException.class)
public void testNonSpringTxFactoryNonSpringDSWithTx() {
Environment original = sqlSessionFactory.getConfiguration().getEnvironment();
MockDataSource mockDataSource = new MockDataSource();
mockDataSource.setupConnection(createMockConnection());
Environment nonSpring = new Environment("non-spring", new JdbcTransactionFactory(), mockDataSource);
sqlSessionFactory.getConfiguration().setEnvironment(nonSpring);
TransactionStatus status = null;
try {
status = txManager.getTransaction(new DefaultTransactionDefinition());
session = SqlSessionUtils.getSqlSession(sqlSessionFactory);
fail("should not be able to get an SqlSession using non-Spring tx manager when there is an active Spring tx");
} finally {
// rollback required to close connection
txManager.rollback(status);
sqlSessionFactory.getConfiguration().set
spring-mybatis-spring-1.0.2.zip
需积分: 0 93 浏览量
更新于2024-04-19
收藏 108KB ZIP 举报
《Spring与MyBatis整合详解》
在Java开发领域,Spring框架和MyBatis作为两个极为重要的组件,常被用于构建高效、灵活的企业级应用。本资源包"spring-mybatis-spring-1.0.2.zip"正是为了解决这两者之间的整合问题,提供了在Windows各个版本上的兼容支持,且可免费下载,对于开发者来说是一大福音。
Spring是一个开源的Java平台,它简化了企业级应用的开发,提供了依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented Programming,AOP)等核心功能。而MyBatis则是一个优秀的持久层框架,它简化了SQL操作,将数据库访问逻辑与业务逻辑分离,提高了代码的可维护性。
整合Spring和MyBatis的主要目标是实现数据访问层(Data Access Object,DAO)的无缝集成,使开发者可以利用Spring的强大功能,同时享受MyBatis对数据库操作的灵活性。以下是整合过程中的关键步骤:
1. **配置MyBatis-Spring**:需要在项目中引入mybatis-spring的依赖库,这可以通过Maven或Gradle等构建工具完成。这个库提供了Spring和MyBatis之间的桥梁,使得Spring可以管理SqlSessionFactory和SqlSessionTemplate。
2. **创建SqlSessionFactoryBean**:在Spring的配置文件中,定义一个SqlSessionFactoryBean,它会根据配置文件(通常为mybatis-config.xml)创建SqlSessionFactory,这是MyBatis的核心对象。
3. **配置DataSource**:SqlSessionFactory需要数据源(DataSource),所以在Spring配置中也需要定义数据源,可以使用Apache的Commons DBCP或者Tomcat的JNDI数据源等。
4. **Mapper配置**:MyBatis的Mapper接口和XML配置文件是进行SQL操作的关键。在Spring中,可以通过MapperScannerConfigurer扫描包下所有的Mapper接口,自动将它们注册到Spring容器中。
5. **使用SqlSessionTemplate**:Spring提供的SqlSessionTemplate是线程安全的,可以替代MyBatis原生的SqlSession,方便地在Service层调用Mapper接口执行SQL。
6. **事务管理**:Spring的PlatformTransactionManager负责事务管理,可以配合MyBatis的SqlSessionTemplate使用,实现声明式事务控制。
7. **Mapper接口的使用**:在Service层,通过@Autowired注解注入Mapper接口,然后直接调用其方法,即可执行对应的SQL语句,无需关心底层的SqlSession操作。
通过以上步骤,我们完成了Spring和MyBatis的整合,实现了DAO层的无侵入设计,提升了代码的可读性和可维护性。这个资源包"spring-mybatis-spring-1.0.2.zip"提供了完整的整合示例,对于初学者和开发者来说,都是学习和参考的好材料。无论你是Windows哪个版本的用户,都可以免费下载,快速上手Spring和MyBatis的整合应用。
段子手-168
- 粉丝: 4804
- 资源: 2745
最新资源
- 没用333333333333333333333333333333
- 基于Vue和SpringBoot的企业员工管理系统2.0版本设计源码
- 【C++初级程序设计·配套源码】第2期-基本数据类型
- 基于Java和Vue的kopsoftKANBAN车间电子看板设计源码
- 影驰战将PS3111 东芝芯片TT18G23AIN开卡成功分享,图片里面画线的选项很重要
- 【C++初级程序设计·配套源码】第1期-语法基础
- 基于JavaScript、CSS、HTML的简易DOM版飞机游戏设计源码
- 基于Java开发的日程管理FlexTime应用设计源码
- SM2258XT-BGA144-4BGA180-6L-R1019 三星KLUCG4J1CB B0B1颗粒开盘工具 , EC, 3A, 94, 43, A4, CA 七彩虹SL300这个固件有用
- GJB 5236-2004 军用软件质量度量