Mybatis入門html
1、Mybatis環境搭建及簡單實例java
pom.xmlmysql
mybatis-config.xmlsql
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 7 <!-- 指定properties配置文件, 我這裏面配置的是數據庫相關 --> 8 <properties resource="dbConfig.properties"></properties> 9 10 <environments default="development"> 11 <environment id="development"> 12 <transactionManager type="JDBC"/> 13 <dataSource type="POOLED"> 14 <!-- 15 若是上面沒有指定數據庫配置的properties文件,那麼此處能夠這樣直接配置 16 <property name="driver" value="com.mysql.jdbc.Driver"/> 17 <property name="url" value="jdbc:mysql://localhost:3306/test1"/> 18 <property name="username" value="root"/> 19 <property name="password" value="root"/> 20 --> 21 22 <!-- 上面指定了數據庫配置文件, 配置文件裏面也是對應的這四個屬性 --> 23 <property name="driver" value="${driver}"/> 24 <property name="url" value="${url}"/> 25 <property name="username" value="${username}"/> 26 <property name="password" value="${password}"/> 27 28 </dataSource> 29 </environment> 30 </environments> 31 32 <!-- 映射文件,mybatis精髓, 後面纔會細講 --> 33 <mappers> 34 <mapper resource="com/dy/dao/userDao-mapping.xml"/> 35 </mappers> 36 37 </configuration>
1. configuration節點爲根節點。數據庫
2. 在configuration節點之下,咱們能夠配置10個子節點, 分別爲:properties、typeAliases、plugins、objectFactory、objectWrapperFactory、settings、environments、databaseIdProvider、typeHandlers、mappers。apache
實體類——User緩存
properties的使用方法session
envirements元素節點的使用方法mybatis
environments元素節點能夠配置多個environment子節點, 怎麼理解呢? oracle
假如咱們系統的開發環境和正式環境所用的數據庫不同(這是確定的), 那麼能夠設置兩個environment, 兩個id分別對應開發環境(dev)和正式環境(final),那麼經過配置environments的default屬性就能選擇對應的environment了, 例如,我將environments的deault屬性的值配置爲dev, 那麼就會選擇dev的environment。
typeAliases
typeHandler
Mybatis中的TypeHandler是什麼?
不管是 MyBatis 在預處理語句(PreparedStatement)中設置一個參數時,仍是從結果集中取出一個值時,都會用類型處理器將獲取的值以合適的方式轉換成 Java 類型。Mybatis默認爲咱們實現了許多TypeHandler, 當咱們沒有配置指定TypeHandler時,Mybatis會根據參數或者返回結果的不一樣,默認爲咱們選擇合適的TypeHandler處理。
配置typeHandler
1 <configuration> 2 <typeHandlers> 3 <!-- 4 當配置package的時候,mybatis會去配置的package掃描TypeHandler 5 <package name="com.dy.demo"/> 6 --> 7 8 <!-- handler屬性直接配置咱們要指定的TypeHandler --> 9 <typeHandler handler=""/> 10 11 <!-- javaType 配置java類型,例如String, 若是配上javaType, 那麼指定的typeHandler就只做用於指定的類型 --> 12 <typeHandler javaType="" handler=""/> 13 14 <!-- jdbcType 配置數據庫基本數據類型,例如varchar, 若是配上jdbcType, 那麼指定的typeHandler就只做用於指定的類型 --> 15 <typeHandler jdbcType="" handler=""/> 16 17 <!-- 也可二者都配置 --> 18 <typeHandler javaType="" jdbcType="" handler=""/> 19 20 </typeHandlers> 21 22 ...... 23 24 </configuration>
objectFactory是幹什麼的? 須要配置嗎?
MyBatis 每次建立結果對象的新實例時,它都會使用一個對象工廠(ObjectFactory)實例來完成。默認的對象工廠須要作的僅僅是實例化目標類,要麼經過默認構造方法,要麼在參數映射存在的時候經過參數構造方法來實例化。默認狀況下,咱們不須要配置,mybatis會調用默認實現的objectFactory。 除非咱們要自定義ObjectFactory的實現, 那麼咱們才須要去手動配置。
plugin有何做用? 須要配置嗎?
plugins 是一個可選配置。mybatis中的plugin其實就是個interceptor, 它能夠攔截Executor 、ParameterHandler 、ResultSetHandler 、StatementHandler 的部分方法,處理咱們本身的邏輯。Executor就是真正執行sql語句的東西, ParameterHandler 是處理咱們傳入參數的,還記得前面講TypeHandler的時候提到過,mybatis默認幫咱們實現了很多的typeHandler, 當咱們不顯示配置typeHandler的時候,mybatis會根據參數類型自動選擇合適的typeHandler執行,其實就是ParameterHandler 在選擇。ResultSetHandler 就是處理返回結果的。
mappers做用 ? 須要配置嗎?
mappers 節點下,配置咱們的mapper映射文件, 所謂的mapper映射文件,就是讓mybatis 用來創建數據表和javabean映射的一個橋樑。在咱們實際開發中,一般一個mapper文件對應一個dao接口, 這個mapper能夠看作是dao的實現。因此,mappers必須配置。
mapper映射文件配置之insert、update、delete
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper 3 PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" 4 "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd"> 5 6 <!-- mapper 爲根元素節點, 一個namespace對應一個dao --> 7 <mapper namespace="com.dy.dao.UserDao"> 8 9 <insert 10 <!-- 1. id (必須配置) 11 id是命名空間中的惟一標識符,可被用來表明這條語句。 12 一個命名空間(namespace) 對應一個dao接口, 13 這個id也應該對應dao裏面的某個方法(至關於方法的實現),所以id 應該與方法名一致 --> 14 15 id="insertUser" 16 17 <!-- 2. parameterType (可選配置, 默認爲mybatis自動選擇處理) 18 將要傳入語句的參數的徹底限定類名或別名, 若是不配置,mybatis會經過ParameterHandler 根據參數類型默認選擇合適的typeHandler進行處理 19 parameterType 主要指定參數類型,能夠是int, short, long, string等類型,也能夠是複雜類型(如對象) --> 20 21 parameterType="com.demo.User" 22 23 <!-- 3. flushCache (可選配置,默認配置爲true) 24 將其設置爲 true,任什麼時候候只要語句被調用,都會致使本地緩存和二級緩存都會被清空,默認值:true(對應插入、更新和刪除語句) --> 25 26 flushCache="true" 27 28 <!-- 4. statementType (可選配置,默認配置爲PREPARED) 29 STATEMENT,PREPARED 或 CALLABLE 的一個。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認值:PREPARED。 --> 30 31 statementType="PREPARED" 32 33 <!-- 5. keyProperty (可選配置, 默認爲unset) 34 (僅對 insert 和 update 有用)惟一標記一個屬性,MyBatis 會經過 getGeneratedKeys 的返回值或者經過 insert 語句的 selectKey 子元素設置它的鍵值,默認:unset。若是但願獲得多個生成的列,也能夠是逗號分隔的屬性名稱列表。 --> 35 36 keyProperty="" 37 38 <!-- 6. keyColumn (可選配置) 39 (僅對 insert 和 update 有用)經過生成的鍵值設置表中的列名,這個設置僅在某些數據庫(像 PostgreSQL)是必須的,當主鍵列不是表中的第一列的時候須要設置。若是但願獲得多個生成的列,也能夠是逗號分隔的屬性名稱列表。 --> 40 41 keyColumn="" 42 43 <!-- 7. useGeneratedKeys (可選配置, 默認爲false) 44 (僅對 insert 和 update 有用)這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數據庫內部生成的主鍵(好比:像 MySQL 和 SQL Server 這樣的關係數據庫管理系統的自動遞增字段),默認值:false。 --> 45 46 useGeneratedKeys="false" 47 48 <!-- 8. timeout (可選配置, 默認爲unset, 依賴驅動) 49 這個設置是在拋出異常以前,驅動程序等待數據庫返回請求結果的秒數。默認值爲 unset(依賴驅動)。 --> 50 timeout="20"> 51 52 <update 53 id="updateUser" 54 parameterType="com.demo.User" 55 flushCache="true" 56 statementType="PREPARED" 57 timeout="20"> 58 59 <delete 60 id="deleteUser" 61 parameterType="com.demo.User" 62 flushCache="true" 63 statementType="PREPARED" 64 timeout="20"> 65 </mapper>
若是咱們在使用mysql的時候,想在數據插入後返回插入的id, 咱們也可使用 selectKey 這個元素:
1 <!-- 對應userDao中的insertUser方法, --> 2 <insert id="insertUser" parameterType="com.dy.entity.User"> 3 <!-- oracle等不支持id自增加的,可根據其id生成策略,先獲取id 4 5 <selectKey resultType="int" order="BEFORE" keyProperty="id"> 6 select seq_user_id.nextval as id from dual 7 </selectKey> 8 9 --> 10 11 <!-- mysql插入數據後,獲取id --> 12 <selectKey keyProperty="id" resultType="int" order="AFTER" > 13 SELECT LAST_INSERT_ID() as id 14 </selectKey> 15 16 insert into user(id, name, password, age, deleteFlag) 17 values(#{id}, #{name}, #{password}, #{age}, #{deleteFlag}) 18 </insert>
select配置
1 <select 2 <!-- 1. id (必須配置) 3 id是命名空間中的惟一標識符,可被用來表明這條語句。 4 一個命名空間(namespace) 對應一個dao接口, 5 這個id也應該對應dao裏面的某個方法(至關於方法的實現),所以id 應該與方法名一致 --> 6 7 id="selectPerson" 8 9 <!-- 2. parameterType (可選配置, 默認爲mybatis自動選擇處理) 10 將要傳入語句的參數的徹底限定類名或別名, 若是不配置,mybatis會經過ParameterHandler 根據參數類型默認選擇合適的typeHandler進行處理 11 parameterType 主要指定參數類型,能夠是int, short, long, string等類型,也能夠是複雜類型(如對象) --> 12 parameterType="int" 13 14 <!-- 3. resultType (resultType 與 resultMap 二選一配置) 15 resultType用以指定返回類型,指定的類型能夠是基本類型,能夠是java容器,也能夠是javabean --> 16 resultType="hashmap" 17 18 <!-- 4. resultMap (resultType 與 resultMap 二選一配置) 19 resultMap用於引用咱們經過 resultMap標籤訂義的映射類型,這也是mybatis組件高級複雜映射的關鍵 --> 20 resultMap="personResultMap" 21 22 <!-- 5. flushCache (可選配置) 23 將其設置爲 true,任什麼時候候只要語句被調用,都會致使本地緩存和二級緩存都會被清空,默認值:false --> 24 flushCache="false" 25 26 <!-- 6. useCache (可選配置) 27 將其設置爲 true,將會致使本條語句的結果被二級緩存,默認值:對 select 元素爲 true --> 28 useCache="true" 29 30 <!-- 7. timeout (可選配置) 31 這個設置是在拋出異常以前,驅動程序等待數據庫返回請求結果的秒數。默認值爲 unset(依賴驅動)--> 32 timeout="10000" 33 34 <!-- 8. fetchSize (可選配置) 35 這是嘗試影響驅動程序每次批量返回的結果行數和這個設置值相等。默認值爲 unset(依賴驅動)--> 36 fetchSize="256" 37 38 <!-- 9. statementType (可選配置) 39 STATEMENT,PREPARED 或 CALLABLE 的一個。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認值:PREPARED--> 40 statementType="PREPARED" 41 42 <!-- 10. resultSetType (可選配置) 43 FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一個,默認值爲 unset (依賴驅動)--> 44 resultSetType="FORWARD_ONLY">
resultMap配置
1 <!-- 2 1.type 對應類型,能夠是javabean, 也能夠是其它 3 2.id 必須惟一, 用於標示這個resultMap的惟一性,在使用resultMap的時候,就是經過id指定 4 --> 5 <resultMap type="" id=""> 6 7 <!-- id, 惟一性,注意啦,這個id用於標示這個javabean對象的惟一性, 不必定會是數據庫的主鍵(不要把它理解爲數據庫對應表的主鍵) 8 property屬性對應javabean的屬性名,column對應數據庫表的列名 9 (這樣,當javabean的屬性與數據庫對應表的列名不一致的時候,就能經過指定這個保持正常映射了) 10 --> 11 <id property="" column=""/> 12 13 <!-- result與id相比, 對應普通屬性 --> 14 <result property="" column=""/> 15 16 <!-- 17 constructor對應javabean中的構造方法 18 --> 19 <constructor> 20 <!-- idArg 對應構造方法中的id參數 --> 21 <idArg column=""/> 22 <!-- arg 對應構造方法中的普通參數 --> 23 <arg column=""/> 24 </constructor> 25 26 <!-- 27 collection,對應javabean中容器類型, 是實現一對多的關鍵 28 property 爲javabean中容器對應字段名 29 column 爲體如今數據庫中列名 30 ofType 就是指定javabean中容器指定的類型 31 --> 32 <collection property="" column="" ofType=""></collection> 33 34 <!-- 35 association 爲關聯關係,是實現N對一的關鍵。 36 property 爲javabean中容器對應字段名 37 column 爲體如今數據庫中列名 38 javaType 指定關聯的類型 39 --> 40 <association property="" column="" javaType=""></association> 41 </resultMap>
那麼,問題來了: 什麼是動態SQL? 動態SQL有什麼做用?
傳統的使用JDBC的方法,相信你們在組合複雜的的SQL語句的時候,須要去拼接,稍不注意哪怕少了個空格,都會致使錯誤。Mybatis的動態SQL功能正是爲了解決這種問題, 其經過 if, choose, when, otherwise, trim, where, set, foreach標籤,可組合成很是靈活的SQL語句,從而提升開發人員的效率。
if
1 <select id="findUserById" resultType="user"> 2 select * from user where 3 <if test="id != null"> 4 id=#{id} 5 </if> 6 and deleteFlag=0; 7 </select>
有問題?
where
1 <select id="findUserById" resultType="user"> 2 select * from user 3 <where> 4 <if test="id != null"> 5 id=#{id} 6 </if> 7 and deleteFlag=0; 8 </where> 9 </select>
從表面上來看,就是多了個where標籤而已, 不過實質上, mybatis是對它作了處理,當它遇到AND或者OR這些,它知道怎麼處理。其實咱們能夠經過 trim 標籤去自定義這種處理規則。
trim
上面的where標籤,其實能夠用trim表示:
<trim prefix="WHERE" prefixOverrides="AND |OR "> ... </trim>
set
1 <update id="updateUser" parameterType="com.dy.entity.User"> 2 update user set 3 <if test="name != null"> 4 name = #{name}, 5 </if> 6 <if test="password != null"> 7 password = #{password}, 8 </if> 9 <if test="age != null"> 10 age = #{age} 11 </if> 12 <where> 13 <if test="id != null"> 14 id = #{id} 15 </if> 16 and deleteFlag = 0; 17 </where> 18 </update>
1 <update id="updateUser" parameterType="com.dy.entity.User"> 2 update user 3 <set> 4 <if test="name != null">name = #{name},</if> 5 <if test="password != null">password = #{password},</if> 6 <if test="age != null">age = #{age},</if> 7 </set> 8 <where> 9 <if test="id != null"> 10 id = #{id} 11 </if> 12 and deleteFlag = 0; 13 </where> 14 </update>
這個用trim 可表示爲:
<trim prefix="SET" suffixOverrides=","> ... </trim>
foreach
1 <select id="selectPostIn" resultType="domain.blog.Post"> 2 SELECT * 3 FROM POST P 4 WHERE ID in 5 <foreach item="item" index="index" collection="list" 6 open="(" separator="," close=")"> 7 #{item} 8 </foreach> 9 </select>
choose
<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <choose> <when test="title != null"> AND title like #{title} </when> <when test="author != null and author.name != null"> AND author_name like #{author.name} </when> <otherwise> AND featured = 1 </otherwise> </choose> </select>
SqlSessionFactory與sqlsession
從表面上來看,我們都是經過SqlSession去執行sql語句。那麼我們就先看看是怎麼獲取SqlSession的吧:
1 SqlSessionFactory sessionFactory = null; 2 String resource = "mybatis-conf.xml"; 3 try { 4 //SqlSessionFactoryBuilder讀取配置文件 5 sessionFactory = new SqlSessionFactoryBuilder().build(Resources 6 .getResourceAsReader(resource)); 7 } catch (IOException e) { 8 e.printStackTrace(); 9 } 10 //經過SqlSessionFactory獲取SqlSession 11 SqlSession sqlSession = sessionFactory.openSession();
SqlSession我們也拿到了,我們能夠調用SqlSession中一系列的select..., insert..., update..., delete...方法輕鬆自如的進行CRUD操做了。 就這樣? 那咱配置的映射文件去哪兒了? 別急, 我們接着往下看:
2. 利器之MapperProxy:
在mybatis中,經過MapperProxy動態代理我們的dao, 也就是說, 當我們執行本身寫的dao裏面的方法的時候,實際上是對應的mapperProxy在代理。