本系列博客將對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開發方式。后面會通過這個例子深入源碼分析。