本文旨在用最通俗的語言講述最枯燥的基本知識
當項目框架SSH(spring Struts hibernate)日落西山時,SSM(spring SpringMVC、MyBatis)就大行其道,大部分項目都漸漸轉至SSM,所以mybatis也成了Java程序員的必學之術,本文就mybatis的語法作一次小小的總結,旨在讓讀者用最少的時間學會使用MyBatis。java
文章提綱:mysql
- 什麼是MyBatis
- MyBatis的引入
- MyBatis的初始化配置
- MyBatis的SQL語法
- 運行原理和實操一波
MyBatis的前身是Apache的一個開源項目ibatis,後來遷移到Google code就更名爲MyBatis。程序員
用網上已經說爛了的話來講就是:spring
MyBatis是一款優秀的持久層框架,它支持定製化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎全部的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 可使用簡單的 XML 或註解來配置和映射原生信息,將接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java對象)映射成數據庫中的記錄。sql
- 若是是傳統的的項目,則直接下載相應jar包引入到項目中便可,下載地址爲:
http://central.maven.org/maven2/org/mybatis/mybatis/3.4.6/mybatis-3.4.6.jar
- 若是爲maven構建的項目,則只須要在pom.xml中加入如下依賴而後reimport一下便可:
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>x.x.x</version> </dependency>
- 若是是gradle構建的項目,則只須要在配置中添加如下代碼:
// https://mvnrepository.com/artifact/org.mybatis/mybatis compile group: 'org.mybatis', name: 'mybatis', version: '3.4.6'
在引入mybatis以後,接下來須要學習的mybatis的配置,雖然如今流行的框架像springboot等已經不須要用XML方式進行配置,但做爲一名新手,咱們仍是須要學習一些關於mybatis的配置的解釋,這樣有助於咱們理解mybatis的原理。
mybatis的基本配置:數據庫
<?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> <!--properties用於定義一些屬性變量,以便在配置文件中調用--> <properties> <!--定義一個變量爲driver的屬性,在下面就能夠用${driver}來得到其屬性值--> <property name="driver" value="com.mysql.cj.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://10.0.0.111/test"></property> </properties> <!--定義不一樣環境下的配置,便於區分生產、測試等環節的配置--> <environments default="development"> <!--定義一個環境下的配置--> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="root"/> <property name="password" value="1111"/> </dataSource> </environment> </environments> <!--用於設置mapper文件的引入--> <mappers> <!--resource方式引入mapper文件--> <mapper resource="mapper/UserMapper.xml"/> </mappers> </configuration>
這是一個標準的mybatis的配置文件,不少狀況下,這個配置已經,可是爲了在之後的使用有更好的認識,下面講解配置文件中configuration標籤下的經常使用子標籤:編程
- properties標籤:用於定義一些通用屬性,便於配置文件中使用
- settings標籤:用於設置一些改變MyBatis運行時行爲的配置
- environments標籤:用於配置成適應多種環境
- mappers標籤:用於mapper映射器的設置
下面分別對每一個標籤作簡單講解:設計模式
1.properties標籤
當咱們須要把一些值做爲一個變量被配置中使用時,就能夠在properties標籤下增長一個property標籤,其中屬性name是指變量名稱,屬性value是值,如:緩存
<properties> <property name="driver" value="com.mysql.cj.jdbc.Driver"></property> </property>
定義好以後,就能夠在配置文件中使用了,如:springboot
<dataSource type="POOLED"> <property name="driver" value="${driver}"/> </dataSource>
1.settings標籤
settings標籤中的每個setting都是用於調整mybatis的運行行爲,咱們在須要使用其中某些setting時加入便可,其經常使用的配置以及各個setting的解釋以下:
<settings> #設置配置文件中的全部映射器已經配置的任何緩存,默認false。 <setting name="cacheEnabled" value="true"/> #延遲加載的全局開關。當開啓時,全部關聯對象都會延遲加載,默認爲false <setting name="lazyLoadingEnabled" value="true"/> #是否容許單一語句返回多結果集,默認爲true <setting name="multipleResultSetsEnabled" value="true"/> #是否使用列標籤代替列名,默認爲true <setting name="useColumnLabel" value="true"/> #是否容許JDBC支持自動生成主鍵,默認爲false <setting name="useGeneratedKeys" value="false"/> #指定 MyBatis 應如何自動映射列到字段或屬性 <setting name="autoMappingBehavior" value="PARTIAL"/> #指定發現自動映射目標未知列(或者未知屬性類型)的行爲,默認NONE #NONE: 不作任何反應 #WARNING: 輸出提醒日誌 #FAILING: 映射失敗 (拋出 SqlSessionException) <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/> #配置默認的執行器。默認爲SIMPLE #SIMPLE 就是普通的執行器; #REUSE 執行器會重用預處理語句; #BATCH 執行器將重用語句並執行批量更新 <setting name="defaultExecutorType" value="SIMPLE"/> #設置超時時間,它決定驅動等待數據庫響應的秒數。 <setting name="defaultStatementTimeout" value="25"/> #爲驅動的結果集獲取數量(fetchSize)設置一個提示值 <setting name="defaultFetchSize" value="100"/> #是否容許在嵌套語句中使用分頁。若是容許使用則設置爲false。 <setting name="safeRowBoundsEnabled" value="false"/> #是否開啓自動駝峯命名規則(camel case)映射,默認爲false <setting name="mapUnderscoreToCamelCase" value="false"/> </settings>
3. environments
environments是爲了配置多環境數據源而生,在咱們定義好了各類環境以後,只須要在代碼中設置從哪一個環境中加載數據源便可,或者修改environments標籤中的default也能夠達到切換環境的效果。
environments的基本配置以下:
<environments default="development"> #定義一個名稱爲development的環境配置 <environment id="development"> #設置事務管理器的類型,有JDBC和MANAGED梁總 <transactionManager type="JDBC"> <property name="..." value="..."/> </transactionManager> #數據源設置 <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments>
當咱們須要增長一個環境配置時,只須要複製粘貼一份environment,修改其中屬性的值便可。
4.mappers
mappers標籤其實是用於高速mybatis從哪找到咱們寫好的SQL語句,也就是映射文件。當咱們寫好一個表對應的mapper.xml時,咱們只須要在mappers下增長一個mapper便可。
mappers查找mapper的方式有多種:
這些mapper.xml在resources中的某個文件夾xxx中,則用resource屬性設置
<mappers> <mapper resource="xxx/AMapper.xml"/> <mapper resource="xxx/BMapper.xml"/> </mappers>
當咱們在這些mapper.xml設置好了namespace以後,咱們能夠經過映射器接口實現類的全路徑類來設置,如在AMapper.xml設置namespace爲com.xxx.dao.AMapper類以後,咱們在這裏可使用class屬性指定查找的mapper,但前提是:
AMapper.xml和AMapper.java必須在同一個包下。
<mappers> <mapper class ="com.xxx.dao.AMapper"/> <mapper class ="com.xxx.dao.BMapper"/> </mappers>
有人會說,若是咱們表有不少,這樣一行一行的寫不是很費勁嗎,mybatis爲了便於使用,提供了package的方式引入映射器,但前提
全部的mapper.xml和mapper.java必須在同一個包下。
<mappers> <package name="org.xxx.dao"/> </mappers>
若是你的mapper不在項目中,而是放到了其餘文件內,mybatis提供了經過URL的方式引入mapper.xml。
<mappers> <mapper url="C:///test/mappers/AMapper.xml"/> <mapper url="C:///test/mappers/BMapper.xml"/> </mappers>
在現有的框架下編寫代碼,多數狀況下都不須要理會mybatis底層的東西,而大量的工做都集中在編寫mapper文件上。所以學會在mybatis下編寫SQL語句是很是有必要的,咱們首先來看一個標準的mapper文件的格式:
<?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.xxx.dao.XxxMapper"> </mapper>
能夠看出,一個mapper文件的根結構是mapper標籤開始,而mapper標籤中的namespace有什麼用呢?他應該怎麼寫?
咱們知道,有一種編程思想叫作面向接口編程,就是把業務需求中具體邏輯實現和接口分開,對外只暴露接口,經過接口實現業務。而在業務需求變化時,僅須要修改實現類,而不須要變更現有的對接代碼,下降對系統的影響。
而mybatis正是基於這樣的思想,在namespace中指定該mapper對應的接口以後,不須要編寫接口實現類,mybatis會經過該綁定自動幫你找到對應要執行的SQL語句。
如:在com.xxx.dao中建立一個XxxMapper.java的接口,須要編寫一根據用戶查詢用戶信息的方法。
package com.xxx.dao; public interface XxxMapper { //根據姓名查詢一條用戶信息 Map selectUserByName(@Param("name") String name); }
此時咱們就能夠在mapper.xml中設置namespace對應到上面的接口來:
<?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.xxx.dao.XxxMapper"> <select id="selectUserByName" parameterType="String" resultType="hashmap"> select * from user where name = #{name} </select> </mapper>
而在具體的業務實現類中,則是這樣使用的:
@Service public class XxxServiceImpl implements CustomerInfoService { @Resource private XxxMapper xxxMapper=null; @Override public Map getUser(String name) { return xxxMapper.selectUserByName(name); } }
能夠看出,從編寫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元素配備了很是多的屬性,一下僅列出最經常使用的幾個屬性以及做用解釋:
<select #必填,惟一標識符,和mapper接口中的方法一一對應 id="selectUser" #選填,默認值爲 unset,用於傳入參數的類型設置 parameterType="String" #選填,語句查詢結果返回的指望類型,resultType 和 resultMap不能同時使用 resultType="HashMap" #選填,語句查詢結果返回的數據集,能夠對應實體類和和resultMap定義的ID。 resultMap="com.xxx.entity.User" #是否清除緩存,爲true時本地緩存和二級緩存都會被清除 flushCache="false" #是否啓用緩存,爲true時查詢結果會被放入二級緩存 useCache="true" > #SQL語句編寫.... </select>
2. update標籤
<update #必填,惟一標識符,和mapper接口中的方法一一對應 id="updateUser" #選填,默認值爲 unset,用於傳入參數的類型設置 parameterType="com.xxx.entity.User" #是否清除緩存,爲true時本地緩存和二級緩存都會被清除 flushCache="true"> #編寫update的SQL語句... </update>
3. insert標籤
<insert #必填,惟一標識符,和mapper接口中的方法一一對應 id="updateUser" #選填,默認值爲 unset,用於傳入參數的類型設置 parameterType="com.xxx.entity.User" #是否清除緩存,爲true時本地緩存和二級緩存都會被清除 flushCache="true" #是否取出由數據庫內部生成的主鍵,默認爲false useGeneratedKeys="false" #選填,設置了以後,會經過getGeneratedKeys的返回值或者經過 insert語句的selectKey子元素設置它的鍵值。 keyProperty="id" > #編寫insert的SQL語句... </insert>
4. delete標籤
<delete #必填,惟一標識符,和mapper接口中的方法一一對應 id="updateUser" #選填,默認值爲 unset,用於傳入參數的類型設置 parameterType="com.xxx.entity.User" #是否清除緩存,爲true時本地緩存和二級緩存都會被清除 flushCache="true"> #編寫delete的SQL語句... </delete>
5. sql標籤
SQL節點用來編寫那些能夠被重用的SQL代碼段,當咱們用SQL編寫好一個代碼段以後,就能夠在其餘語句使用。
咱們都知道,在寫滿了SQL以後,若是要修改表名,是一件很痛苦的事情,由於表名都寫到了SQL語句中了,可是在mybatis中,咱們能夠利用sql標籤來定義好表名,若是在全部的SQL中引入這個代碼塊便可:
<sql id="TABLE_NAME">user</sql> #在語句中用include的方式把表名動態化 <select id="selectUserByName"> select * from <include refid="TABLE_NAME" /> where name = #{name} </select>
相似的用法還有很是多,好比把查詢字段一致的能夠用sql塊統必定義,而後在須要的地方調用...須要咱們在實際使用過程,靈活運用這些標籤來減輕SQL的代碼量和下降複雜度。
6. resultMap標籤
resultMap標籤用於表示數據庫查詢結果和實體對象的映射關係,它是映射文件中中所複雜的一個標籤,經常使用的屬性有兩個:
<resultMap #定義這個resultMap的惟一標識 id="XXXResult" #返回值的全限定類名,或類型別名 type="com.xxx.entity.User"> #子節點.... </resultMap>
而它的子節點則就很是多了:
<resultMap id="XXXResult" type="java.util.HashMap"> #constructor:類在實例化時,用來注入結果到構造方法中 <constructor> #idArg:ID參數;標記結果做爲ID能夠幫助提升總體效能 <idArg/> #arg:注入到構造方法的一個普通結果 <arg/> </constructor> #一個 ID 結果;標記出做爲 ID 的結果能夠幫助提升總體性能 <id/> #注入到字段或 JavaBean 屬性的普通結果 <result/> #一個複雜類型的關聯;許多結果將包裝成這種類型 <association property=""/> #一個複雜類型的集合 <collection property=""/> # 使用結果值來決定使用哪一個 resultMap <discriminator javaType=""> #基於某些值的結果映射 <case value=""></case> </discriminator>! </resultMap>
如查詢要把查詢結果的字段用駝峯的寫法映射,能夠定義一個resultMap,吧對象和實體屬性一一對應起來:
<resultMap id="UserResultMap" type="java.util.HashMap"> <id column="id" property="id"/> <result column="nick_name" property="nickName"/> <result column="gmt_created" property="gmtCreated"/> <result column="gmt_modified" property="gmtModified"/> </resultMap>
在SQL用就能夠直接使用這個resultMap做爲返回類型:
<select id="selectUserByName" resultMap="UserResultMap"> select id,nick_name,gmt_created,gmt_modified from user where name =#{name} </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中的依賴爲:
<dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.7</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.6</version> </dependency> </dependencies>
- 在resources中建立一個名爲mybatis-config.xml的配置文件,內容爲:
<?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> <!--properties用於定義一些屬性變量,以便在配置文件中調用--> <properties> <!--定義一個變量爲driver的屬性,在下面就能夠用${driver}來得到其屬性值--> <property name="driver" value="com.mysql.cj.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://10.9.0.111/test"></property> </properties> <!--定義不一樣環境下的配置,便於區分生產、測試等環節的配置--> <environments default="development"> <!--定義一個環境下的配置--> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="root"/> <property name="password" value="test100"/> </dataSource> </environment> </environments> <!--用於設置mapper文件的引入--> <mappers> <!--resource方式引入mapper文件--> <mapper resource="mapper/UserMapper.xml"/> </mappers> </configuration>
- 建立表結構:
DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `gmt_created` varchar(255) DEFAULT NULL, `gmt_modified` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4; -- 插入一條數 INSERT INTO `user` VALUES ('1', 'hello mybatis', null, null);
- 在java下建立User.java的實體類(注意:爲了簡化代碼,getter和serter已經去掉,實操時自行補上):
public class User { private Integer id; private String name; private String gmtCreated; private String gmtModified; //getter 和 setter... }
- 在java下建立UserMapper.java的映射類:
public interface UserMapper { User getUserByName(@Param("name") String name); }
- 在resources下建立mapper文件夾,在mapper下建立UserMapper的xml文件:
<?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="UserMapper"> <select id="getUserByName" resultType="User"> select * from user where name =#{name} </select> </mapper>
- 啓動mybatis執行SQL
根據上面的運行流程,就能夠編寫一個測試類:
public static void main(String args[]){ try { String resource = "mybatis-config.xml"; // 1. 獲取配置文件的輸入流 InputStream inputStream = Resources.getResourceAsStream(resource); // 2. 讀取配置文件並用SqlSessionFactoryBuilder建立一個SqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 3. 從SqlSessionFactory中獲取一個SqlSession SqlSession s= sqlSessionFactory.openSession(); // 4. 查找映射SQL文件 UserMapper mapper=s.getMapper(UserMapper.class); // 5.執行CURD操做 User user=mapper.getUserByName("hello mybatis"); if(user!=null){ System.out.print("查詢成功,個人名次是:"+user.getName()); } }catch (Exception e){ e.printStackTrace(); } }
查看輸出:
查詢成功,個人名次是:hello mybatis
大功告成!有興趣的讀者能夠根據上面的過程,編寫屬於本身的原生態mybatis的測試項目,若是有問題或者須要源碼請關注公衆號留言或加微信:sisi-ceo,咱們一塊兒來征服寫代碼這作大山~
以爲本文對你有幫助?請分享給更多人
關注「編程無界」,提高裝逼技能
![]()