上篇文章給大家擼了一遍用 JDBC 直接運算元據庫的例項,還只是簡單寫了一個查詢的介面,其程式碼量就已經很大了,並且可樂還給大家分析了直接使用 JDBC 帶來的一些問題,總之是一種反人類的操作,為了讓這種操作人類正常化,我們選擇使用 ORM 框架。
本篇文章給大家從頭搭建一遍,如何基於 XML 配置,使用 Mybatis 進行增刪改查操作。
看到這,可能有讀者就要問了,what?
我現在使用 Springboot 多爽,還要這些複雜的配置幹啥?
可樂這裡要說的是,Springboot 用起來是爽,它啥都給你封裝好了,但是很多細節問題你可能並不知道,後續擼 Mybatis 的原始碼流程也是基於此,所以大家一定要過一遍 Mybatis 原始的執行方式。
專案原始碼地址:https://github.com/YSOcean/mybatisproject
這裡可樂不會介紹各種配置含義,需要的可以直接參考官網,更加權威,你值得擁有:https://mybatis.org/mybatis-3/zh/configuration.html
1、建立庫表
以 Mysql 資料庫為例,表比較簡單,這裡可樂就直接放圖和建表語句了。
-- ----------------------------
-- Table structure for person
-- ----------------------------
DROP TABLE IF EXISTS `person`;
CREATE TABLE `person` (
`pid` int NOT NULL AUTO_INCREMENT,
`pname` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
`page` int DEFAULT NULL,
PRIMARY KEY (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Records of person
-- ----------------------------
BEGIN;
INSERT INTO `person` VALUES (1, 'itcoke', 11);
INSERT INTO `person` VALUES (2, 'IT可樂', 22);
COMMIT;
2、建立工程
通過 IDEA 建立一個工程,並匯入相應的jar包。
以 maven 為例,配置 MySQL 和 Mybatis 即可。
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.26</version> </dependency>
整個專案結構可以參考我的GitHub地址:https://github.com/YSOcean/mybatisproject
3、建立與表對應的實體類物件
1 package com.itcoke.bean; 2 3 public class Person { 4 5 private Long pid; 6 7 private String pname; 8 9 private Integer page; 10 11 public Long getPid() { 12 return pid; 13 } 14 15 public void setPid(Long pid) { 16 this.pid = pid; 17 } 18 19 public String getPname() { 20 return pname; 21 } 22 23 public void setPname(String pname) { 24 this.pname = pname; 25 } 26 27 public Integer getPage() { 28 return page; 29 } 30 31 public void setPage(Integer page) { 32 this.page = page; 33 } 34 35 @Override 36 public String toString() { 37 return "Person{" + 38 "pid=" + pid + 39 ", pname='" + pname + '\'' + 40 ", page=" + page + 41 '}'; 42 } 43 }
4、編寫資料庫配置檔案 mybatis-config.xml
關於配置檔案的詳細介紹,可以參考官網:https://mybatis.org/mybatis-3/zh/configuration.html
<?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> <!-- 可以配置多個執行環境,但是每個 SqlSessionFactory 例項只能選擇一個執行環境 --> <!-- 預設使用的環境 ID,名字隨意,但是要匹配下面其中一個環境 ID --> <environments default="development"> <!-- 環境ID --> <environment id="development"> <!--事務管理器 一、JDBC:這個配置直接簡單使用了 JDBC 的提交和回滾設定。它依賴於從資料來源得到的連線來管理事務範圍 二、MANAGED:這個配置幾乎沒做什麼。它從來不提交或回滾一個連線。而它會讓容器來管理事務的整個生命週期 比如 spring 或 JEE 應用伺服器的上下文,預設情況下,它會關閉連線。然而一些容器並不希望這樣, 因此如果你需要從連線中停止它,就可以將 closeConnection 屬性設定為 false,比如: <transactionManager type="MANAGED"> <property name="closeConnection" value="false"/> </transactionManager> --> <transactionManager type="JDBC"/> <!--dataSource 元素使用標準的 JDBC 資料來源介面來配置 JDBC 連線物件源 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis-study"/> <property name="username" value="root"/> <property name="password" value="root1234"/> </dataSource> </environment> </environments> </configuration>
5、定義person表對映檔案
官方權威地址:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html
<?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="com.itcoke.mapper.PersonMapper"> <!-- 根據 id 查詢 person 表中的資料 id:唯一識別符號,此檔案中的id值不能重複 resultType:返回值型別,一條資料庫記錄也就對應實體類的一個物件 parameterType:引數型別,也就是查詢條件的型別 --> <select id="selectPersonById" resultType="com.itcoke.bean.Person" parameterType="java.lang.Long" > <!-- 這裡和普通的sql 查詢語句差不多,後面的 #{id}表示佔位符,裡面不一定要寫id,寫啥都可以,但是不要空著 --> select * from person where pid = #{pid} </select> <!-- 根據 id 更新 person 表的資料 --> <update id="updatePersonById" parameterType="com.itcoke.bean.Person"> update person p <trim prefix="set" suffixOverrides=","> <if test="pname != null and pname != ''"> p.pname = #{pname}, </if> <if test="page != null and page != ''"> p.page = #{page}, </if> </trim> where pid=#{pid} </update> <!-- 向 person 表插入一條資料 --> <insert id="insertPerson" parameterType="com.itcoke.bean.Person"> insert into person(pname,page) value(#{pname},#{page}) </insert> <!-- 根據 id 刪除 person 表的資料 --> <delete id="deletePersonById" parameterType="Long"> delete from person where pid=#{pid} </delete> </mapper>
6、向 mybatis-config.xml 中註冊對映檔案
<mappers> <!-- 註冊PersonMapper.xml檔案 --> <mapper resource="com/itcoke/mapper/PersonMapper.xml"/> </mappers>
7、編寫測試類
1 package com.itcoke; 2 3 4 import com.itcoke.bean.Person; 5 import com.itcoke.mapper.PersonMapper; 6 import org.apache.ibatis.io.Resources; 7 import org.apache.ibatis.session.SqlSession; 8 import org.apache.ibatis.session.SqlSessionFactory; 9 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 10 import org.junit.Before; 11 import org.junit.Test; 12 13 import java.io.IOException; 14 import java.io.InputStream; 15 16 public class MybatisprojectApplicationTests { 17 // 定義SqlSessionFactory 18 SqlSessionFactory sessionFactory = null; 19 20 @Before 21 public void init() { 22 //定義mybatis全域性配置檔案 23 String resource = "mybatis-config.xml"; 24 //載入 mybatis 全域性配置檔案 25 InputStream inputStream = null; 26 try { 27 inputStream = Resources.getResourceAsStream(resource); 28 } catch (IOException e) { 29 e.printStackTrace(); 30 } 31 //構建sqlSession的工廠 32 sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 33 34 } 35 36 //根據id查詢person表資料 37 @Test 38 public void testSelectPersonById() { 39 /*這個字串由 PersonMapper.xml 檔案中 兩個部分構成 40 <mapper namespace="com.itcoke.mapper.PersonMapper"> 的 namespace 的值 41 <select id="selectPersonById" > id 值 42 */ 43 String namespace = "com.itcoke.mapper.PersonMapper"; 44 String method = "selectPersonById"; 45 //根據 sqlSessionFactory 產生 session 46 SqlSession sqlSession = sessionFactory.openSession(); 47 Person person = sqlSession.selectOne(namespace + "." + method, 1L); 48 System.out.println(person); 49 sqlSession.close(); 50 } 51 52 53 //根據id更新person表資料 54 @Test 55 public void testUpdatePersonById() { 56 String statement = "com.itcoke.mapper.PersonMapper.updatePersonById"; 57 Person p = new Person(); 58 p.setPid(2L); 59 p.setPage(18); 60 //根據 sqlSessionFactory 產生 session 61 SqlSession sqlSession = sessionFactory.openSession(); 62 sqlSession.update(statement, p); 63 sqlSession.commit(); 64 sqlSession.close(); 65 } 66 67 68 //向 person 表插入資料 69 @Test 70 public void testInsertPerson() { 71 String statement = "com.itcoke.mapper.PersonMapper.insertPerson"; 72 Person p = new Person(); 73 p.setPname("可樂"); 74 p.setPage(18); 75 //根據 sqlSessionFactory 產生 session 76 SqlSession sqlSession = sessionFactory.openSession(); 77 sqlSession.insert(statement, p); 78 sqlSession.commit(); 79 sqlSession.close(); 80 } 81 82 //根據id更新person表資料 83 @Test 84 public void testDeletePersonById() { 85 String statement = "com.itcoke.mapper.PersonMapper.deletePersonById"; 86 Person p = new Person(); 87 p.setPid(4L); 88 //根據 sqlSessionFactory 產生 session 89 SqlSession sqlSession = sessionFactory.openSession(); 90 sqlSession.delete(statement, p); 91 sqlSession.commit(); 92 sqlSession.close(); 93 } 94 }
9、通過介面
在上面的例子中,我們發現 statement 每次都要自己書寫拼接,很容易就寫錯了,這時候 MyBatis 提供了介面註冊方式。
①、在 mapper 包下面新建一個 PersonMapper 介面
注意要和 PersonMapper.xml 同名,且在同一個包下,因為要和 namespace 相同。
1 package com.itcoke.mapper; 2 3 import com.itcoke.bean.Person; 4 5 6 public interface PersonMapper { 7 8 Person selectPersonById(long pid); 9 10 void updatePersonById(Person person); 11 12 void insertPerson(Person person); 13 14 void deletePersonById(long pid); 15 }
②、測試
1 //根據id查詢person表資料 2 //通過介面代理的方式 3 @Test 4 public void testInterfaceSelectPersonById() { 5 //根據 sqlSessionFactory 產生 session 6 SqlSession sqlSession = sessionFactory.openSession(); 7 PersonMapper mapper = sqlSession.getMapper(PersonMapper.class); 8 Person person = mapper.selectPersonById(1L); 9 System.out.println(person); 10 sqlSession.close(); 11 }
8、小結
至此,我們從頭到尾擼了一遍利用 Mybatis 進行增刪改查,後面便會深入底層,梳理架構。