【超詳細】Mybatis基礎及核心知識點總結

使用jdbc開發時,和mybatis相比的不足 
1,數據庫連接,使用時就創建,不使用就釋放,對數據庫進行頻繁連接開關和關閉,造成數據庫資源浪費,影響數據庫的性能 
解決:使用數據庫連接池管理數據庫的連接 
2,sql語句使用硬編碼在java程序中,修改sql語句,就需要重新編譯java代碼,不利於系統維護 
解決:把sql語句放在xml配置文件中,修改sql語句也不需要重新編譯java代碼 
3,向預編譯語句PreparedStatement中設置參數,對佔位符位置和設置參數值,硬編碼,修改sql語句也不需要重新編譯java代碼 
解決:把sql語句和佔位符設置參數值放在xml配置文件中 
4,從result中遍歷結果集數據時,存在硬編碼,將獲取表的字段進行硬編碼 
解決:將查詢的結果集,自動映射成 java對象

二 mybatis框架,是一個持久層框架,是apache下的頂級項目 
mybatis讓程序員將主要精力放在sql上,通過mytabis提供的映射方式,自動生成滿足需要的sql語句 
mybatis可以向PreparedStatement中輸入參數自動進行輸入映射,將查詢結果集靈活的映射成Java對象(輸出映射),輸入映射和輸出映射這是mybatis的核心 
mybatis框架執行流程圖 
這裏寫圖片描述
三 mybatis的工作環境搭建和架構示意圖 
這裏寫圖片描述 
四 mybatis的開發 
1.映射文件的開發如下圖 
這裏寫圖片描述
2,映射文件配置好了之後,還需要在全局配置文件sqlMapConfig.xml中添加映射文件 
這裏寫圖片描述 
3,sqlsession會話去執行操作查詢數據庫映射文件,下圖中的錯誤糾正爲’%${value}%’ 
這裏寫圖片描述
查詢出的是單條記錄使用selectOne,下圖中的錯誤糾正爲把“1”改爲int類型的1 
sqlsession.selectOne(“test.findUserById”, 1); 
這裏寫圖片描述 
查詢出的是多條記錄使用selectList 
sqlsession.selectList(“test.findUserByName”, “hello”); 
這裏寫圖片描述 
4,添加用戶映射文件配置如下: 
這裏寫圖片描述
程序代碼: 
這裏寫圖片描述
5,總結: 
這裏寫圖片描述 
四 mybatis開發dao方法 
mybatis的配置文件不變 
1,先使用原型的開發dao方法 
開發接口 
這裏寫圖片描述 
2, 開發接口實現 
這裏寫圖片描述 
3, 測試代碼 
這裏寫圖片描述
4,總結 
這裏寫圖片描述 
五 mybatis利用mapper代理開發dao(重點掌握) 
mapper代理開發,就不需要接口的實現類,只需要接口UserMapper.java和映射文件UserMapper.xml就可以了,但是遵循一定的開發規範: 
1,在UserMapper.xml文件中namespace等於UserMapper接口地址 
這裏寫圖片描述 
2,UserMapper.java接口中的方法名要和UserMapper.xml中的statement的id一致 
3,UserMapper.java接口中的方法輸入參數要和UserMapper.xml中的statement的parameterType指定的類型一致 
4,UserMapper.java接口中的方法的返回值類型要和UserMapper.xml中的statement的resultType指定的類型一致 
測試代碼: 
這裏寫圖片描述 
上圖畫線區域:這裏沒有實現接口的實現類,而是使用mybatis生成的代理對象來生成UserMappper接口的對象,從而能夠調用其方法

mapper代理開發dao出現的問題總結: 
1,代理對象內部調用selectOne或selectList 
如果mapper方法返回單個pojo對象(非集合對象),代理對象內部通過selectOne查詢數據庫,也可以使用selectList查詢。 
如果mapper方法返回集合對象,代理對象內部通過selectList查詢 數據庫,不能使用selectOne查詢,否則會出錯。 
問題是: 編譯期間不會報錯,二者容易寫錯使用。 
2,mapper接口方法參數只有一個 
根據規範編寫的代理對象的傳入參數只能有一個(mapper.xml文件中的parameterType參數只有一個),不利於系統的擴展 
解決:即使mapper接口中只有一個參數,可以使用包裝類型的pojo滿足不同的業務方法需求

mybatis的一些細節剖析:

