30分鐘入門MyBatis

來自:編程無界(id:qianshic)

30分鐘入門MyBatis


本文旨在用最通俗的語言講述最枯燥的基本知識

當項目框架SSH(spring、Struts、Hibernate)日落西山時,SSM(spring、SpringMVC、MyBatis)就大行其道,大部分項目都漸漸轉至SSM,因此MyBatis也成了Java程序員的必學知識,本文就mybatis的語法做一次小小的總結,旨在讓讀者用最少的時間學會使用MyBatis。

文章提綱:

  • 什麼是MyBatis
  • MyBatis的引入
  • MyBatis的配置
  • MyBatis的SQL語法
  • 運行原理和實操一波

1. 什麼是MyBatis

MyBatis的前身是Apache的一個開源項目ibatis,後來遷移到Google code就改名為MyBatis。

用網上已經說爛了的話來說就是:

MyBatis是一款優秀的持久層框架,它支持定製化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 可以使用簡單的 XML 或註解來配置和映射原生信息,將接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java對象)映射成數據庫中的記錄。

2. MyBatis的引入

  • 如果是傳統的的項目,則直接下載相應jar包引入到項目中即可,下載地址為:
1http://central.maven.org/maven2/org/mybatis/mybatis/3.4.6/mybatis-3.4.6.jar
  • 如果為maven構建的項目,則只需要在pom.xml中加入以下依賴然後reimport一下即可:
1
2 org.mybatis
3 mybatis
4 x.x.x
5

  • 如果是gradle構建的項目,則只需要在配置中添加以下代碼:
1// https://mvnrepository.com/artifact/org.mybatis/mybatis
2compile group: 'org.mybatis', name: 'mybatis', version: '3.4.6'

3. MyBatis的配置和初始化

在引入mybatis之後,接下來需要學習的mybatis的配置,雖然現在流行的框架像springboot等已經不需要用XML方式進行配置,但作為一名新手,我們還是需要學習一些關於mybatis的配置的解釋,這樣有助於我們理解mybatis的原理。

mybatis的基本配置:

 1
2br> 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
4
5
6
7
8
9
10

11
12
13
14
15

16
17
18
19
20
21

22

23

24
25
26
27
28

29

這是一個標準的mybatis的配置文件,很多情況下,這個配置已經足夠,但是為了在以後的使用有更好的認識,下面講解配置文件中configuration標籤下的常用子標籤:

  • properties標籤:用於定義一些通用屬性,便於配置文件中使用
  • settings標籤:用於設置一些改變MyBatis運行時行為的配置
  • environments標籤:用於配置成適應多種環境
  • mappers標籤:用於mapper映射器的設置

下面分別對每個標籤做簡單講解:

1.properties標籤

當我們需要把一些值作為一個變量被配置中使用時,就可以在properties標籤下增加一個property標籤,其中屬性name是指變量名稱,屬性value是值,如:

1 
2
3

定義好之後,就可以在配置文件中使用了,如:

1
2
3

2.settings標籤

settings標籤中的每一個setting都是用於調整mybatis的運行行為,我們在需要使用其中某些setting時加入即可,其常用的配置以及各個setting的解釋如下:

 1
2 #設置配置文件中的所有映射器已經配置的任何緩存,默認false。
3
4 #延遲加載的全局開關。當開啟時,所有關聯對象都會延遲加載,默認為false
5
6 #是否允許單一語句返回多結果集,默認為true
7
8 #是否使用列標籤代替列名,默認為true
9
10 #是否允許JDBC支持自動生成主鍵,默認為false
11
12 #指定 MyBatis 應如何自動映射列到字段或屬性
13
14 #指定發現自動映射目標未知列(或者未知屬性類型)的行為,默認NONE
15 #NONE: 不做任何反應
16 #WARNING: 輸出提醒日誌
17 #FAILING: 映射失敗 (拋出 SqlSessionException)
18
19 #配置默認的執行器。默認為SIMPLE
20 #SIMPLE 就是普通的執行器;
21 #REUSE 執行器會重用預處理語句;

