mybatis 第一天 mybatis的基礎知識

1.JDBC的問題

  • 數據庫經常連接和釋放:使用連接池
  • SQL硬編碼到Java代碼中,不利於維護:使用XML配置文件的形式進行維護
  • 參數硬編碼到preparedStatement中:使用XML配置參數
  • 從resultSet中獲取結果集存在硬編碼:把結果集硬編碼成Java對象

2.mybatis框架

mybatis讓程序將主要精力放在sql上,通過mybatis提供的映射方式,自由靈活生成(半自動化,大部分需要程序員編寫sql)滿足需要sql語句

3.入門程序

3.1 準備

需求:根據用戶id(主鍵)查詢用戶信息、根據用戶名稱模糊查詢用戶信息、添加用戶、刪除 用戶、更新用戶

導包:mybatis及本身依賴的包,數據庫驅動以及log4j.properties文件
在這裏插入圖片描述
創建SqlMapConfig.xml文件:配置mybatis的運行環境(不掌握),數據源

3.2 【功能1】根據用戶id(主鍵)查詢用戶信息

(1)創建用戶類User.class:對應數據庫的表結構
(2)創建映射文件UserMapper.xml:配置實現不同功能的SQL語句

#{}表示一個佔位符號
#{id}:其中的id表示接收輸入的參數,參數名稱就是id,
       如果輸入 參數是簡單類型,#{}中的參數名可以任意,可以value或其它名稱	

在這裏插入圖片描述
(3)在SqlMapConfig.xml加載映射文件
在這裏插入圖片描述
(4)創建測試類
在這裏插入圖片描述

3.3 【功能2】根據用戶名稱模糊查詢用戶信息

(1)在User.xml,添加根據用戶名稱模糊查詢用戶信息的sql語句。

${}:表示拼接sql串,將接收到參數的內容不加任何修飾拼接在sql中。
    使用${}拼接sql,引起 sql注入
${value}:接收輸入參數的內容,如果傳入類型是簡單類型,${}中只能使用value

在這裏插入圖片描述
(2)在測試類添加新函數
這裏返回的結果是對象列表,使用List類型
在這裏插入圖片描述

3.4 【功能3】添加用戶

(1)在 User.xml中配置添加用戶的Statement

parameterType:指定輸入 參數類型是pojo(包括 用戶信息)
#{}中指定pojo的屬性名,接收到pojo對象的屬性值,mybatis通過OGNL獲取對象的屬性值

在這裏插入圖片描述
(2)在測試類添加新函數
對於修改數據庫的函數,需要使用事務
在這裏插入圖片描述
(3)自增主鍵返回
功能:將插入數據的主鍵返回,返回到user對象中

SELECT LAST_INSERT_ID():得到剛insert進去記錄的主鍵值,只適用於自增主鍵
keyProperty:			 將查詢到主鍵值設置到parameterType指定的對象的哪個屬性
order:		 SELECT LAST_INSERT_ID()執行順序,相對於insert語句來說它的執行順序
resultType: 指定SELECT LAST_INSERT_ID()的結果類型

在這裏插入圖片描述
(4)非自增主鍵返回
功能:使用mysql的uuid()函數生成主鍵,需要修改表中id字段類型爲string,長度設置成35位。
執行思路
先通過uuid()查詢到主鍵,將主鍵值輸入到sql語句中。
執行uuid()語句順序在insert語句之前執行。
在這裏插入圖片描述

3.5 【功能4】刪除用戶

(1)在映射文件添加刪除語句
在這裏插入圖片描述
(2)測試函數
在這裏插入圖片描述

3.6 【功能5】更新用戶

(1)在映射文件添加更新語句
需要傳入用戶的id
需要傳入用戶的更新信息
parameterType指定user對象,包括 id和更新信息,注意:id必須存在
#{id}:從輸入 user對象中獲取id屬性值
在這裏插入圖片描述
(2)測試函數
在這裏插入圖片描述

3.7 總結

(1)parameterType
在映射文件中通過parameterType指定輸入參數的類型。
(2)resultType
在映射文件中通過resultType指定輸出結果的類型。
(3)#{}和${}

#{}表示一個佔位符號,#{}接收輸入參數,類型可以是簡單類型,pojo、hashmap。
'如果接收簡單類型,#{}中可以寫成value或其它名稱'。
#{}接收pojo對象值,通過OGNL讀取對象中的屬性值,通過屬性.屬性.屬性...的方式獲取對象屬性值。
${}表示一個拼接符號,會引用sql注入,'所以不建議使用${}'。
${}接收輸入參數,類型可以是簡單類型,pojo、hashmap。
'如果接收簡單類型,${}中只能寫成value'。
${}接收pojo對象值,通過OGNL讀取對象中的屬性值,通過屬性.屬性.屬性...的方式獲取對象屬性值。

