最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

mybatis單元測(cè)試過程(無需啟動(dòng)容器)

 更新時(shí)間:2024年09月19日 10:18:28   作者:wating1112  
在MyBatis中,單元測(cè)試無需啟動(dòng)容器即可進(jìn)行,主要涉及Configuration類、Executor接口及其實(shí)現(xiàn)類,以及XMLMapperBuilder的作用,Configuration類是配置的承載者,負(fù)責(zé)初始化并解析配置文件,Executor接口及其實(shí)現(xiàn)類

一、淺析相關(guān)類

1 Configuration

MyBatis在啟動(dòng)時(shí)會(huì)取讀取所有配置文件,然后加載到內(nèi)存中,Configuration類就是承載整個(gè)配置的類。

SqlSessionFactoryBuilder調(diào)用build方法創(chuàng)建SqlSessionFactory,而SqlSessionFactory需要Configuration配置中心提供創(chuàng)建的條件,在build方法中XMLConfigBuilder 將xml文件流進(jìn)行初始化并parse返回Configuration,返回之前需要通過parseConfiguration來真正為Configuration設(shè)置信息,XPathParser負(fù)責(zé)將節(jié)點(diǎn)下的信息轉(zhuǎn)換成XNode對(duì)象方便訪問。

2 Executor

Executor是跟SqlSession綁定在一起的,每一個(gè)SqlSession都擁有一個(gè)新的Executor對(duì)象,由Configuration創(chuàng)建。

Mybatis中所有的Mapper語句的執(zhí)行都是通過Executor進(jìn)行的,Executor是Mybatis的一個(gè)核心接口。

從其定義的接口方法我們可以看出,對(duì)應(yīng)的增刪改語句是通過Executor接口的update方法進(jìn)行的,查詢是通過query方法進(jìn)行的。

雖然Executor接口的實(shí)現(xiàn)類有BaseExecutor和CachingExecutor,而BaseExecutor的子類又有SimpleExecutor、ReuseExecutor和BatchExecutor,但BaseExecutor是一個(gè)抽象類,其只實(shí)現(xiàn)了一些公共的封裝,而把真正的核心實(shí)現(xiàn)都通過方法抽象出來給子類實(shí)現(xiàn),如doUpdate()、doQuery();CachingExecutor只是在Executor的基礎(chǔ)上加入了緩存的功能,底層還是通過Executor調(diào)用的,所以真正有作用的Executor只有SimpleExecutor、ReuseExecutor和BatchExecutor。

它們都是自己實(shí)現(xiàn)的Executor核心功能,沒有借助任何其它的Executor實(shí)現(xiàn),它們是實(shí)現(xiàn)不同也就注定了它們的功能也是不一樣的。

3 XMLMapperBuilder

mapper文件的解析依賴于XMLConfigBuilder的mapperElement方法來解析mapper文件。

解析過程中實(shí)質(zhì)是實(shí)例化一個(gè)XMLMapperBuilder對(duì)象,然后調(diào)用其parse方法,parse方法調(diào)用的configurationElement方法是真正mapper節(jié)點(diǎn)解析入口,包括sql解析,緩存,等。

二、單元測(cè)試

1 生成mapper實(shí)例

運(yùn)用以上相關(guān)類的功能,可以直接生成mapper的類實(shí)例。

基于Java的編程思想,設(shè)計(jì)一個(gè)基類:

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;
    /**
     * 數(shù)據(jù)庫(kù)連接
     */
    private SqlSession sqlSession;
    /**
     * 執(zhí)行
     */
    private static Executor executor;
    /**
     * 配置
     */
    private static Configuration configuration;

    static {
        try {
            //定義一個(gè)配置
            configuration = new Configuration();
            configuration.setCacheEnabled(false);
            configuration.setLazyLoadingEnabled(false);
            configuration.setAggressiveLazyLoading(true);
            configuration.setDefaultStatementTimeout(20);
            //讀取測(cè)試環(huán)境數(shù)據(jù)庫(kù)配置
            PropertySource propertySource = new ResourcePropertySource(new ClassPathResource("testdb.properties"));
            //設(shè)置數(shù)據(jù)庫(kù)鏈接
            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());
            //設(shè)置事務(wù)(測(cè)試設(shè)置事務(wù)不提交false)
            Transaction transaction = new JdbcTransaction(dataSource, TransactionIsolationLevel.READ_UNCOMMITTED, false);
            //設(shè)置執(zhí)行
            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();
            //直接實(shí)例化一個(gè)默認(rèn)的sqlSession
            //是做單元測(cè)試,那么沒必要通過SqlSessionFactoryBuilder構(gòu)造SqlSessionFactory,再來獲取SqlSession
            sqlSession = new DefaultSqlSession(configuration, executor, false);
            //將接口實(shí)例化成對(duì)象
            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實(shí)例對(duì)象
     */
    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單元測(cè)試都可以實(shí)現(xiàn),下面給出一個(gè)junit測(cè)試的例子

/**
 * @author lyx
 * 直接繼承BaseMapperTest,并指定待持久層測(cè)試的接口即可
 */
@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);
    }

}

???????總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解Java反射各種應(yīng)用

    詳解Java反射各種應(yīng)用

    Java除了給我們提供在編譯期得到類的各種信息之外,還通過反射讓我們可以在運(yùn)行期間得到類的各種信息。通過反射獲取類的信息,得到類的信息之后,就可以獲取很多相關(guān)內(nèi)容。下面跟著小編一起來看下吧
    2017-01-01
  • 基于RabbitMQ的簡(jiǎn)單應(yīng)用(詳解)

    基于RabbitMQ的簡(jiǎn)單應(yīng)用(詳解)

    下面小編就為大家分享一篇基于RabbitMQ的簡(jiǎn)單應(yīng)用(詳解),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2017-11-11
  • Nacos源碼之注冊(cè)中心的實(shí)現(xiàn)詳解

    Nacos源碼之注冊(cè)中心的實(shí)現(xiàn)詳解

    這篇文章主要為大家介紹了Nacos源碼之注冊(cè)中心的實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • 詳解Java集合類之HashTable,Properties篇

    詳解Java集合類之HashTable,Properties篇

    這篇文章主要為大家詳細(xì)介紹一下Java集合類中HashTable和Properties的用法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定幫助,感興趣的可以了解一下
    2022-07-07
  • java8中定時(shí)任務(wù)最佳實(shí)現(xiàn)方式(實(shí)現(xiàn)原理)

    java8中定時(shí)任務(wù)最佳實(shí)現(xiàn)方式(實(shí)現(xiàn)原理)

    這篇文章主要介紹了java8中定時(shí)任務(wù)最佳實(shí)現(xiàn)方式,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-12-12
  • 通過Java添加Word文本框過程詳解

    通過Java添加Word文本框過程詳解

    這篇文章主要介紹了通過Java添加Word文本框過程詳解,在Word中,文本框是指一種可移動(dòng)、可調(diào)節(jié)大小的文字或圖形容器。我們可以向文本框中添加文字、圖片、表格等對(duì)象,下面,將通過Java編程來實(shí)現(xiàn)添加以上對(duì)象到Word文本框,需要的朋友可以參考下
    2019-07-07
  • Guava - 并行編程Futures詳解

    Guava - 并行編程Futures詳解

    這篇文章主要介紹了Guava - 并行編程Futures詳解方法的相關(guān)資料,需要的朋友可以參考下
    2016-09-09
  • Java8中的default方法詳解

    Java8中的default方法詳解

    這篇文章主要介紹了Java8中的default方法詳解,Java 8新增了default方法,它可以在接口添加新功能特性,而且還不影響接口的實(shí)現(xiàn)類,需要的朋友可以參考下
    2015-03-03
  • 基于logback實(shí)現(xiàn)純java版本的SDK組件

    基于logback實(shí)現(xiàn)純java版本的SDK組件

    這篇文章主要介紹了基于logback實(shí)現(xiàn)純java版本的SDK組件,在項(xiàng)目開發(fā)過程中通常會(huì)使用logback作為日志記錄的依賴工具,使用方式是引入logback相關(guān)jar包,然后配置logback.xml配置文件的方式來實(shí)現(xiàn),需要的朋友可以參考下
    2023-11-11
  • Mac M1 Java 開發(fā)環(huán)境配置詳解

    Mac M1 Java 開發(fā)環(huán)境配置詳解

    這篇文章主要介紹了Mac M1 Java 開發(fā)環(huán)境配置詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03

最新評(píng)論

芦溪县| 都匀市| 临漳县| 马关县| 乌审旗| 大冶市| 福贡县| 高碑店市| 北海市| 乌海市| 桂林市| 博湖县| 成安县| 灌云县| 津南区| 高雄县| 璧山县| 夹江县| 浦北县| 灵璧县| 建宁县| 永吉县| 崇阳县| 镇沅| 满城县| 平谷区| 电白县| 满洲里市| 新邵县| 横峰县| 潜山县| 金秀| 贵德县| 西贡区| 昌平区| 郯城县| 仪征市| 阜新| 扎囊县| 南乐县| 革吉县|