查看原文
其他

MyBatis源码分析之——构建源码分析测试用例

冰河 冰河技术 2022-09-10



一、源码准备


首先,到MyBatis官方GitHub地址将MyBatis源码Fork到自己的GitHub仓库中。


注意:MyBatis官方GitHub地址为:https://github.com/mybatis/mybatis-3。


笔者GitHub地址为:https://github.com/sunshinelyz/mybatis


将MyBatis源码Fork完成后,通过IDEA将MyBatis源码从自己的GitHub地址导入到IDEA中。


在随后的MyBatis源码分析过程中,笔者将会按照https://github.com/sunshinelyz/mybatis 中的代码进行详细分析,并将一些测试用例和代码注释以及流程图提交到https://github.com/sunshinelyz/mybatis 链接地址。 


二、源码改造


1.添加resources目录


首先,下载后的源码在src/test/目录下没有resources目录,我们创建MyBatis的源码测试用例时需要构建一个较为完整的数据库查询Demo,需要在src/test/resources目录下创建相应的配置文件。所以,需要在MyBatis源码的src/test目录下创建resources目录。创建完成后,需要将resources目录设置为source目录。将resources目录设置为source目录的过程如下所示。


(1)打开项目结构


单击IDEA的“File”—> “Project Structure”打开项目的结构



(2)将resources目录设置为source目录


过程按下图所示。



2.添加依赖环境


编辑MyBatis的pom.xml文件,添加一些测试用例需要使用的Jar文件,首先在properties节点中添加一些依赖的环境的版本属性,如下所示。


<properties> <!--此处省略n多配置项---> <!--下面几个是自己加的--> <lombok.version>1.16.10</lombok.version> <fastjson.version>1.2.62</fastjson.version> <jdbc.version>5.1.48</jdbc.version></properties>


接下来,在pom.xml文件的dependencies节点下添加依赖的Jar环境,如下所示


<dependencies> <!---前面省略n多配置--> <!---后面的依赖是自己加的--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${jdbc.version}</version> </dependency> </dependencies>


3.编辑配置文件


(1)创建MyBatis配置文件


在新创建的resources目录下创建mybatis目录,并在mybatis目录下创建mybatis-config.xml配置文件,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"><configuration> <settings> <setting name="logImpl" value="LOG4J"/> </settings> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=false"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="mybatis/UserMapper.xml"/> <!-- <mapper class="io.binghe.mybatis.mapper.UserMapper"/>--> </mappers> </configuration>


(2)修改log4j.properties文件


修改MyBatis源码下的src/test/java下的log4j.properties文件,在log4j.properties文件的最后添加如下一行代码。


#MyBatis日志配置log4j.logger.io.binghe.mybatis=TRACE


4.创建测试类


注意:测试用例的所有Java类都是在MyBatis源码下的src/test/java目录下创建的。


(1)创建实体类User


在io.binghe.mybatis.entity包下创建测试实体类User,User类总体上比较简单,只包含id、username和age三个属性,如下所示。


package io.binghe.mybatis.entity; import lombok.ToString; import java.io.Serializable; /** * @author binghe * @version 1.0.0 * @description 测试实体类 */@ToStringpublic class User implements Serializable { private static final long serialVersionUID = 821465757967990094L; private int id; private String username; private int age; public User() { } public User(int id, String username, int age) { this.id = id; this.username = username; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}


(2)创建User类的Mapper接口


在io.binghe.mybatis.mapper包下创建UserMapper接口,如下所示。


package io.binghe.mybatis.mapper; import io.binghe.mybatis.entity.User;import org.apache.ibatis.annotations.Select; /** * @author binghe * @version 1.0.0 * @description User类的Mapper接口 */public interface UserMapper { // @Select("select * from t_user where id = #{id}") User selectUser(Integer id);}


(3)创建UserMapper接口对应的UserMapper.xml文件


在src/test/resources/mybatis目录下创建UserMapper接口对应的UserMapper.xml文件,UserMapper.xml文件的内容如下所示。


<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="io.binghe.mybatis.mapper.UserMapper"> <select id="selectUser" resultType="io.binghe.mybatis.entity.User"> select * from t_user where id = #{id} </select></mapper>


这里,有两个需要注意的地方:


  •  UserMapper.xml文件中的namespace属性需要和UserMapper接口的全类名相同。

  •  UserMapper.xml文件中的select标签的id属性需要和UserMapper接口中定义的方法名相同。


在后续的源码分析中,会详细阐述MyBatis中为何需要这样设置。


(4)创建测试类MyBatisTest


在io.binghe.mybatis.test包中创建测试程序的入口类MyBatisTest,如下所示。


package io.binghe.mybatis.test; import io.binghe.mybatis.entity.User;import io.binghe.mybatis.mapper.UserMapper;import lombok.extern.slf4j.Slf4j;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.Test; import java.io.IOException;import java.io.InputStream; /** * @author binghe * @version 1.0.0 * @description 测试用例的入口类 */@Slf4jpublic class MyBatisTest { @Test public void testXml() throws IOException { String resource = "mybatis/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); User user = sqlSession.selectOne("io.binghe.mybatis.mapper.UserMapper.selectUser",1); log.info(user.toString()); } @Test public void testAnnotation() throws IOException { String resource = "mybatis/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.selectUser(1); log.info(user.toString()); }}


在MyBatisTest类中,提供了两个测试方法,一个是用于测试以xml文件方式配置MyBatis的testXml()方法,一个是用于测试以注解方式配置MyBatis的testAnnotation()方法。


(5)创建测试数据表


最后,在MySQL的test数据库下创建测试数据表t_user,并在t_user数据表中插入测试数据,如下所示。


CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) DEFAULT '', `age` int(2) DEFAULT '0', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4; INSERT INTO `test`.`t_user` (`id`, `username`, `age`) VALUES ('1', 'admin', '18');INSERT INTO `test`.`t_user` (`id`, `username`, `age`) VALUES ('2', 'binghe', '19');INSERT INTO `test`.`t_user` (`id`, `username`, `age`) VALUES ('3', 'zhangsan', '19');INSERT INTO `test`.`t_user` (`id`, `username`, `age`) VALUES ('4', 'lisi', '19');



三、运行测试用例


运行MyBatisTest类中的testXml()方法,输出结果如下所示。


DEBUG [main] - ==> Preparing: select * from t_user where id = ? DEBUG [main] - ==> Parameters: 1(Integer)TRACE [main] - <== Columns: id, username, ageTRACE [main] - <== Row: 1, admin, 18DEBUG [main] - <== Total: 1 INFO [main] - User(id=1, username=admin, age=18) Process finished with exit code 0



说明测试用例构建成功,接下来就可以分析MyBatis源码了。



你在刷抖音,玩游戏的时候,别人都在这里学习,成长,提升,人与人最大的差距其实就是思维。你可能不信,优秀的人,总是在一起。



扫码加入星球,看到人生中更多的可能性。





您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存