当前位置: 代码网 > it编程>编程语言>Java > mybatis单元测试过程(无需启动容器)

mybatis单元测试过程(无需启动容器)

2024年09月19日 Java 我要评论
一、浅析相关类1 configurationmybatis在启动时会取读取所有配置文件,然后加载到内存中,configuration类就是承载整个配置的类。sqlsessionfactorybuild

一、浅析相关类

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,再来获取sqlsession
            sqlsession = 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");
    }

    @test
    public void selectlistbycodetest() {
        string code = "lyx";
        list<baseconfigdto> baseconfiglist = super.getmapper().selectlistbycode(code);
        assert.asserttrue(baseconfiglist.size() > 0);
    }

}

​​​​​​​总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com