(4)selectOne和selectList
selectOne表示查詢出一條記錄進行映射。如果使用selectOne可以實現,那麼使用selectList也可以實現(list中只有一個對象)。
selectList表示查詢出一個列表(多條記錄)進行映射。如果使用selectList查詢多條記錄,不能使用selectOne。

如果使用selectOne報錯:

org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 4

(5)mybatis和hibernate本質區別和應用場景

hibernate:是一個標準ORM框架(對象關係映射)。入門門檻較高的,不需要程序寫sql,sql語句自動生成了。
對sql語句進行優化、修改比較困難的。
應用場景:適用與需求變化不多的中小型項目,比如:後臺管理系統,erp、orm、oa。。

mybatis:專注是sql本身,需要程序員自己編寫sql語句,sql修改、優化比較方便。mybatis是一個不完全 的ORM框架,雖然程序員自己寫sql,mybatis 也可以實現映射(輸入映射、輸出映射)。
應用場景:適用與需求變化較多的項目,比如:互聯網項目。

4. mybatis開發->dao的方法

4.1 思路

上面我們每個測試方法都需要創建SqlSessionFactoryBuilder、 SqlSessionFactory和SqlSession,修改如下:

  1. SqlSessionFactoryBuilder當成一個工具類使用即可
  2. 單例模式管理sqlSessionFactory
  3. SqlSession最佳應用場合在方法體內,定義成局部變量使用

程序員需要寫dao接口和dao實現類。需要向dao實現類中注入SqlSessionFactory,在方法體內通過SqlSessionFactory創建SqlSession。

4.2 總結原始 dao開發問題

在這裏插入圖片描述

  1. dao接口實現類方法中存在大量模板方法(session的關閉等),設想能否將這些代碼提取出來,大大減輕程序員的工作量。
  2. 調用sqlsession方法時將statement的id硬編碼了(sql的映射id)
  3. 調用sqlsession方法時傳入的變量,由於sqlsession方法使用泛型,即使變量類型傳入錯誤,在編譯階段也不報錯,不利於程序員開發。

4.3 mapper代理方法

程序員編寫mapper接口需要遵循一些開發規範,mybatis可以自動生成mapper接口實現類代理對象。

mapper.java:接口文件(相當於dao接口)。接口裏面是針對數據庫的不同操作方法的集合
mapper.xml:映射文件。針對接口中不同方法配置對應的SQL語句

開發規範
1、mapper.xml:namespace等於mapper接口路徑
2、mapper.java:接口中的方法名等於mapper.xml中statement的id
3、mapper.java:接口中的方法輸入參數類型等於mapper.xml中statement的parameterType指定的類型
4、mapper.java:接口中的方法返回值類型等於mapper.xml中statement的resultType指定的類型
(1)mapper.java
在這裏插入圖片描述
(2)map.xml
在這裏插入圖片描述
(3)在SqlMapConfig.xml中加載mapper.xml
在這裏插入圖片描述
(4)測試:接口對象 = sqlSession.getMapper(接口名.class)
在這裏插入圖片描述
(5)問題總結
代理對象內部調用selectOne或selectList
如果mapper方法返回單個pojo對象(非集合對象),代理對象內部通過selectOne查詢數據庫。
如果mapper方法返回集合對象,代理對象內部通過selectList查詢數據庫。

mapper接口方法參數只能有一個是否影響系統 開發
系統框架中,dao層的代碼是被業務層公用的。
即使mapper接口只有一個參數,可以使用包裝類型的pojo滿足不同的業務方法的需求。
注意:持久層方法的參數可以包裝類型、map。。。,service方法中建議不要使用包裝類型(不利於業務層的可擴展)。

5 SqlMapConfig.xml

mybatis的全局配置文件SqlMapConfig.xml,配置內容如下:

-properties(屬性)
-settings(全局配置參數)
-typeAliases(類型別名)
-typeHandlers(類型處理器)
-objectFactory(對象工廠)
-plugins(插件)
-environments(環境集合屬性對象)
	environment(環境子屬性對象)
		transactionManager(事務管理)
		dataSource(數據源)
-mappers(映射器)

5.1 properties 屬性

MyBatis 將按照下面的順序來加載屬性:

  • 首先,讀取在 properties 元素體內定義的屬性
  • 然後,會讀取properties 元素中resource或 url 加載的屬性,它會覆蓋已讀取的同名屬性。
  • 最後,讀取parameterType傳遞的屬性,它會覆蓋已讀取的同名屬性。

建議:
不要在properties元素體內添加任何屬性值,只將屬性值定義在properties文件中。
在properties文件中定義屬性名要有一定的特殊性,如:XXXXX.XXXXX.XXXX

例如數據庫參數配置:
數據庫連接參數單獨配置在db.properties中,只需要在SqlMapConfig.xml中加載db.properties的屬性值。在SqlMapConfig.xml中就不需要對數據庫連接參數硬編碼。
在這裏插入圖片描述
在這裏插入圖片描述

5.2 settings 全局參數配置

mybatis框架在運行時可以調整一些運行參數。比如:開啓二級緩存、開啓延遲加載。。
全局參數將會影響mybatis的運行行爲。