1,全局配置文件sqlMapConfig.xml中配置內容如下:

  1. properties(屬性) 
    注意:mybatis將按照下面的順序來加載屬性: 
    (1)在properties元素體內定義的屬性首先被讀取。(可以在此屬性中加入jdbc的配置文件db.properties),在sqlMapConfig.xml中就不需要對數據庫連接參數進行硬編碼了。 

  2. settings全局參數設置 
    mybatis框架運行時可以調整一些運行參數,會影響mybatis運行行爲,所以建議不要隨便修改 
    比如:二級緩存,開啓延時加載。。。

  3. typeAliases(別名) 重點掌握 
    這裏寫圖片描述
  <typeAliases>
           <!--針對單個別名定義
               type:類型的路徑
               alias:別名 -->
          <typeAlias type="com.jary.mybatis.po.User" alias="user" />
          <!--還可以進行批量別名定義
          指定包名,mybatis自動掃描包中的po類 -->
          <package name="com.jary.mybatis.po" />
      </typeAliases> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

上面的別名定義後,在mapper.xml中就可以這樣使用了 

user代替了輸出結果類型com.jary.mybatis.po.User。

4.映射文件(mapper)

通過resource加載單個的映射文件

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

通過mapper接口加載單個mapper,要遵循一定的規範: 
(1)前提是使用mapper代理開發(已經有4個規範) 
(2)需要將mapper接口類名和mapper.xml映射文件名稱保持一致,且在同一目錄下 
這裏寫圖片描述

<mapper class="com.jary.mybatis.mapper.UserMapper" />
  • 1

通過批量加載mapper(推薦使用):實現條件是 
要滿足mapper接口加載映射文件和使用mapper代理開發同時滿足 
這裏寫圖片描述 
mybatis的一些細節剖析結束

mybatis的核心輸入映射和輸出映射開始:

輸入映射 
通過parameterType指定輸入參數類型,類型可以是簡單類型、hashmap、pojo的包裝類型 
1,傳遞pojo的包裝對象 
(1)需求 
完成用戶信息的綜合查詢,需要傳入查詢條件複雜(可能包括用戶信息,商品信息,商品訂單等),這樣靠一個parameterType只能傳入一個輸入參數,所有需要pojo的包裝類型來實現 
(2)定義包裝類型pojo 
針對上面的需求,在包裝類型的pojo中把這些複雜的查詢條件包裝進去,定義包裝類UserQueryVo,把需要查詢的條件全部定義在裏面 
這裏寫圖片描述 
上圖中標註的用戶查詢條件使用的是User的擴展類(因爲User類一般是由逆向工程自動生成的,不要進行修改,所有使用的擴展類來實現) 
映射文件UserMapper.xml配置 
這裏寫圖片描述 
UserMapper.java接口文件的配置 
這裏寫圖片描述 
上圖中,把包裝類作爲參數傳入,返回值是一個用戶列表所以用list集合接收

測試代碼如下圖: 
這裏寫圖片描述

輸出映射 
1,resultType 
使用resultType進行輸出映射時,只有查詢輸出結果列名和pojo中的屬性名一致纔可以,映射成功 
如果查詢出來的列名和pojo中的屬性名沒有一個一致的,就不會創建pojo對象 
如果查詢出來的列名和pojo中的屬性名有一個一致,就會創建pojo對象 
輸出pojo對象和pojo列表 
不管是輸出的pojo單個對象還是一個列表(list中包含pojo),在mapper.xml中resultType指定的類型是一樣的 
在mapper.java指定的方法返回值類型不一樣: 
(1)輸出單個pojo對象,方法返回值是個單個對象類型 
(2)輸出pojo對象list,方法返回值就是list對象類型 
在動態代理對象中,是根據mapper方法的返回值類型來確定是調用selectOne(返回單個對象)還是selectList(返回集合對象) 
2,resultMap 
使用resultMap進行映射時,查詢結果列名和pojo的屬性名不一致時,resultMap會對列名和pojo屬性名進行映射,保證其成功映射 
使用resultMap需要這二步: 
(1)定義resultMap 
這裏寫圖片描述 
(2)使用resultMap作爲statement的輸出映射類型 
這裏寫圖片描述 
mybatis的核心輸入映射和輸出映射結束:

mybatis的動態sql和sql片段開始:

動態sql 
mybatis核心就是對sql語句進行靈活操作,通過表達式進行判斷,對sql進行靈活拼接和組裝。 
需求:用戶信息查詢的綜合信息需要使用動態sql 
對查詢條件進行判斷,如果出入參數不爲空,才進行拼接 
這裏寫圖片描述 
測試代碼需要注意的是如下圖: 
這裏寫圖片描述 
如果不設置某個值,條件將不拼接在sql中

