mybatis源码解读(一)——初始化环境
本系列博客将对mybatis的源码进行解读,关于mybatis的使用教程,可以查看我前面写的博客——传送门。
为了便于后面的讲解,我们这里首先构造一个统一环境。也可以参考mybatis官网。
1、数据库建表
DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `user_id` int(32) NOT NULL COMMENT '用户id', `user_name` varchar(64) default NULL COMMENT '用户姓名', `user_age` int(3) default NULL COMMENT '用户年龄', PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2、项目的目录结构
相关配置的版本如下:
JDK:1.8 maven:3.3.9 mybatis:3.4.3
3、pom文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>com.ys</groupId> 8 <artifactId>MybatisDemo</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 <dependencies> 11 <dependency> 12 <groupId>org.mybatis</groupId> 13 <artifactId>mybatis</artifactId> 14 <version>3.4.3</version> 15 </dependency> 16 <dependency> 17 <groupId>junit</groupId> 18 <artifactId>junit</artifactId> 19 <version>4.12</version> 20 <scope>test</scope> 21 </dependency> 22 23 <dependency> 24 <groupId>mysql</groupId> 25 <artifactId>mysql-connector-java</artifactId> 26 <version>5.1.30</version> 27 </dependency> 28 29 </dependencies> 30 31 <build> 32 <plugins> 33 <plugin> 34 <groupId>org.apache.maven.plugins</groupId> 35 <artifactId>maven-compiler-plugin</artifactId> 36 <configuration> 37 <source>1.8</source> 38 <target>1.8</target> 39 </configuration> 40 </plugin> 41 </plugins> 42 43 <resources> 44 <resource> 45 <directory>src/main/java</directory> 46 <includes> 47 <include>**/*.properties</include> 48 <include>**/*.xml</include> 49 </includes> 50 <filtering>false</filtering> 51 </resource> 52 <resource> 53 <directory>src/main/resources</directory> 54 <includes> 55 <include>**/*.properties</include> 56 <include>**/*.xml</include> 57 </includes> 58 <filtering>false</filtering> 59 </resource> 60 </resources> 61 </build> 62 63 64 </project>
分别在pom文件中添加mybatis包,mysql数据库连接包,Junit测试包。
注意:由于我使用的编译器是 IDEA,这里必须在pom文件中配置对resource资源目录下的xml 文件的访问,否则,IEDA会读取不到resource目录下的配置文件。
4、资源文件配置
①、jdbc.properties
1 jdbc.driver=com.mysql.jdbc.Driver 2 jdbc.url=jdbc:mysql://localhost:3306/mybatisTest?useUnicode=true&characterEncoding=utf-8 3 jdbc.username=root 4 jdbc.password=root
②、mybatsi-configuration.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> 3 <configuration> 4 5 <!-- 加载数据库属性文件 --> 6 <properties resource="jdbc.properties"> 7 </properties> 8 <!-- 可以配置多个运行环境,但是每个 SqlSessionFactory 实例只能选择一个运行环境 一、development:开发模式 二、work:工作模式 --> 9 <environments default="development"> 10 <!--id属性必须和上面的default一样 --> 11 <environment id="development"> 12 <transactionManager type="JDBC" /> 13 <!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源 --> 14 <dataSource type="POOLED"> 15 <property name="driver" value="${jdbc.driver}" /> 16 <property name="url" value="${jdbc.url}" /> 17 <property name="username" value="${jdbc.username}" /> 18 <property name="password" value="${jdbc.password}" /> 19 </dataSource> 20 </environment> 21 </environments> 22 23 <mappers> 24 <mapper resource="com/ys/mapper/userMapper.xml"/> 25 </mappers> 26 </configuration>
5、pojo 类
前面我们创建了 user 表,这里创建其实体类。
1 package com.ys.po; 2 3 import java.io.Serializable; 4 5 public class User implements Serializable{ 6 7 public User() { 8 super(); 9 } 10 public User(Integer id, String name, Integer age) { 11 super(); 12 this.id = id; 13 this.name = name; 14 this.age = age; 15 } 16 private Integer id; 17 private String name; 18 private Integer age; 19 public Integer getId() { 20 return id; 21 } 22 public void setId(Integer id) { 23 this.id = id; 24 } 25 public String getName() { 26 return name; 27 } 28 public void setName(String name) { 29 this.name = name; 30 } 31 public Integer getAge() { 32 return age; 33 } 34 public void setAge(Integer age) { 35 this.age = age; 36 } 37 @Override 38 public String toString() { 39 return "User [id=" + id + ", name=" + name + ", age=" + age + "]"; 40 } 41 42 }
注意:根据阿里巴巴的最新编码规范,实体类中的属性不要写基本数据类型,必须使用包装类型。比如 int 类型的 id,我们应该写成其包装类 Integer 类型。
原因:比如显示成交总额涨跌情况,即正负 x %, x 为基本数据类型,调用的 RPC 服务,调用不成功时,返回的是默认值,页面显示为 0%,这是不合理的,应该显示成中划线。所以包装数据类型的 null 值,能够表示额外的信息,如:远程调用失败,异常退出。
6、mapper 文件
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 <mapper namespace="com.ys.po.userMapper"> 6 <resultMap id="BaseResultMap" type="com.ys.po.User"> 7 <id column="user_id" property="id" jdbcType="INTEGER"></id> 8 <result column="user_name" property="name" jdbcType="VARCHAR" /> 9 <result column="user_age" property="age" jdbcType="INTEGER" /> 10 </resultMap> 11 12 <sql id="Base_Column_List"> 13 user_id, user_name, user_age 14 </sql> 15 16 <!-- 根据id查询 user 表数据 --> 17 <select id="selectUserById" resultMap="BaseResultMap" parameterType="java.lang.Integer"> 18 select 19 <include refid="Base_Column_List" /> 20 from user where user_id = #{id,jdbcType=INTEGER} 21 </select> 22 23 24 <!-- 查询 user 表的所有数据 --> 25 <select id="selectUserAll" resultMap="BaseResultMap"> 26 select 27 <include refid="Base_Column_List" /> 28 from user 29 </select> 30 31 32 <!-- 向 user 表插入一条数据 --> 33 <insert id="insertUser" parameterType="com.ys.po.User" > 34 insert into 35 user(<include refid="Base_Column_List" />) 36 value(#{id,jdbcType=INTEGER},#{name,jdbcType=VARCHAR},#{age,jdbcType=INTEGER}) 37 </insert> 38 39 <!-- 根据 id 更新 user 表的数据 --> 40 <update id="updateUserById" parameterType="com.ys.po.User"> 41 update user set 42 user_name=#{name,jdbcType=VARCHAR} where user_id=#{id,jdbcType=INTEGER} 43 </update> 44 45 <!-- 根据 id 删除 user 表的数据 --> 46 <delete id="deleteUserById" parameterType="java.lang.Integer"> 47 delete from 48 user where user_id=#{id,jdbcType=INTEGER} 49 </delete> 50 </mapper>
7、测试类
1 package com.ys.test; 2 3 import java.io.InputStream; 4 import java.util.List; 5 6 import org.apache.ibatis.session.SqlSession; 7 import org.apache.ibatis.session.SqlSessionFactory; 8 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 9 import org.junit.Test; 10 11 import com.ys.po.User; 12 13 public class MybatisTest { 14 private static final String NAME_SPACE = "com.ys.po.userMapper"; 15 private static SqlSessionFactory sqlSessionFactory; 16 17 static{ 18 InputStream inputStream = MybatisTest.class.getClassLoader().getResourceAsStream("mybatis-configuration.xml"); 19 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 20 } 21 /** 22 * 查询单个记录 23 */ 24 @Test 25 public void testSelectOne(){ 26 SqlSession session = sqlSessionFactory.openSession(); 27 User user = session.selectOne(NAME_SPACE+".selectUserById", 1); 28 System.out.println(user); 29 session.close(); 30 31 } 32 33 /** 34 * 查询多个记录 35 */ 36 @Test 37 public void testSelectList(){ 38 SqlSession session = sqlSessionFactory.openSession(); 39 List<User> listUser = session.selectList(NAME_SPACE+".selectUserAll"); 40 if(listUser != null){ 41 System.out.println(listUser.size()); 42 } 43 session.close(); 44 } 45 46 /** 47 * 插入一条记录 48 */ 49 @Test 50 public void testInsert(){ 51 SqlSession session = sqlSessionFactory.openSession(); 52 User user = new User(2,"zhangsan",22); 53 session.insert(NAME_SPACE+".insertUser", user); 54 session.commit(); 55 session.close(); 56 } 57 58 /** 59 * 更新一条记录 60 */ 61 @Test 62 public void testUpdate(){ 63 SqlSession session = sqlSessionFactory.openSession(); 64 User user = new User(2,"lisi",22); 65 session.update(NAME_SPACE+".updateUserById", user); 66 session.commit(); 67 session.close(); 68 } 69 70 /** 71 * 删除一条记录 72 */ 73 @Test 74 public void testDelete(){ 75 SqlSession session = sqlSessionFactory.openSession(); 76 session.delete(NAME_SPACE+".deleteUserById", 2); 77 session.commit(); 78 session.close(); 79 } 80 81 }
8、测试结果
出现5条绿色的横杆,然后去数据库查看相应的结果。
9、总结
这个demo没什么好说的,不懂的看我前面的新手使用教程即可,这是最原始的mybatis开发方式。后面会通过这个例子深入源码分析。