MABITIS框架知識點 java
一部分:框架spring
MyBatis是一個支持普通SQL查詢,存儲過程和高級映射的優秀 持久層框架。sql
MyBatis可使用簡單的XML或註解用於配置和原始映射,將接口和Java的POJO(Plain Old Java Objects,普通的Java對象)映射成數據庫中的記錄。數據庫
1. SqlMapConfig.xml,此文件做爲mybatis的全局配置文件,配置了mybatis的運行環境等信息。(mapper.xml文件即sql映射文件,文件中配置了操做數據庫的sql語句。編程
此文件須要在SqlMapConfig.xml中加載。)設計模式
2經過mybatis環境等配置信息構造SqlSessionFactory即會話工廠。由會話工廠建立sqlSession即會話,操做數據庫須要經過sqlSession進行。瀏覽器
3 mybatis底層自定義了Executor執行器接口操做數據庫,Executor接口有兩個實現,一個是基本執行器、一個是緩存執行器。緩存
5Mapped Statement也是mybatis一個底層封裝對象,它包裝了mybatis配置信息及sql映射信息等。mapper.xml文件中一個sql對應一個Mapped Statement對象,sql的id便是Mappedstatement的id。安全
6 Mapped Statement對sql執行輸入參數進行定義,包括HashMap、基本類型、pojo,Executor經過Mapped Statement在執行sql前將輸入的java對象映射至sql中,輸入參數映射就是jdbc編程中對 preparedStatement設置參數。session
7 Mapped Statement對sql執行輸出結果進行定義,包括HashMap、基本類型、pojo,Executor經過Mapped Statement在執行sql後將輸出結果映射至java對象中,輸出結果映射過程至關於jdbc編程中對結果 的解析處理過程。
二部分:Mapper代理開發
1、用mapper代理開發時只要寫2個:
(1)mapper.xml
(2)mapper接口
2、Mapper接口開發須要遵循如下規範:
(1)Mapper.xml文件中的namespace與mapper接口的類路徑相同。
(2)Mapper接口方法名和Mapper.xml中定義的每一個statement的id相同。
(3)Mapper接口方法的輸入參數類型和mapper.xml中定義的每一個sql 的parameterType的類型相同。
(4)Mapper接口方法的輸出參數類型和mapper.xml中定義的每一個sql的resultType的類型相同。
3、代理對象內部調用selectOne()和selectList()
若是mapper對象返回單個pojo對象(非集合對象)代理對象內部經過selectOne查詢數據庫,若是mapper方法返回集合對象,代理對象內部經過selectList查詢數據庫。
4、mapper接口中的方法參數只能有一個是否影響系統開發,mapper接口方法參數只能有一個,
系統是否不利於維護?
回答:系統框架中,dao層的代碼是被業務層公用的。mapper接口只有一個參數,可使用包裝類型的pojo知足不一樣的業務方法的需求。
<SqlMapConfig.xml全局配置文件解析見文檔>
三部分:動態sql
OGNL,全稱爲Object-Graph Navigation Language,它是一個功能強大的表達式語言,用來獲取和設置Java對象的屬性,它旨在提供一個更高的更抽象的層次來對Java對象圖進行導航。
mybatis 動態SQL 語句主要有如下幾類: if choose trim where set foreach
if: 提供了title參數,那麼就要知足title=#{title}
choose :全部的when和otherwise條件中,只有一個會輸出
trim : 在本身包含的內容前加上某些前綴,也能夠在其後加上某些後綴
prefix:前綴 prefixoverride:去掉第一個 suffixoverride:去掉最後一個逗號(也能夠是其餘的標記,就像是上面前綴中的and同樣) suffix:後綴
where : (主要是用來簡化sql語句中where條件判斷的,能智能的處理 and or 條件)
set : 主要用於更新時, 若是包含的語句是以逗號結束的話將會把該逗號忽略
<select id="dynamicForeachTest" resultType="com.mybatis.entity.User">
select * from t_user where id in
<foreach collection="list" index="index" item="item" open="(" separator=","
close=")">
#{item}
</foreach>
</select>
item表示集合中每個元素進行迭代時的別名。index指定一個名字,用於表示在迭代過程當中,每次迭代到的位置。
open表示該語句以什麼開始。separator表示在每次進行迭代之間以什麼符號做爲分隔符。
close表示以什麼結束。
四部分 延遲加載
需求:若是查詢訂單而且關聯查詢用戶信息。若是先查詢訂單信息便可知足要求,當咱們須要查詢用戶信息時再查詢用戶信息。把對用戶信息的按需去查詢就是延遲加載。
**延遲加載**:先從單表查詢、須要時再從關聯表去關聯查詢,大大提升數據庫性能,由於查詢單表要比關聯查詢多張錶速度要快。
使用association實現延遲加載
須要定義兩個mapper的方法對應的statement
<!-- 查詢訂單關聯查詢用戶,用戶信息按需延遲加載 的 resultMap定義 --> 第二部:查詢訂單,關聯用戶
<resultMap type="com.mybatis.entity.Orders" id="ordersUserLazyLoading">
<!--對訂單信息進行映射配置 -->
<id column="id" property="id"/>
<result column="number" property="number"/>
<result column="createtime" property="createTime"/>
<!-- 實現對用戶信息進行延遲加載 select:指定延遲加載須要執行的statement的id(是根據user_id查詢用戶信息的statement)
column:訂單信息中關聯用戶信息查詢的列,是user_id
<association property="user" javaType="com.mybatis.entity.User" select="findUserById" column="user_id"/>
</resultMap>
<!-- 查詢訂單關聯用戶,用戶信息延遲加載 --> 第一步:查詢訂單,返回resultMap="ordersUserLazyLoading
<select id="findOrdersUserLazyLoading" resultMap="ordersUserLazyLoading">
select * from orders
</select>
<!-- 根據Id查詢用戶,用於測試延遲加載 --> 第三部,根據關聯字段 user_id,查詢用戶信息
<select id="findUserById" parameterType="int" resultType="com.mybatis.entity.User" >
select * from t_user where id=#{id}
</select>
延遲加載在mybatis核心配置文件sqlMapConfig.xml中的配置
mybatis默認沒有開啓延遲加載,須要在SqlMapConfig.xml中setting配置。
mybatis核心配置文件中配置:
lazyLoadingEnabled:全局性設置懶加載。若是設爲'false'(默認),則全部相關聯的都會被初始化加載。
aggressiveLazyLoading:true(默認)懶加載的對象可能被任何懶屬性所有加載。false,每一個屬性都按需加載。
延遲加載的原理:
它的原理是,使用CGLIB建立目標對象的代理對象,當調用目標方法時,進入攔截器方法,好比調用a.getB().getName(),攔截器invoke()方法發現a.getB()是null值,那麼就會單獨發送事先保存好
的查詢關聯B對象的sql,把B查詢上來,而後調用a.setB(b),因而a的對象b屬性就有值了,接着完成a.getB().getName()方法的調用。這就是延遲加載的基本原理。
五部分 查詢緩存
查詢緩存:mybatis提供查詢緩存(一級緩存和二級緩存),用於減輕數據壓力,提升數據庫性能。
一級緩存(默認支持)
一級緩存是sqlSession級別的緩存。在操做數據庫時須要構造sqlSession對象,在對象中有一個數據結構(HashMap),用於存儲緩存數據。不一樣的sqlSession之間的緩存區域(HashMap)是互不影響的。
***若是是執行兩次service調用查詢相同的用戶信息,不走一級緩存,由於session方法結束,sqlSession就關閉,一級緩存就清空。
(1). 第一次發起查詢用戶id爲1的用戶信息,先去找緩存中是否有id爲1的用戶信息,若是沒有,從數據庫查詢用戶信息。獲得用戶信息,而後將用戶信息存儲到一級緩存中。
(2). 若是sqlSession去執行commit操做(執行插入、更新、刪除),清空SqlSession中的一級緩存,這樣作的目的爲了讓緩存中存儲的是最新的信息,避免髒讀。
(3). 第二次發起查詢用戶id爲1的用戶信息,先去找緩存中是否有id爲1的用戶信息,緩存中有,直接從緩存中獲取用戶信息。
二級緩存
(1). 首先開啓mybatis的二級緩存。
(2). sqlSession1去查詢用戶id爲1的用戶信息,查詢到用戶信息會將查詢數據存儲到二級緩存中。
(3). 若是SqlSession3去執行相同 mapper下sql,執行commit提交,清空該 mapper下的二級緩存區域的數據。
(4). sqlSession2去查詢用戶id爲1的用戶信息,去緩存中找是否存在數據,若是存在直接從緩存中取出數據。
二級緩存與一級緩存區別,二級緩存的範圍更大,多個sqlSession能夠共享一個UserMapper的二級緩存區域。
UserMapper有一個二級緩存區域(按namespace分) ,其它mapper也有本身的二級緩存區域(按namespace分)。每個namespace的mapper都有一個二緩存區域,兩個mapper的namespace
若是相同,這兩個mapper執行sql查詢到數據將存在相同的二級緩存區域中。
開啓二級緩存
mybaits的二級緩存是mapper範圍級別,除了在SqlMapConfig.xml設置二級緩存的總開關,還要在具體的mapper.xml中開啓二級緩存
<setting name="cacheEnabled" value="true"/>
禁用二級緩存
在statement中設置useCache=false能夠禁用當前select語句的二級緩存,即每次查詢都會發出sql去查詢,默認狀況是true,即該sql使用二級緩存。
<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">
刷新緩存
設置statement配置中的flushCache="true" 屬性,默認狀況下爲true即刷新緩存,若是改爲false則不會刷新。使用緩存時若是手動修改數據庫表中的查詢數據會出現髒讀。
<insert id="insertUser" parameterType="com.mybaits.entity.User" flushCache="true">
Mybatis Cache參數
flushInterval(刷新間隔)能夠被設置爲任意的正整數,並且它們表明一個合理的毫秒形式的時間段。默認狀況是不設置,也就是沒有刷新間隔,緩存僅僅調用語句時刷新。size(引用數目)能夠被設置爲任意正整數,要記住你緩存的對象數目和你運行環境的可用內存資源數目。默認值是1024。readOnly(只讀)屬性能夠被設置爲true或false。只讀的緩存會給全部調用者返回緩存對象的相同實例。所以這些對象不能被修改。這提供了很重要的性能優點。可讀寫的緩存會返回緩存對象的拷貝(經過序列化)。這會慢一些,可是安全,所以默認是false
二級緩存應用場景
對於訪問多的查詢請求且用戶對查詢結果實時性要求不高,此時可採用mybatis二級緩存技術下降數據庫訪問量,提升訪問速度,業務場景好比:耗時較高的統計分析sql、電話帳單查詢sql等。
實現方法以下:經過設置刷新間隔時間,由mybatis每隔一段時間自動清空緩存,根據數據變化頻率設置緩存刷新間隔flushInterval,好比設置爲30分鐘、60分鐘、24小時等,根據需求而定。
7、二級緩存的侷限性
mybatis二級緩存對細粒度的數據級別的緩存實現很差,好比以下需求:對商品信息進行緩存,因爲商品信息查詢訪問量大,可是要求用戶每次都能查詢最新的商品信息,此時若是使用mybatis的二級
緩存就沒法實現當一個商品變化時只刷新該商品的緩存信息而不刷新其它商品的信息,由於mybaits的二級緩存區域以mapper爲單位劃分,當一個商品信息變化會將全部商品信息的緩存數據所有清空。解
決此類問題須要在業務層根據需求對數據有針對性緩存。
六部分高級映射
例:業務關係
一對一查詢 :建立包裝類VO
需求:查詢訂單信息,關聯查詢用戶信息,resultType實現(resultMapXXX)
SELECT t1.*, t2.username,t2.sex,t2.address FROM orders t1,t_user t2 WHERE t1.user_id=t2.id
步驟: 建立各個實體類;
建立一個包裝類,將查詢到的信息能夠所有映射到此類:OrdersCustom.java (public class OrdersCustom extends Orders,全部訂單信息和部分用戶信息)
建立OrdersCustomMapper.java接口,public interface OrdersCustomMapper {
建立OrdersCustomMapper.xml和上面對應的接口名稱一致,以便經過mapper接口加載配置文件
<!-- 查詢訂單,關聯查詢用戶信息 -->
<select id="findOrdersUser" resultType="com.mybatis.entity.OrdersCustom">
<!sql語句 ; 肯定查詢的主表:訂單表,肯定查詢的關聯表:用戶表。>
select t1.*,t2.username,t2.sex,t2.address from orders t1,t_user t2
where t1.user_id = t2.id
</select>
一對多查詢 : mybatis使用resultMap的collection對關聯查詢的多條記錄映射到一個list集合屬性中。
需求:查詢訂單(關聯用戶)及訂單明細;
在orders.java類中添加List<orderDetail> orderDetails屬性(上面實體已添加)。最終會將訂單信息映射到orders中,訂單所對應的訂單明細映射到orders中的orderDetails屬性中.
在ordersCustomMapper.xml中添加以下代碼
<!-- 查詢訂單(關聯用戶)及訂單明細的resultMap -->
<resultMap type="com.mybatis.entity.Orders" id="ordersAndOrderDetailResultMap" extends="OrdersUserResultMap">
<collection property="orderdetails" ofType="com.mybatis.entity.OrderDetail">
<id column="orderdetail_id" property="id"/>
<result column="items_id" property="itemsId"/>
<result column="items_num" property="itemsNum"/>
</collection>
</resultMap>
、statement定義
<!-- 查詢訂單關聯查詢用戶及訂單明細 -->
<select id="findOrdersAndOrderDetailResultMap" resultMap="ordersAndOrderDetailResultMap">
SELECT t1.*,t2.username,t2.sex,t2.address,t3.id orderdetail_id,t3.items_id,
t3.items_num,t3.orders_id FROM orders t1,t_user t2,orderdetail t3
WHERE t1.user_id = t2.id AND t3.orders_id=t1.id
</select>
、在OrdersCustomMapper.java接口類中添加一個方法
/**查詢訂單(關聯用戶)以及訂單明細*/
public List<OrderDetail>findOrdersAndOrderDetailResultMap();
多對多
使用association和collection完成一對一和一對多高級映射(對結果有特殊的映射要求)。
(1)association:
做用:將關聯查詢信息映射到一個pojo對象中。
場合:爲了方便查詢關聯信息可使用association將關聯訂單信息映射爲用戶對象的pojo屬性中,好比:查詢訂單及關聯用戶信息。使用resultType沒法將查詢結果映射到pojo對象的pojo屬性中,根據
對結果集查詢遍歷的須要選擇使用resultType仍是resultMap。
(2)collection:
做用:將關聯查詢信息映射到一個list集合中。
場合:爲了方便查詢遍歷關聯信息可使用collection將關聯信息映射到list集合中,好比:查詢用戶權限範圍模塊及模塊下的菜單,可以使用collection將模塊映射到模塊list中,將菜單列表映射到模塊對象的
菜單list屬性中,這樣的做的目的也是方便對查詢結果集進行遍歷查詢。若是使用resultType沒法將查詢結果映射到list集合中。
SpRING+SPEINGMVC+MABATIS 框架
工廠設計模式(BeanFactory 、ApplicationContext)/ 代理設計模式(AOP)/ 單例設計模式(bean) /模板設計 (jdbcTemplate) /適配器模式(AOP中的加強,MVC) /包裝器 /觀察者…
Spring 經過XML配置或者註解的方式來管理bean .
IoC是spring的核心,貫穿始終。所謂IoC,對於spring框架來講,就是由spring來負責控制對象的生命週期和對象間的關係。AOP(面向方面編程),代碼每每水平地散佈在全部對象層次中,而與它所散佈到的對象的核心功能毫無關係。將那些與業務無關,卻爲業務模塊所共同調用的邏輯或責任封裝起來,便於減小系統的重複代碼,下降模塊間的耦合度,並有利於將來的可操做性和可維護性。
事務的隔離級別就是爲了解決髒讀、幻讀、不可重複讀等問題,包括DEFAULT /READ_UNCOMMITTED /READ_COMMITED /REPEATABLE_READ /SERLALIZABLE ,傳播機制包括 PROPAGATION_REQUIRED PROPAGATION_REQUIRES_NEW PROPAGATION_SUPPORTS…
一級緩存是sqlSession 級別的,一級緩存默認開啓;二級緩存是userMapper級別的,二級緩存須要開啓,查詢的實時性不高。#會給參數加上「」,防止sql注入。
DispatcherServlet接收到請求後,根據對應配置文件中配置的處理器映射,找到對應的處理器映射項(HandlerMapping),根據配置的映射規則,找到對應的處理器(Handler)。接着再經過相應的HandlerAdapter處理該Handler
HandlerAdapter在對Handler進行處理以後會返 回一個ModelAndView傳給DispatcherServlet, ModelAndView包含了處理結果的視圖和視圖中要使用的數據。
DispatcherServlet根據獲得的ModelAndView中的視圖對象,找到一個合適的ViewReslover(視圖解析器),根據視圖解析器的配置,DispatcherServlet將視圖要顯示的數據傳給對應的視圖,最後給瀏覽器構造一個HTTP響應。
來簡化新Spring應用的初始搭建以及開發過程, 。該框架使用了特定的方式來進行配置,從而使開發人員再也不須要定義樣板化的配置。
Dubbo