MyBatis的JUnit测试

栏目: 数据库 · 发布时间: 6年前

内容简介:最近项目中遇到一个场景,需要将项目中原有的DB切成MySQL。为了验证修改后的MyBatis的XML映射文件的SQL语法是否OK,重新部署后,在界面上一顿狂点。这种做法太Low,不仅没效率,还可能存在漏测。通过MyBatis自带的API,实现XML映射文件的加载,达到在本地测试的目的。无需启动spring框架服务,灵活配置本地调试场景。配置数据库驱动、用户名、密码等属性,写入db-config.properties文件中,如:

最近项目中遇到一个场景,需要将项目中原有的DB切成MySQL。为了验证修改后的MyBatis的XML映射文件的 SQL 语法是否OK,重新部署后,在界面上一顿狂点。这种做法太Low,不仅没效率,还可能存在漏测。

目的

通过MyBatis自带的API,实现XML映射文件的加载,达到在本地测试的目的。无需启动spring框架服务,灵活配置本地调试场景。

实现方案

1. 数据库连接属性配置

配置数据库驱动、用户名、密码等属性,写入db-config.properties文件中,如:

mysql.driver=com.mysql.cj.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/qiyin?useUnicode=true&characterEncoding=utf8
mysql.username=root
mysql.password=123456
复制代码

2. MyBatis配置文件

MyBatis配置文件的各个字段,在官网有详细介绍【传送门】 。

如下是我的配置文件mybatis-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--实现mybatis与数据库的连接  -->
<configuration>
    <!-- 引入属性配置文件 -->
    <properties resource="db-config.properties"/>
    <!-- 指定日志的具体实现 -->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!--<setting name="logImpl" value="LOG4J2"/>-->
    </settings>
    <typeAliases>
        <package name="me.ifight.bean"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <!-- 采用JDBC管理事务-->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${mysql.driver}"/>
                <property name="url" value="${mysql.url}"/>
                <property name="username" value="${mysql.username}"/>
                <property name="password" value="${mysql.password}"/>
            </dataSource>
        </environment>

    </environments>
    <!-- 注册mapper -->
    <mappers>
        <mapper resource="mybatisMapper/ProjectMapper.xml"/>
    </mappers>
</configuration>
复制代码

值得注意的有一下几点:

  1. properties字段的resource指向在上一节定义好的数据库连接属性文件的路径。
  2. environment节点可以定义多个,其包含的dataSource节点中的属性值引用来自于db-config.properties定义的变量。
  3. mapper节点可以有几种不同实现方式,详细可查看官方文档【传送门】。但如果配置不当,会报 XXX is not known to the MapperRegistry 或者是抛出 BindingException 异常。最终我采用了 <mapper resource="xxx/xxx/xxx.xml"/> 方式,虽然每个XML映射文件都需要手动声明一次,但胜在不易出错。如果有更nice的方法,请在回复中不吝赐教。

3. MyBatis创建Session工具类

上面两步骤完成了一些必要的配置,接下来,就需要使用一个 工具 类来代替spring来实现数据库会话创建、Mapper类加载等操作。直接上代码:

public class MybatisUtil {
    private static final LogUtil log = LogUtil.getLogger(MybatisUtil.class, MybatisUtil.class.getSimpleName());

    /**
     * MyBatis配置文件路径
      */
    private static final String MYBATIS_CONFIG_PATH = "mybatis-config.xml";

    private static SqlSessionFactory factory;
    private static ThreadLocal<SqlSession> localSessions = new ThreadLocal<>();

    /**
     * 加载并解析配置文件
     */
    static {
        try(
                InputStream in = Resources.getResourceAsStream(MYBATIS_CONFIG_PATH)
        ) {
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            factory = builder.build(in);
        } catch (IOException e) {
            log.error("SqlSessionFactory init error", e);
        }
    }

    /**
     * 常见会话
     * @return
     */
    public static SqlSession getSession(){
        SqlSession sqlSession = localSessions.get();
        if (sqlSession == null){
            sqlSession = factory.openSession();
            localSessions.set(sqlSession);
        }

        if (sqlSession == null){
            log.error("#getSession error, session is nulll");
        } else {
            log.info("#getSession successfully");
        }

        return sqlSession;
    }

    /**
     * 销毁会话
     */
    public static void closeSession(){
        SqlSession sqlSession = localSessions.get();
        if (sqlSession != null){
            sqlSession.close();
            localSessions.remove();
        }
        log.info("#closeSession successfully");
    }
}
复制代码

4. 测试验证材料

在项目的resources目录中,已经有一个MyBatis的XML映射文件:mybatisMapper/ProjectMapper.xml。模拟一个select方法selectProjectsByUserName

<select id="selectProjectsByUserName" resultMap="AllColumnMap">
        SELECT <include refid="all_column"/>
        FROM todo_project
        where created_user_name = #{userName}
        order by last_time desc
        LIMIT 1000
    </select>
复制代码

对应的接口类为:ProjectDao

public interface ProjectDao {
    List<ProjectDO> selectProjectsByUserName(@Param("userName") String userName);
}
复制代码

5. JUnit测试脚本

public class ProjectDaoTest{
    private static final LogUtil log = LogUtil.getLogger(ProjectDaoTest.class, ProjectDaoTest.class.getSimpleName());
    private SqlSession sqlSession;
    private ProjectDao projectDao;

    @Before
    public void setUp() throws Exception{
        log.info("#setUp start...");
        sqlSession = MybatisUtil.getSession();
        projectDao = sqlSession.getMapper(ProjectDao.class);
    }

    @Test
    public void testSelectProjectsByUserName(){
        List<ProjectDO> projects = projectDao.selectProjectsByUserName("admin");
        Assert.assertTrue(CollectionUtils.isNotEmpty(projects));
    }

    @After
    public void tearDown() throws Exception{
        log.info("#tearDown start...");
        sqlSession.commit();
        MybatisUtil.closeSession();
    }
}
复制代码

测试脚本的关键在于,使用SqlSession实例的getMapper()方法加载已经注册的Mapper对象。 所谓的已经注册是指在解析MyBatis配置文件时,通过加载MyBatis配置文件中的mappers节点的信息,调用MapperRegistry实例的addMappers方法来完成注册。

备注

项目中一般都会存在多个MyBatis的XML映射文件,此时需要在mybatis-config.xml文件的mappers节点中添加新的映射关系。然后可以考虑,在测试包目录下,新建一个类似ProjectDaoTest的测试类。在这个类中,可以测试XML映射文件中涉及的每个sql方法。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Beginning ARKit for iPhone and iPad

Beginning ARKit for iPhone and iPad

Wallace Wang / Apress / 2018-11-5 / USD 39.99

Explore how to use ARKit to create iOS apps and learn the basics of augmented reality while diving into ARKit specific topics. This book reveals how augmented reality allows you to view the screen on ......一起来看看 《Beginning ARKit for iPhone and iPad》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具