sql片段 
需求:將上面的動態sql(重複的sql語句)抽取出來做成一個片段,方便其他statement語句重複使用sql片段 
定義sql片段 
使用sql片段 
這裏寫圖片描述

使用foreach標籤遍歷 
給sql傳入數組或者集合時,mybatis使用foreach解析 
需求:在用戶信息的綜合查詢中增加多個id傳入 
sql語句如下: 
select * from user where id=1 or id=3 or id=5 
也可以使用select * from user where id in(1,3,5) 
這裏寫圖片描述 
mybatis的動態sql和sql片段結束

mybatis高級映射開始: 
一、 高級映射一對一查詢(使用到assocition標籤實現關聯對象的一對一查詢映射),分別使用resultType和resultMap,並且比較二者的區別 
這裏寫圖片描述 
還有一點就是,resultType查詢關聯列表結果列如果和pojo屬性名不一致,需要自己創建擴展類(繼承包括結果集列名多的pojo對象,這樣可以少寫一點屬性名)。resultMap則不需要創建擴展類,而是把關聯信息的對象注入,從而實現結果集列名和pojo屬性名保持一致。 
二、高級映射一對多查詢(使用collection標籤來實現關聯對象的一對多查詢映射),一對多,就是關聯的對象查詢結果是一個List集合 
開發步驟: 
(1)首先寫sql語句 
需求:查詢訂單及訂單明細信息(一個訂單包含多個訂單明細,所以一對多) 
主表:訂單表 
關聯表:訂單明細表 
經過之前一對一查詢(用戶的訂單)的分析,我們只需要在此基礎上關聯訂單明細表即可。 
這裏寫圖片描述 
(2)pojo類(resultType時用到擴展類,這裏我們使用resultMap不需要包裝類) 
這裏寫圖片描述 
(3)mapper.xml(這裏我們使用了resultMap的繼承,不需要重新關聯訂單表和用戶表,通過繼承之前的一對一(用戶查詢訂單)所寫的二個表,可以減少大量的重複代碼。同時使用了collection集合標籤將關聯查詢出的多條記錄映射到List集合中) 
這裏寫圖片描述
(4)mapper.java 
這裏寫圖片描述

一對多查詢總結: 
mybatis使用resultMap的collection(resultType沒有此標籤)對關聯查詢的多條記錄映射到一個list集合中。 
使用resultType通過雙重循環遍歷可以實現,去除重複記錄,將訂單明細映射在orderdetail中(瞭解) 
多對多查詢實例和上邊類似。主要是搞清楚各個表之間的對應關係,訂單的collection中嵌套訂單明細的collection,而訂單明細的collection中嵌套商品信息。

mybatis高級映射結束

mybatis的延遲加載和緩存技術開始 
mybatis一級緩存 
這裏寫圖片描述 
mybatis的二級緩存

mybatis默認是沒有開啓二級緩存的。 
開啓二級緩存需要在mybatis的全局配置文件sqlMapConfig.xml中加入 

除了開啓二級緩存開關外,還需要在各自的mapper.xml中開啓二級緩存。 
這裏寫圖片描述

原理圖: 
這裏寫圖片描述 
如上圖:sqlsession1去查詢id爲1的用戶信息,查詢到用戶信息就會查詢數據存放在二級緩存區域(hashmap)中 
sqlsession2去查詢id爲1的用戶信息,首先去緩存中查找是否存在數據,如果存在就直接從二級緩存中取出數據。 
二級緩存和一級緩存的區別:二級緩存的範圍更大,多個sqlsession 
可以共享usermapper的二級緩存。 
二級緩存是根據mapper的namespace來劃分的,相同namaspace下的mapper共享二級緩存,反之 
如果sqlsession3去執行相同mapper下sql,並執行commit()操作,則清空該命名空間下的二級緩存

二級緩存的測試代碼:

這裏寫圖片描述

上面塗黃部分要特別注意,sqlsession關閉時纔可以把數據寫到二級緩存區域中,如果本namespace下的sqlsession執行了commit()操作,二級緩存就會清空

禁用二級緩存 
也可以禁用單個查詢的二級緩存,這樣要保證每次查詢的都是最新數據。 
這裏寫圖片描述

刷新二級緩存(就是清空緩存,切記) 
這裏寫圖片描述 
總結:一般情況下,執行commit()操作之後,都要刷新緩存,因此flushCache都設爲true,來避免數據的髒讀。

mybatis cache的參數設置 
flushInterval(刷新間隔),可以爲任意整數,單位爲毫秒值,這個比較有用。

mybatis和第三方分佈式緩存框架整合(ehcache,redis,memcache) 
mybatis在緩存方面還是比較弱,特別是分佈式緩存不支持 
這裏寫圖片描述 
我們的系統爲了提高系統併發,性能,一般對系統進行分佈式部署(集羣部署方式)