22 #BATCH 執行器將重用語句並執行批量更新
23
24 #設置超時時間,它決定驅動等待數據庫響應的秒數。
25
26 #為驅動的結果集獲取數量(fetchSize)設置一個提示值
27
28 #是否允許在嵌套語句中使用分頁。如果允許使用則設置為false。
29
30 #是否開啟自動駝峰命名規則(camel case)映射,默認為false
31
32

3. environments

environments是為了配置多環境數據源而生,在我們定義好了各種環境之後,只需要在代碼中設置從哪個環境中加載數據源即可,或者修改environments標籤中的default也可以達到切換環境的效果。

environments的基本配置如下:

 1
2 #定義一個名稱為development的環境配置
3

4 #設置事務管理器的類型,有JDBC和MANAGED梁總
5
6
7

8 #數據源設置
9
10
11
12
13
14

15

16

當我們需要增加一個環境配置時,只需要複製粘貼一份environment,修改其中屬性的值即可。

4.mappers

mappers標籤實際上是用於高速mybatis從哪找到我們寫好的SQL語句,也就是映射文件。當我們寫好一個表對應的mapper.xml時,我們只需要在mappers下增加一個mapper即可。

mappers查找mapper的方式有多種:

1. 根據mapper.xml文件定位:

這些mapper.xml在resources中的某個文件夾xxx中,則用resource屬性設置

1
2
3
4

2. 根據映射器接口實現類的完全限定類名:

當我們在這些mapper.xml設置好了namespace之後,我們可以通過映射器接口實現類的全路徑類來設置,如在AMapper.xml設置namespace為com.xxx.dao.AMapper類之後,我們在這裡可以使用class屬性指定查找的mapper,但前提是:

AMapper.xml和AMapper.java必須在同一個包下。

1
2
3
4

3. 包映射

有人會說,如果我們表有很多,這樣一行一行的寫不是很費勁嗎,mybatis為了便於使用,提供了package的方式引入映射器,但前提

所有的mapper.xml和mapper.java必須在同一個包下。

1
2
3

4. URL映射:

如果你的mapper不在項目中,而是放到了其他文件內,mybatis提供了通過URL的方式引入mapper.xml。

1
2
3
4

5. MyBatis的SQL語法

在現有的框架下編寫代碼,多數情況下都不需要理會mybatis底層的東西,而大量的工作都集中在編寫mapper文件上。因此學會在mybatis下編寫SQL語句是非常有必要的,我們首先來看一個標準的mapper文件的格式:

1
2
3
4

可以看出,一個mapper文件的根結構是mapper標籤開始,而mapper標籤中的namespace有什麼用呢?他應該怎麼寫?

我們知道,有一種編程思想叫做面向接口編程,就是把業務需求中具體邏輯實現和接口分開,對外只暴露接口,通過接口實現業務。而在業務需求變化時,僅需要修改實現類,而不需要變動現有的對接代碼,降低對系統的影響。

而mybatis正是基於這樣的思想,在namespace中指定該mapper對應的接口之後,不需要編寫接口實現類,mybatis會通過該綁定自動幫你找到對應要執行的SQL語句。

如:在com.xxx.dao中創建一個XxxMapper.java的接口,需要編寫一根據用戶查詢用戶信息的方法。

1package com.xxx.dao;
2public interface XxxMapper {
3 //根據姓名查詢一條用戶信息
4 Map selectUserByName(@Param("name") String name);
5}

此時我們就可以在mapper.xml中設置namespace對應到上面的接口來:

1
2
3
4
7

而在具體的業務實現類中,則是這樣使用的:

1@Service
2public class XxxServiceImpl implements CustomerInfoService {
3 @Resource
4 private XxxMapper xxxMapper=null;
5 @Override
6 public Map getUser(String name) {
7 return xxxMapper.selectUserByName(name);
8 }
9}

可以看出,從編寫SQL語句到最終業務調用SQL語句的過程中,我們並沒有給XxxMapper接口編寫任何的實現類,這就是基於接口編程的思想,mybatis已經把這些事情都處理好了,我們只需要在namespace中把SQL映射文件和接口類對應起來,就可以使用了。

知道根節點mapper怎麼設置之後,接下來我們需要學習如何在mapper節點裡編寫SQL語句,在mapper標籤後,mybatis提供了很多語義化的標籤以便於我們編寫SQL語句和配置映射文件,下面是幾個非常常用子標籤:

1. select:用於編寫查詢語句的標籤

2. update:用於編寫update語句的標籤

3. insert:用於編寫insert語句的標籤

4. delete:用於編寫delete語句的標籤

5. sql:編寫語句塊的標籤,可被其它語句引用

6. resultMap:定義數據庫結果和實體屬性的映射關係

這些標籤都是我們在編寫SQL語句中的必備標籤,下面一一描述他們的使用。

1. select標籤

在一個項目中,大部分功能都涉及到查詢,因此mybatis也為select元素配備了非常多的屬性,一下僅列出最常用的幾個屬性以及作用解釋:

 1 

2. update標籤

 1 2 #必填,唯一標識符,和mapper接口中的方法一一對應
3 id="updateUser"
4 #選填,默認值為 unset,用於傳入參數的類型設置
5 parameterType="com.xxx.entity.User"
6 #是否清除緩存,為true時本地緩存和二級緩存都會被清除
7 flushCache="true">

8
9 #編寫update的SQL語句...
10
11

3. insert標籤

 1 2 #必填,唯一標識符,和mapper接口中的方法一一對應
3 id="updateUser"
4 #選填,默認值為 unset,用於傳入參數的類型設置
5 parameterType="com.xxx.entity.User"
6 #是否清除緩存,為true時本地緩存和二級緩存都會被清除
7 flushCache="true"
8 #是否取出由數據庫內部生成的主鍵,默認為false
9 useGeneratedKeys="false"
10 #選填,設置了之後,會通過getGeneratedKeys的返回值或者通過 insert語句的selectKey子元素設置它的鍵值。
11 keyProperty="id"
12 >
13
14 #編寫insert的SQL語句...
15
16

4. delete標籤

 1 2 #必填,唯一標識符,和mapper接口中的方法一一對應 

3 id="updateUser"
4 #選填,默認值為 unset,用於傳入參數的類型設置
5 parameterType="com.xxx.entity.User"
6 #是否清除緩存,為true時本地緩存和二級緩存都會被清除
7 flushCache="true">
8
9 #編寫delete的SQL語句...
10
11

5. sql標籤

SQL節點用來編寫那些可以被重用的SQL代碼段,當我們用SQL編寫好一個代碼段之後,就可以在其他語句使用。

我們都知道,在寫滿了SQL之後,如果要修改表名,是一件很痛苦的事情,因為表名都寫到了SQL語句中了,但是在mybatis中,我們可以利用sql標籤來定義好表名,如果在所有的SQL中引入這個代碼塊即可:

1user
2
3#在語句中用include的方式把表名動態化
4

類似的用法還有非常多,比如把查詢字段一致的可以用sql塊統一定義,然後在需要的地方調用…需要我們在實際使用過程,靈活運用這些標籤來減輕SQL的代碼量和降低複雜度。

6. resultMap標籤

resultMap標籤用於表示數據庫查詢結果和實體對象的映射關係,它是映射文件中中所複雜的一個標籤,常用的屬性有兩個:

1 2 #定義這個resultMap的唯一標識
3 id="XXXResult"
4 #返回值的全限定類名,或類型別名
5 type="com.xxx.entity.User">
6
7 #子節點....
8
9

而它的子節點則就非常多了:

 1  
2 #constructor:類在實例化時,用來注入結果到構造方法中
3
4 #idArg:ID參數;標記結果作為ID可以幫助提高整體效能

5
6 #arg:注入到構造方法的一個普通結果
7
8

9 #一個 ID 結果;標記出作為 ID 的結果可以幫助提高整體性能
10
11 #注入到字段或 JavaBean 屬性的普通結果
12
13 #一個複雜類型的關聯;許多結果將包裝成這種類型
14
15 #一個複雜類型的集合
16
17 # 使用結果值來決定使用哪個 resultMap
18
19 #基於某些值的結果映射
20
21

22

如查詢要把查詢結果的字段用駝峰的寫法映射,可以定義一個resultMap,吧對象和實體屬性一一對應起來:

1
2

3
4
5
6

在SQL用就可以直接使用這個resultMap作為返回類型:

1