5.3 typeAliases 類型別名(重點)

(1)可以針對parameterType或resultType指定的類型定義一些別名,在mapper.xml中通過別名定義,方便開發。
(2)默認支持別名
在這裏插入圖片描述
(3)自定義別名
單個別名
別名定義:
在這裏插入圖片描述
別名引用:
在這裏插入圖片描述
批量別名】(常用)
在這裏插入圖片描述

5.4 typeHandlers 類型處理器

mybatis中通過typeHandlers完成jdbc類型和java類型的轉換。
通常情況下,mybatis提供的類型處理器滿足日常需要,不需要自定義.

5.5 mappery 映射配置

作用在於告訴 MyBatis 到哪裏去找映射文件SQL。
(1)通過resource加載單個映射文件

<mapper resource="mapper/UserMapper.xml"/>

(2)通過mapper接口加載單個mapper
規範:需要將mapper接口類名和mapper.xml映射文件名稱保持一致,且在一個目錄中。這樣就不需要配置mapper.xml路徑。
規範的前提:使用的是mapper代理方法

<mapper class="cn.itcast.mybatis.mapper.UserMapper"/> 

(3)批量加載mapper(推薦使用)
指定mapper接口的包名,mybatis自動掃描包下邊所有mapper接口進行加載多個接口。
遵循規範:需要將mapper接口類名和mapper.xml映射文件名稱保持一致,且在一個目錄 中
規範的前提是:使用的是mapper代理方法

<package name="cn.itcast.mybatis.mapper"/>

6. 輸入映射

有時傳入查詢條件很複雜(可能包括用戶信息、其它信息,比如商品、訂單的),需要使用複雜的輸入。
針對上邊需求,建議使用自定義的包裝類型的pojo。在包裝類型的pojo中將複雜的查詢條件包裝進去。

6.1 傳遞pojo的包裝對象

(1)定義包裝類型
在這裏插入圖片描述
(2)UserMapper.xml
在UserMapper.xml中,把定義的包裝類型作爲輸入參數
在這裏插入圖片描述
(3)mapper.java
定義功能接口
在這裏插入圖片描述
(4)測試
基於接口創建對象,設置查詢條件,調用對象的方法,使用sql語句進行查詢。
在這裏插入圖片描述

6.2 hashmap

7. 輸出映射

7.1 resultType

(1)使用resultType進行輸出映射,只有查詢出來的列名和pojo中的屬性名一致,該列纔可以映射成功。
如果查詢出來的列名和pojo中的屬性名全部不一致,沒有創建pojo對象。
只要查詢出來的列名和pojo中的屬性有一個一致,就會創建pojo對象。

(2)查詢出來的結果集只有一行且一列,可以使用簡單類型進行輸出映射。

(3)輸出pojo對象和pojo列表
不管是輸出的pojo單個對象還是一個列表(list中包括pojo),在mapper.xml中resultType指定的類型是一樣的,但是在mapper.java指定的方法返回值類型不一樣

1、輸出單個pojo對象,方法返回值是單個對象類型Pojo  ————>動態代理對象調用selectOne
2、輸出pojo對象list,方法返回值是List<Pojo>  ————>動態代理對象調用selectList 

7.1 resultMap

(1)作用:如果查詢出來的列名和pojo的屬性名不一致,通過定義一個resultMap對列名和pojo屬性名之間作一個映射關係。
(2)如何定義resultMap
在UserMapper.xml中定義sql語句中不同列名對應的pojo屬性名:
在這裏插入圖片描述
(3)使用resultMap作爲statement的輸出映射類型,而不是原來的pojo類型
在這裏插入圖片描述

8. 動態sql

對sql語句進行靈活操作,通過表達式進行判斷,對sql進行靈活拼接、組裝,減少重複語句。

8.1 動態SQL語句

(1)需求:用戶信息綜合查詢列表這個statement的定義使用動態sql。對查詢條件進行判斷,如果輸入參數不爲空才進行查詢條件拼接。
(2)實現:mapper.xml文件的SQL中增加判斷語句
在這裏插入圖片描述

8.2 定義sql片段

(1)需求:將上邊實現的動態sql判斷代碼塊抽取出來,組成一個sql片段。其它的statement中就可以引用sql片段。方便程序員進行開發。
(2)實現:
在這裏插入圖片描述
在這裏插入圖片描述

8.3 foreach

向sql傳遞數組或List,mybatis使用foreach解析
(1)需求:
在用戶查詢列表的statement中增加多個id輸入查詢。

兩種sql語句:
SELECT * FROM USER WHERE id=1 OR id=10 OR id=16
SELECT * FROM USER WHERE id IN(1,10,16)

(2)實現
在輸入參數類型中添加List 屬性ids用於傳入多個id
在這裏插入圖片描述
修改mapper.xml的sql片段:
在這裏插入圖片描述
或者:
在這裏插入圖片描述
總結:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章