整合方法 
mybatis提供了一個cache接口,如果要實現自己的緩存邏輯,實現cache接口即可 
mybatis和ehcache整合,mybatis和ehcache整合包中提供了一個cache接口的實現類。 
這裏寫圖片描述

二級緩存的應用場景(實際開發中用 刷新間隔) 
這裏寫圖片描述

二級緩存額侷限性 
這裏寫圖片描述 
細粒度緩存,就是修改一個商品信息(即執行commit()方法),只修改緩存中這一個商品的信息,其餘的信息不清空。

mybatis的延遲加載和緩存技術結束

mybatis和spring的整合(重點掌握)開始

1、整合的思路: 
(1)首先需要spring通過單例方式管理sqlSessionFactory 
(2)spring和mybatis整合生成代理對象,使用SqlSessionFactory創建sqlSession會話(此步是由spring和mybatis整合自動完成) 
(3)持久層的mapper,dao都需要由spring來管理 
2、環境的搭建 
這裏寫圖片描述 
上面的sqlmap目錄下的User.xml是爲了原始dao開發使用的。還要加載spring,mybatis,mybatis-srping等jar包。 
3、在spring的配置文件中配置sqlSessionFactory和數據源 
sqlSessionFactory在mybatis和spring的整合包下 
這裏寫圖片描述 
上圖中:使用C3P0配置數據庫連接池,屬性參數名要按照規定寫,不能自己定義,否則會報錯,而使用dbcp就可以自定義參數名,這點注意。 
在加載配置文件時,都要加上類路徑名classpath 
在使用原始dao開發時,屬性name值要與UserDaoImpl類中變量名一致(特別是大小寫) 
4、*原始Dao的開發(和spring整合後)* 
4.1 User.xml(也稱mapper.xml更準確) 
這裏寫圖片描述 
和spring整合後,需要使用spring來管理mapper,spring配置文件爲applicationContext.xml 
還有mybatis的配置文件來加載User.xml 
這裏寫圖片描述 
4.2 UserDAO 
這裏寫圖片描述 
基本上不用改變 
4.3 UserDaoImpl(重點在Dao的實現類上) 
這裏寫圖片描述 
上圖中的代碼最重要的就是繼承了SqlSessionDaoSupport通過this.getSqlSession()來得到SqlSession會話 
這裏也不需要寫sqlSession的事務提交(更新操作不用寫)和sqlSession關閉 
4.4 測試代碼 
這裏寫圖片描述

5、使用mapper代理來開發 (mybatis和spring整合後) 
和利用原始dao開發差不多,只是不需要dao接口的實現類 
而是根據一個規範來實現dao接口生成代理對象

5.1規範: 
(1)mapper.xml中的namespace命名空間等於mapper.java的全路徑名 
這裏寫圖片描述
(2)mapper.xml和mapper.java應在同一個目錄下 
這裏寫圖片描述 
(3)mapper.xml中的statement語句的輸入參數paramType類型應與mapper.java中方法中傳遞的參數類型一致 
這裏寫圖片描述 
這裏寫圖片描述 
(4)mapper.xml中的statement語句的輸出參數resultType類型應與mapper.java中方法返回值類型一致 
這裏寫圖片描述 
這裏寫圖片描述 
5.2 讓spring來管理mapper,在配置文件中 
這裏寫圖片描述 
重點在這裏,使用mybatis和spring的整合包中MapperFactoryBean來實現mapper接口生成代理對象 
屬性值有mapperInterface和sqlSessionFactory 
總結:此方法存在一個大問題,需要針對每個mapper進行配置,太麻煩 
終極解決方案: 通過mapper批量掃描,從mapper包中掃描出mapper接口,自動創建代理對象並且在spring容器中註冊 
這裏寫圖片描述

<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
  • 1

上面代碼,不能使用ref而是使用value,剛開始用錯了。 
開發中推薦使用自動掃描, 
mybatis和spring的整合(重點掌握)結束 
mybatis的逆向工程(瞭解會用就行) 
這裏寫圖片描述
generator.xml的配置,這裏要記住,上圖中最下邊table後面的一長串值等於false的屬性,是爲了不生成其他與我們無關的example等代碼 
下面需要mybatis-generator-core-1.3.2.jar和generator.xml文件在同於目錄下,並且建立src目錄接收生成的文件 
這裏寫圖片描述
生成後的如下圖 

這裏寫圖片描述

原創鏈接 https://blog.csdn.net/jaryle/article/details/51228751

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