上面的例子只用到resultMap中最常用的兩個子標籤: 。還有很多其它的標籤可以寫成高級的resultMap,由於篇幅較長,而文章旨在入門,因此在此暫不對每個標籤舉例子解釋,有興趣的可以自行百度。

6. 運行原理和實操一波

看完一波語法之後,腦子處於似懂非懂的狀態,好像都是在講配置文件和mapper的使用。當我們學會了編寫這些mapper之後,究竟應該怎麼使用它?

到這裡我們就不得不提一下mybatis的運行過程了,先了解幾個mybatis提供的接口/類:

  • SqlSessionFactoryBuilder : SqlSessionFactory的構造器,用於創建SqlSessionFactory,採用了Builder設計模式。
  • SqlSessionFactory:SqlSession工廠類,以工廠形式創建SqlSession對象,採用了Factory工廠設計模式。
  • SqlSession:執行SQL的接口

由於mybatis的運行原理非常複雜,遠遠不是30分鐘能掌握的,因此在此只是概括為最大的四個過程:

  • 加載配置創建SqlSessionFacotry
  • 通過sqlSessionFactory獲取SqlSession
  • SqlSession查找和轉化Mapper
  • SqlSession執行mapper中的SQL語句

知道了運行流程之後,我們就可以實操一波了,雖然主流的開發框架都已經看不見這些東西了,但作者還是決定拋棄一切框架,只用maven構建一個空白項目進行實操:

  • 在idea上創建一個maven項目,並且在pom中引入mybatis和mysql依賴

這個簡單,不多描述。

其中pom中的依賴為:

 1
2
3 org.mybatis
4 mybatis
5 3.2.7
6

7
8 mysql
9 mysql-connector-java
10 6.0.6
11

12

  • 在resources中創建一個名為mybatis-config.xml的配置文件,內容為:
 1
2br> 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
4
5
6
7

8
9
10

11
12
13
14
15
16
17
18
19
20
21

22

23

24
25
26
27
28

29

  • 創建表結構:
 1DROP TABLE IF EXISTS `user`;
2CREATE TABLE `user` (
3 `id` int(11) NOT NULL AUTO_INCREMENT,
4 `name` varchar(255) DEFAULT NULL,
5 `gmt_created` varchar(255) DEFAULT NULL,
6 `gmt_modified` varchar(255) DEFAULT NULL,
7 PRIMARY KEY (`id`)
8) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
9-- 插入一條數
10INSERT INTO `user` VALUES ('1', 'hello mybatis', null, null);
  • 在java下創建User.java的實體類(注意:為了簡化代碼,getter和serter已經去掉,實操時自行補上):
1public class User {
2 private Integer id;
3 private String name;
4 private String gmtCreated;
5 private String gmtModified;
6 //getter 和 setter...
7}
  • 在java下創建UserMapper.java的映射類:
1public interface UserMapper {
2 User getUserByName(@Param("name") String name);
3}
  • 在resources下創建mapper文件夾,在mapper下創建UserMapper的xml文件:
1
2
3
4
7

  • 啟動mybatis執行SQL

根據上面的運行流程,就可以編寫一個測試類:

 1 public static void main(String args[]){
2 try {
3 String resource = "mybatis-config.xml";
4// 1. 獲取配置文件的輸入流
5 InputStream inputStream = Resources.getResourceAsStream(resource);
6// 2. 讀取配置文件並用SqlSessionFactoryBuilder創建一個SqlSessionFactory
7 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
8// 3. 從SqlSessionFactory中獲取一個SqlSession
9 SqlSession s= sqlSessionFactory.openSession();
10// 4. 查找映射SQL文件
11 UserMapper mapper=s.getMapper(UserMapper.class);
12// 5.執行CURD操作
13 User user=mapper.getUserByName("hello mybatis");
14
15 if(user!=null){
16 System.out.print("查詢成功,我的名次是:"+user.getName());
17 }
18
19 }catch (Exception e){
20 e.printStackTrace();
21 }

22 }

查看輸出:

1查詢成功,我的名次是:hello mybatis

大功告成!有興趣的讀者可以根據上面的過程,編寫屬於自己的原生態mybatis的測試項目


分享到:


相關文章: