本文旨在用最通俗的語言講述最枯燥的基本知識java
當項目框架SSH(spring Struts hibernate)日落西山時,SSM(spring SpringMVC、MyBatis)就大行其道,大部分項目都漸漸轉至SSM,所以mybatis也成了Java程序員的必學之術,本文就mybatis的語法作一次小小的總結,旨在讓讀者用最少的時間學會使用MyBatis。mysql
文章提綱:程序員
- 什麼是MyBatis
- MyBatis的引入
- MyBatis的初始化配置
- MyBatis的SQL語法
- 運行原理和實操一波
MyBatis的前身是Apache的一個開源項目ibatis,後來遷移到Google code就更名爲MyBatis。spring
用網上已經說爛了的話來講就是:sql
MyBatis是一款優秀的持久層框架,它支持定製化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎全部的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 可使用簡單的 XML 或註解來配置和映射原生信息,將接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java對象)映射成數據庫中的記錄。數據庫
- 若是是傳統的的項目,則直接下載相應jar包引入到項目中便可,下載地址爲:
1http://central.maven.org/maven2/org/mybatis/mybatis/3.4.6/mybatis-3.4.6.jar
複製代碼
- 若是爲maven構建的項目,則只須要在pom.xml中加入如下依賴而後reimport一下便可:
1<dependency>
2 <groupId>org.mybatis</groupId>
3 <artifactId>mybatis</artifactId>
4 <version>x.x.x</version>
5</dependency>
複製代碼
- 若是是gradle構建的項目,則只須要在配置中添加如下代碼:
1// https://mvnrepository.com/artifact/org.mybatis/mybatis
2compile group: 'org.mybatis', name: 'mybatis', version: '3.4.6'
複製代碼
在引入mybatis以後,接下來須要學習的mybatis的配置,雖然如今流行的框架像springboot等已經不須要用XML方式進行配置,但做爲一名新手,咱們仍是須要學習一些關於mybatis的配置的解釋,這樣有助於咱們理解mybatis的原理。
mybatis的基本配置:編程
1<?xml version="1.0" encoding="UTF-8" ?>
2<!DOCTYPE configuration
3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
4<configuration>
5 <!--properties用於定義一些屬性變量,以便在配置文件中調用-->
6 <properties>
7 <!--定義一個變量爲driver的屬性,在下面就能夠用${driver}來得到其屬性值-->
8 <property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
9 <property name="url" value="jdbc:mysql://10.0.0.11/test"></property>
10 </properties>
11 <!--定義不一樣環境下的配置,便於區分生產、測試等環節的配置-->
12 <environments default="development">
13 <!--定義一個環境下的配置-->
14 <environment id="development">
15 <transactionManager type="JDBC"/>
16 <dataSource type="POOLED">
17 <property name="driver" value="${driver}"/>
18 <property name="url" value="${url}"/>
19 <property name="username" value="root"/>
20 <property name="password" value="1111"/>
21 </dataSource>
22 </environment>
23 </environments>
24 <!--用於設置mapper文件的引入-->
25 <mappers>
26 <!--resource方式引入mapper文件-->
27 <mapper resource="mapper/UserMapper.xml"/>
28 </mappers>
29</configuration>
複製代碼
這是一個標準的mybatis的配置文件,不少狀況下,這個配置已經足夠,可是爲了在之後的使用有更好的認識,下面講解配置文件中configuration標籤下的經常使用子標籤:設計模式
- properties標籤:用於定義一些通用屬性,便於配置文件中使用
- settings標籤:用於設置一些改變MyBatis運行時行爲的配置
- environments標籤:用於配置成適應多種環境
- mappers標籤:用於mapper映射器的設置
下面分別對每一個標籤作簡單講解:緩存
1.properties標籤
當咱們須要把一些值做爲一個變量被配置中使用時,就能夠在properties標籤下增長一個property標籤,其中屬性name是指變量名稱,屬性value是值,如:springboot
1 <properties>
2 <property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
3 </property>
複製代碼
定義好以後,就能夠在配置文件中使用了,如:
1<dataSource type="POOLED">
2 <property name="driver" value="${driver}"/>
3</dataSource>
複製代碼
2.settings標籤
settings標籤中的每個setting都是用於調整mybatis的運行行爲,咱們在須要使用其中某些setting時加入便可,其經常使用的配置以及各個setting的解釋以下:
1<settings>
2 #設置配置文件中的全部映射器已經配置的任何緩存,默認false。
3 <setting name="cacheEnabled" value="true"/>
4 #延遲加載的全局開關。當開啓時,全部關聯對象都會延遲加載,默認爲false
5 <setting name="lazyLoadingEnabled" value="true"/>
6 #是否容許單一語句返回多結果集,默認爲true
7 <setting name="multipleResultSetsEnabled" value="true"/>
8 #是否使用列標籤代替列名,默認爲true
9 <setting name="useColumnLabel" value="true"/>
10 #是否容許JDBC支持自動生成主鍵,默認爲false
11 <setting name="useGeneratedKeys" value="false"/>
12 #指定 MyBatis 應如何自動映射列到字段或屬性
13 <setting name="autoMappingBehavior" value="PARTIAL"/>
14 #指定發現自動映射目標未知列(或者未知屬性類型)的行爲,默認NONE
15 #NONE: 不作任何反應
16 #WARNING: 輸出提醒日誌
17 #FAILING: 映射失敗 (拋出 SqlSessionException)
18 <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
19 #配置默認的執行器。默認爲SIMPLE
20 #SIMPLE 就是普通的執行器;
21 #REUSE 執行器會重用預處理語句;
22 #BATCH 執行器將重用語句並執行批量更新
23 <setting name="defaultExecutorType" value="SIMPLE"/>
24 #設置超時時間,它決定驅動等待數據庫響應的秒數。
25 <setting name="defaultStatementTimeout" value="25"/>
26 #爲驅動的結果集獲取數量(fetchSize)設置一個提示值
27 <setting name="defaultFetchSize" value="100"/>
28 #是否容許在嵌套語句中使用分頁。若是容許使用則設置爲false。
29 <setting name="safeRowBoundsEnabled" value="false"/>
30 #是否開啓自動駝峯命名規則(camel case)映射,默認爲false
31 <setting name="mapUnderscoreToCamelCase" value="false"/>
32</settings>
複製代碼
3. environments
environments是爲了配置多環境數據源而生,在咱們定義好了各類環境以後,只須要在代碼中設置從哪一個環境中加載數據源便可,或者修改environments標籤中的default也能夠達到切換環境的效果。
environments的基本配置以下:
1<environments default="development">
2 #定義一個名稱爲development的環境配置
3 <environment id="development">
4 #設置事務管理器的類型,有JDBC和MANAGED梁總
5 <transactionManager type="JDBC">
6 <property name="..." value="..."/>
7 </transactionManager>
8 #數據源設置
9 <dataSource type="POOLED">
10 <property name="driver" value="${driver}"/>
11 <property name="url" value="${url}"/>
12 <property name="username" value="${username}"/>
13 <property name="password" value="${password}"/>
14 </dataSource>
15 </environment>
16</environments>
複製代碼
當咱們須要增長一個環境配置時,只須要複製粘貼一份environment,修改其中屬性的值便可。
4.mappers
mappers標籤其實是用於高速mybatis從哪找到咱們寫好的SQL語句,也就是映射文件。當咱們寫好一個表對應的mapper.xml時,咱們只須要在mappers下增長一個mapper便可。
mappers查找mapper的方式有多種:
這些mapper.xml在resources中的某個文件夾xxx中,則用resource屬性設置
1<mappers>
2<mapper resource="xxx/AMapper.xml"/>
3<mapper resource="xxx/BMapper.xml"/>
4</mappers>
複製代碼
當咱們在這些mapper.xml設置好了namespace以後,咱們能夠經過映射器接口實現類的全路徑類來設置,如在AMapper.xml設置namespace爲com.xxx.dao.AMapper類以後,咱們在這裏可使用class屬性指定查找的mapper,但前提是:
AMapper.xml和AMapper.java必須在同一個包下。
1<mappers>
2<mapper class ="com.xxx.dao.AMapper"/>
3<mapper class ="com.xxx.dao.BMapper"/>
4</mappers>
複製代碼
有人會說,若是咱們表有不少,這樣一行一行的寫不是很費勁嗎,mybatis爲了便於使用,提供了package的方式引入映射器,但前提
全部的mapper.xml和mapper.java必須在同一個包下。
1<mappers>
2 <package name="org.xxx.dao"/>
3</mappers>
複製代碼
若是你的mapper不在項目中,而是放到了其餘文件內,mybatis提供了經過URL的方式引入mapper.xml。
1<mappers>
2 <mapper url="C:///test/mappers/AMapper.xml"/>
3 <mapper url="C:///test/mappers/BMapper.xml"/>
4</mappers>
複製代碼
在現有的框架下編寫代碼,多數狀況下都不須要理會mybatis底層的東西,而大量的工做都集中在編寫mapper文件上。所以學會在mybatis下編寫SQL語句是很是有必要的,咱們首先來看一個標準的mapper文件的格式:
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3<mapper namespace="com.xxx.dao.XxxMapper">
4</mapper>
複製代碼
能夠看出,一個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<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3<mapper namespace="com.xxx.dao.XxxMapper">
4 <select id="selectUserByName" parameterType="String" resultType="hashmap">
5 select * from user where name = #{name}
6</select>
7</mapper>
複製代碼
而在具體的業務實現類中,則是這樣使用的:
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<select
2 #必填,惟一標識符,和mapper接口中的方法一一對應
3 id="selectUser"
4 #選填,默認值爲 unset,用於傳入參數的類型設置
5 parameterType="String"
6 #選填,語句查詢結果返回的指望類型,resultType 和 resultMap不能同時使用
7 resultType="HashMap"
8 #選填,語句查詢結果返回的數據集,能夠對應實體類和和resultMap定義的ID。
9 resultMap="com.xxx.entity.User"
10 #是否清除緩存,爲true時本地緩存和二級緩存都會被清除
11 flushCache="false"
12 #是否啓用緩存,爲true時查詢結果會被放入二級緩存
13 useCache="true" >
14
15 #SQL語句編寫....
16
17 </select>
複製代碼
2. update標籤
1<update
2 #必填,惟一標識符,和mapper接口中的方法一一對應
3 id="updateUser"
4 #選填,默認值爲 unset,用於傳入參數的類型設置
5 parameterType="com.xxx.entity.User"
6 #是否清除緩存,爲true時本地緩存和二級緩存都會被清除
7 flushCache="true">
8
9 #編寫update的SQL語句...
10
11</update>
複製代碼
3. insert標籤
1<insert
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</insert>
複製代碼
4. delete標籤
1<delete
2 #必填,惟一標識符,和mapper接口中的方法一一對應
3 id="updateUser"
4 #選填,默認值爲 unset,用於傳入參數的類型設置
5 parameterType="com.xxx.entity.User"
6 #是否清除緩存,爲true時本地緩存和二級緩存都會被清除
7 flushCache="true">
8
9 #編寫delete的SQL語句...
10
11</delete>
複製代碼
5. sql標籤
SQL節點用來編寫那些能夠被重用的SQL代碼段,當咱們用SQL編寫好一個代碼段以後,就能夠在其餘語句使用。
咱們都知道,在寫滿了SQL以後,若是要修改表名,是一件很痛苦的事情,由於表名都寫到了SQL語句中了,可是在mybatis中,咱們能夠利用sql標籤來定義好表名,若是在全部的SQL中引入這個代碼塊便可:
1<sql id="TABLE_NAME">user</sql>
2
3#在語句中用include的方式把表名動態化
4<select id="selectUserByName">
5select * from
6<include refid="TABLE_NAME" />
7 where name = #{name}
8</select>
複製代碼
相似的用法還有很是多,好比把查詢字段一致的能夠用sql塊統必定義,而後在須要的地方調用…須要咱們在實際使用過程,靈活運用這些標籤來減輕SQL的代碼量和下降複雜度。
6. resultMap標籤
resultMap標籤用於表示數據庫查詢結果和實體對象的映射關係,它是映射文件中中所複雜的一個標籤,經常使用的屬性有兩個:
1 <resultMap
2 #定義這個resultMap的惟一標識
3 id="XXXResult"
4 #返回值的全限定類名,或類型別名
5 type="com.xxx.entity.User">
6
7 #子節點....
8
9 </resultMap>
複製代碼
而它的子節點則就很是多了:
1 <resultMap id="XXXResult" type="java.util.HashMap">
2 #constructor:類在實例化時,用來注入結果到構造方法中
3 <constructor>
4 #idArg:ID參數;標記結果做爲ID能夠幫助提升總體效能
5 <idArg/>
6 #arg:注入到構造方法的一個普通結果
7 <arg/>
8 </constructor>
9 #一個 ID 結果;標記出做爲 ID 的結果能夠幫助提升總體性能
10 <id/>
11 #注入到字段或 JavaBean 屬性的普通結果
12 <result/>
13 #一個複雜類型的關聯;許多結果將包裝成這種類型
14 <association property=""/>
15 #一個複雜類型的集合
16 <collection property=""/>
17 # 使用結果值來決定使用哪一個 resultMap
18 <discriminator javaType="">
19 #基於某些值的結果映射
20 <case value=""></case>
21 </discriminator>!
22 </resultMap>
複製代碼
如查詢要把查詢結果的字段用駝峯的寫法映射,能夠定義一個resultMap,吧對象和實體屬性一一對應起來:
1<resultMap id="UserResultMap" type="java.util.HashMap">
2 <id column="id" property="id"/>
3 <result column="nick_name" property="nickName"/>
4 <result column="gmt_created" property="gmtCreated"/>
5 <result column="gmt_modified" property="gmtModified"/>
6 </resultMap>
複製代碼
在SQL用就能夠直接使用這個resultMap做爲返回類型:
1<select id="selectUserByName" resultMap="UserResultMap">
2 select id,nick_name,gmt_created,gmt_modified from user where name =#{name}
3</select>
複製代碼
上面的例子只用到resultMap中最經常使用的兩個子標籤: <id>、<result>。還有不少其它的標籤能夠寫成高級的resultMap,因爲篇幅較長,而文章旨在入門,所以在此暫不對每一個標籤舉例子解釋,有興趣的能夠自行百度。
看完一波語法以後,腦子處於似懂非懂的狀態,好像都是在講配置文件和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<dependencies>
2 <dependency>
3 <groupId>org.mybatis</groupId>
4 <artifactId>mybatis</artifactId>
5 <version>3.2.7</version>
6 </dependency>
7 <dependency>
8 <groupId>mysql</groupId>
9 <artifactId>mysql-connector-java</artifactId>
10 <version>6.0.6</version>
11 </dependency>
12 </dependencies>
複製代碼
- 在resources中建立一個名爲mybatis-config.xml的配置文件,內容爲:
1<?xml version="1.0" encoding="UTF-8" ?>
2<!DOCTYPE configuration
3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
4<configuration>
5 <!--properties用於定義一些屬性變量,以便在配置文件中調用-->
6 <properties>
7 <!--定義一個變量爲driver的屬性,在下面就能夠用${driver}來得到其屬性值-->
8 <property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
9 <property name="url" value="jdbc:mysql://10.9.0.111/test"></property>
10 </properties>
11 <!--定義不一樣環境下的配置,便於區分生產、測試等環節的配置-->
12 <environments default="development">
13 <!--定義一個環境下的配置-->
14 <environment id="development">
15 <transactionManager type="JDBC"/>
16 <dataSource type="POOLED">
17 <property name="driver" value="${driver}"/>
18 <property name="url" value="${url}"/>
19 <property name="username" value="root"/>
20 <property name="password" value="test100"/>
21 </dataSource>
22 </environment>
23 </environments>
24 <!--用於設置mapper文件的引入-->
25 <mappers>
26 <!--resource方式引入mapper文件-->
27 <mapper resource="mapper/UserMapper.xml"/>
28 </mappers>
29</configuration>
複製代碼
- 建立表結構:
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<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3<mapper namespace="UserMapper">
4 <select id="getUserByName" resultType="User">
5 select * from user where name =#{name}
6 </select>
7</mapper>
複製代碼
- 啓動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的測試項目,若是有問題或者須要源碼請關注公衆號留言或加微信:sisi-ceo,咱們一塊兒來征服寫代碼這作大山~
以爲本文對你有幫助?請分享給更多人
關注「編程無界」,提高裝逼技能![]()