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

mybatis單元測試過程(無需啟動容器)

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

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

1 Configuration

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

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

2 Executor

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

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

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

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

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

3 XMLMapperBuilder

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

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

二、單元測試

1 生成mapper實例

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

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

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ù)庫連接
     */
    private SqlSession sqlSession;
    /**
     * 執(zhí)行
     */
    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);
            //讀取測試環(huán)境數(shù)據(jù)庫配置
            PropertySource propertySource = new ResourcePropertySource(new ClassPathResource("testdb.properties"));
            //設(shè)置數(shù)據(jù)庫鏈接
            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ù)(測試設(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();
            //直接實例化一個默認(rèn)的sqlSession
            //是做單元測試,那么沒必要通過SqlSessionFactoryBuilder構(gòu)造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單元測試都可以實現(xiàn),下面給出一個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);
    }

}

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

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

相關(guān)文章

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

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

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

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

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

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

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

    詳解Java集合類之HashTable,Properties篇

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

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

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

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

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

    Guava - 并行編程Futures詳解

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

    Java8中的default方法詳解

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

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

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

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

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

最新評論

宁强县| 莎车县| 广平县| 潞城市| 柳林县| 忻州市| 博爱县| 兴宁市| 宣威市| 芦溪县| 洛宁县| 大同市| 开平市| 遂川县| 砀山县| 新密市| 贵定县| 隆尧县| 喀喇沁旗| 大方县| 中卫市| 正安县| 滕州市| 会东县| 普定县| 西安市| 石柱| 洛宁县| 巴青县| 石泉县| 驻马店市| 峨眉山市| 加查县| 刚察县| 介休市| 广昌县| 罗定市| 平阳县| 托克逊县| 五家渠市| 资中县|