mybatis单元测试(无需启动容器)
一、浅析相关类
1 Configuration
MyBatis在启动时会取读取所有配置文件,然后加载到内存中,Configuration类就是承载整个配置的类。
SqlSessionFactoryBuilder调用build方法创建SqlSessionFactory,而SqlSessionFactory需要Configuration配置中心提供创建的条件,在build方法中XMLConfigBuilder 将xml文件流进行初始化并parse返回Configuration,返回之前需要通过parseConfiguration来真正为Configuration设置信息,XPathParser负责将节点下的信息转换成XNode对象方便访问。
2 Executor
Executor是跟SqlSession绑定在一起的,每一个SqlSession都拥有一个新的Executor对象,由Configuration创建。
Mybatis中所有的Mapper语句的执行都是通过Executor进行的,Executor是Mybatis的一个核心接口。从其定义的接口方法我们可以看出,对应的增删改语句是通过Executor接口的update方法进行的,查询是通过query方法进行的。虽然Executor接口的实现类有BaseExecutor和CachingExecutor,而BaseExecutor的子类又有SimpleExecutor、ReuseExecutor和BatchExecutor,但BaseExecutor是一个抽象类,其只实现了一些公共的封装,而把真正的核心实现都通过方法抽象出来给子类实现,如doUpdate()、doQuery();CachingExecutor只是在Executor的基础上加入了缓存的功能,底层还是通过Executor调用的,所以真正有作用的Executor只有SimpleExecutor、ReuseExecutor和BatchExecutor。它们都是自己实现的Executor核心功能,没有借助任何其它的Executor实现,它们是实现不同也就注定了它们的功能也是不一样的。
3 XMLMapperBuilder
mapper文件的解析依赖于XMLConfigBuilder的mapperElement方法来解析mapper文件。解析过程中实质是实例化一个XMLMapperBuilder对象,然后调用其parse方法,parse方法调用的configurationElement方法是真正mapper节点解析入口,包括sql解析,缓存,等。
二、单元测试
1 生成mapper实例
运用以上相关类的功能,可以直接生成mapper的类实例。
基于Java的编程思想,设计一个基类:
BaseMapperTest:
import org.apache.ibatis.binding.MapperProxyFactory;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.session.defaults.DefaultSqlSession;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.jdbc.JdbcTransaction;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePropertySource;import java.lang.reflect.ParameterizedType;/*** @author: lyx*/
public class BaseMapperTest<T> {/*** mapper接口类(持久层接口)*/private T mapper;/*** 数据库连接*/private SqlSession sqlSession;/*** 执行*/private static Executor executor;/*** 配置*/private static Configuration configuration;static {try {//定义一个配置configuration = new Configuration();configuration.setCacheEnabled(false);configuration.setLazyLoadingEnabled(false);configuration.setAggressiveLazyLoading(true);configuration.setDefaultStatementTimeout(20);//读取测试环境数据库配置PropertySource propertySource = new ResourcePropertySource(new ClassPathResource("testdb.properties"));//设置数据库链接UnpooledDataSource dataSource = new UnpooledDataSource();dataSource.setDriver(propertySource.getProperty("driverClassName").toString());dataSource.setUrl(propertySource.getProperty("url").toString());dataSource.setUsername(propertySource.getProperty("username").toString());dataSource.setPassword(propertySource.getProperty("password").toString());//设置事务(测试设置事务不提交false)Transaction transaction = new JdbcTransaction(dataSource, TransactionIsolationLevel.READ_UNCOMMITTED, false);//设置执行executor = configuration.newExecutor(transaction);} catch (Exception e) {e.printStackTrace();}}public BaseMapperTest(String mapperName) {try {//解析mapper文件Resource mapperResource = new ClassPathResource(mapperName);XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperResource.getInputStream(), configuration, mapperResource.toString(), configuration.getSqlFragments());xmlMapperBuilder.parse();//直接实例化一个默认的sqlSession//是做单元测试,那么没必要通过SqlSessionFactoryBuilder构造SqlSessionFactory,再来获取SqlSessionsqlSession = new DefaultSqlSession(configuration, executor, false);//将接口实例化成对象ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();MapperProxyFactory<T> mapperProxyFactory = new MapperProxyFactory<>((Class<T>) pt.getActualTypeArguments()[0]);mapper = mapperProxyFactory.newInstance(sqlSession);} catch (Exception e) {e.printStackTrace();}}/*** 返回mapper实例对象*/public T getMapper() {return mapper;}
}
配置文件:testdb.properties
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/demo?serverTimezone=GMT&characterEncoding=utf8&useSSL=false&allowMultiQueries=true
username=root
password=root
2 demo
junit或者Testng单元测试都可以实现,下面给出一个junit测试的例子
/*** @author lyx* 直接继承BaseMapperTest,并指定待持久层测试的接口即可*/
@RunWith(SpringRunner.class)
public class BaseConfigDaoTest extends BaseMapperTest<BaseConfigDao> {public BaseConfigDaoTest() {super("mapper/BaseCodeConfigMapper.xml");}@Testpublic void selectListByCodeTest() {String code = "lyx";List<BaseConfigDTO> baseConfigList = super.getMapper().selectListByCode(code);Assert.assertTrue(baseConfigList.size() > 0);}}
mybatis单元测试(无需启动容器)相关推荐
- docker启动容器服务之后访问失败
关于docker启动容器服务之后,宿主机访问失败(解决方法) 注:在进行docker容器启动宿主机进行容器访问时,无需进行网络的配置,docker容器在启动时会自动解决 第一种原因及修改方法 在进行启 ...
- docker端口映射或启动容器时报错 driver failed programming external connectivity on endpoint quirky_allen
docker端口映射或启动容器时报错 Error response from daemon: driver failed programming external connectivity on e ...
- docker 启动容器_crontab入门二:定时启动docker容器并启动容器内部脚本
在寻梦:crontab入门一:crontab定时启动docker容器里面详细的描述了关于如果利用crontab重启docker容器,如果不太熟悉的同学麻烦先去看 寻梦:crontab入门一:cront ...
- docker端口映射或启动容器时报错 driver failed programming external connectivity on endpoint
docker端口映射或启动容器时报错 Error response from daemon: driver failed programming external connectivity on en ...
- SSM+mybatis单元测试
初学SSM+mybatis单元测试遇到的问题,dao注入后为null Dao层注入失败,查看后,发现注解都写的无误,经朋友的指点, 在测试类上加了一句"@RunWith(SpringJUni ...
- Docker制作镜像、启动容器、查看版本、修改源、安装工具
1.制作镜像所需文件 比如想在容器中瞎捣腾python,那就需要制作一个python的镜像,当然,也可以pull别人的,这里当然选择自己make了 需要在宿主机,就是本机,创建一个目录,用来放制作镜像 ...
- docker之阿里云centos 7.x 启动容器报错处理办法
最近阿里云服务器(操作系统centOS 7.x) 安装docker,参照阿里云帮助文档https://help.aliyun.com/document_detail/51853.html?spm=a2 ...
- docker 容器内部获取自身id_crontab入门二:定时启动docker容器并启动容器内部脚本...
在寻梦:crontab入门一:crontab定时启动docker容器里面详细的描述了关于如果利用crontab重启docker容器,如果不太熟悉的同学麻烦先去看 寻梦:crontab入门一:cront ...
- [问题解决]win10误删启动项(BCD)(HP电脑亲测,无需启动盘,并非重装系统)
[问题解决]win10误删启动项(BCD)(HP电脑亲测,无需启动盘,并非重装系统) 参考文章: (1)[问题解决]win10误删启动项(BCD)(HP电脑亲测,无需启动盘,并非重装系统) (2)ht ...
- docker mysql 启动命令_Mac 下使用 Docker mysql 运行的容器如果挂载了/var/lib/mysql 不能启动容器...
通过以下命令不能启动容器: docker run --name db -e MYSQL_ALLOW_EMPTY_PASSWORD=true -d -p 3306:3306 -v /Users/user ...
最新文章
- Java中的多态(for myself)
- Python基础总结(4)
- BizTalk 开发系列(四十二) 为BizTalk应用程序打包不同的环境Binding
- Linux ext2文件系统小结
- 分享Kali Linux 2017.1镜像
- Nginx.代理MySQL
- vue 怎么在字符串中指定位置插入字符_vue 我想在一个字符串中间加入一个/br 该怎么写?...
- http modules在.net安全认证中的作用
- 16位计算机cpu电路图,简单16位CPU设计.doc
- Java 多线程 —— 死锁与锁的错误用法
- 沈南鹏问了微软CEO四个问题
- maven安装 maven上传jar包到库里面
- idm下载百度网盘有限制 提示403错误 下载显示没有权限404,最新的解决办法教程
- 【jenkins 异常】org.eclipse.jgit.errors.InvalidObjectIdException: Invalid id xxxxx
- h3c s5500 ssh v5 配置_H3C S5500 V2基本配置及配置命令
- Linux - Yocto: 创建toolchain
- js递归遍历树形json数据
- 桥本分数式(用递归法实现全排列)
- 阿里正式交棒在即 普通股“一拆八”为赴港上市铺路?
- 数据结构实验之大规模数据交并集