mybatis加強

MyBatis SQL參數傳遞(掌握)java

SQL映射器Mapper接口(掌握)Mybmysql

atis批量操做(理解掌握)程序員

(多對一)關聯映射(掌握)面試

(一對多,多對多)集合映射   算法

MyBatis原理回顧(Object Relational Mapping,簡稱ORM)spring

    ORM的缺點是會犧牲程序的執行效率和會固定思惟模式。 
        從系統結構上來看,採用ORM的系統通常都是多層系統,系統的層次多了,效率就會下降。ORM是一種徹底的面向對象的作法,而面向對象的作法也會對性能產生必定的影響。 

        在咱們開發系統時,通常都有性能問題。性能問題主要產生在算法不正確和與數據庫不正確的使用上。ORM所生成的代碼通常不太可能寫出很高效的算法,在數據庫應用上更有可能會被誤用,主要體如今對持久對象的提取和和數據的加工處理上,若是用上了ORM,程序員頗有可能將所有的數據提取到內存對象中,而後再進行過濾和加工處理,這樣就容易產生性能問題。 
        在對對象作持久化時,ORM通常會持久化全部的屬性,有時,這是不但願的。 
        但ORM是一種工具,工具確實能解決一些重複,簡單的勞動。這是不能否認的。但咱們不能期望工具能一勞永逸的解決全部問題,有些問題仍是須要特殊處理的,但須要特殊處理的部分對絕大多數的系統,應該是不多的。
sql

S(spring)S(springmvc)M(mybatis)集成(掌握)數據庫

MyBatis是一個ORM持久化框架,應用到系統持久層(Dao);緩存

一個MyBatis的應用程序都以一個SqlSessionFactory對象(單例)的實例爲核心安全

SqlSession對象徹底包含以數據庫爲背景的全部執行SQL操做的方法

MyBatis是針對數據庫交互的一個輔助框架,也是對jdbc作了的簡單封裝,以xml配置代替Java代碼來管理數據庫的交互細節!!

 

MyBatis可使用簡單的XML或註解用於配置和原始映射,將接口(Mapper)和JavaPOJOPlain Old Java Objects,普通的Java對象)映射成數據庫中一條記錄。

MyBatis是一個支持普通SQL查詢,存儲過程和高級映射的優秀持久層框架。MyBatis消除了幾乎全部的JDBC代碼和參數的手工設置以及對結果集的檢索封裝。

加入mybatis  

  1. MyBatis SQL參數傳遞

#{OGNL表達式} ${OGNL表達式} 的區別

 

1.1. #{OGNL表達式}

 

MyBatis會把這個表達式使用?(佔位符)替換,做爲一個sql參數使用:推薦使用

 

     好比name的值爲:  

 

     定義SQL: select * from t_user where name = #{name}

 

     最終SQL: select * from t_user where name = ?

 

1.2. ${OGNL表達式}

 

MyBatis會把這個表達式的值替換到sql,做爲sql的組成部分;

 

該方式主要用於程序拼接SQL;

 

    若是sql中使用${OGNL},而且參數的類型是(integer,string....)那麼OGNL表達式能夠寫成任意東西;

 

1.3. ${OGNL}表達式的應用場景:

 

1.3.1. 不能用在登陸,會出現sql注入

 

好比登陸功能,在輸入name的時候能夠人爲的制形成功:

 

User user=new User();

 

user.setName("\"admin\" or \"1=1\" ");

 

user.setPassword("\"admin\"  ");

 

     定義SQL: select id,name,password from t_user where name = ${name} and password=${password}

 

     最終SQL: select id,name,password from t_user where name="test" or "1=1" and password="test"  出現sql注入

 

 

 

能夠用在order by + limit的場景

 

#{}和${}的使用

 

 

 

resultMap和ParameterMap書寫拼寫要使用#{},resultType 和parameterType類型使用${},使用例子以下:

 

Select ID,COMMAND from Message where COMMAND=#{command}

Select ID,COMMAND from Message where COMMAND=‘${command}’

 

前者解析爲:

 

            Select ID,COMMAND from Message where COMMAND=?具備預編譯效果

 

後者解析爲:

 

            Select ID,COMMAND from Message where COMMAND=段子   不具備預編譯效果

 

 

 

可是,例如當頁面向後臺傳遞一個列名(屬性名)的時候,是不但願被預編譯出一個?的,此時要用到$格式;

 

如:加上 order by${param} ,此時param是一個列名。

 

 

 

#{}和 ognl表達式

 

     

 

 

 

     通常參數的拼寫仍是保證統一風格爲好,便於人讀。

 

常常碰到這樣的面試題目:#{}和${}的區別是什麼?

 

網上的答案是:#{}是預編譯處理,$ {}是字符串替換。mybatis在處理#{}時,會將sql中的#{}替換爲?號,調用PreparedStatement的set方法來賦值;mybatis在處理 $ { } 時,就是把 ${ } 替換成變量的值。使用 #{} 能夠有效的防止SQL注入,提升系統安全性。

 

對於這個題目我感受要抓住兩點:
(1)$ 符號通常用來看成佔位符,常使用Linux腳本的人應該對此有更深的體會吧。既然是佔位符,固然就是被用來替換的。知道了這點就能很容易區分$和#,從而不容易記錯了。
(2)預編譯的機制。預編譯是提早對SQL語句進行預編譯,而其後注入的參數將不會再進行SQL編譯。咱們知道,SQL注入是發生在編譯的過程當中,由於惡意注入了某些特殊字符,最後被編譯成了惡意的執行操做。而預編譯機制則能夠很好的防止SQL注入。

 

最後想說的是,對於mybatis 以及 sql 而言,每個考點背後都是有一個深入的思想存在的,應該好好的體會。這樣才能真正的作到技術提高,成爲技術大牛。

 

 

這第三個例子雖說的是#{}和{}通用的問題,也就是說在此種狀況下#{}和

{}是通用的,只不過須要些小的轉換.如例子中須要手動

 

拼接單引號 ' ' 到變量值的先後,確保sql語句正常.

 

簡單說#{}是通過預編譯的,是安全的,而${}是未通過預編譯的,僅僅是取變量的值,是非安全的,存在sql注入.

 

這裏先說一下只能,,orderby

 

{}了,用#{}會多個' '致使sql語句失效.此外還有一個like 語句後也須要用${},簡單想一下

 

就能明白.因爲,sql,orderby

 

{},那麼不作任何處理的時候是存在sql注入危險的.你說怎麼防止,那我只

 

能悲慘的告訴你,你得手動處理過濾一下輸入的內容,如判斷一下輸入的參數的長度是否正常(注入語句通常很長),更精確寫查詢一下輸入的參數

 

 

  1. SQL映射器Mapper接口

 

MyBatis基於代理機制,可讓咱們無需再編寫Dao的實現。直接把之前的dao接口定義成符合規則的Mapper

 

Mybatis的批量操做(foreach)

 1 <!-- delete from product where id in ( ? , ? ) 批量刪除:  2 collection="list":傳入的list,至關於map的key,經過list獲得傳入的整個集合的值;  3         index="index" :每次循環的索引  4  item="id" :每次循環的這個值  5 open="(" :以什麼開始  6 separator=",":分隔符  7         close=")":以什麼結束  8 -->
 9     <delete id="deleteBatch" parameterType="java.util.List">
10         delete from product where id 11         in
12         <foreach collection="list" index="index" item="id" open="("
13             separator="," close=")">
14  #{id} 15         </foreach>
16     </delete>
 1 <!-- 批量插入:  2  insert into product(productName,salePrice,costPrice,cutoff,supplier,brand,dir_id)  3         values (?,?,?,?,?,?,?) , (?,?,?,?,?,?,?)  4  parameterType:傳入參數是:java.util.List的類型的;  5  對傳入的list進行foreach循環:取出值填入插入的values中:  6         collection="list":這個不能修改,表示傳入的一個list相似於一個key是list,獲得傳入的list集合  7         index="index":每一次遍歷的序號  8         item="item":每次遍歷的這個對象別名,能夠修改  9         separator=",":每遍歷一次後的分隔符 10         -->
11     <insert id="insertBatch" parameterType="java.util.List">
12  insert into 13  product(productName,salePrice,costPrice,cutoff,supplier,brand,dir_id) 14  values 15         <foreach collection="list" index="index" item="item"
16             separator=",">
17  (#{item.productName},#{item.salePrice},#{item.costPrice},#{item.cutoff},#{item.supplier},#{item.brand},#{item.dir_id}) 18         </foreach>
19     </insert>

 

 

關聯映射(多對一)

 

多對一:

 

  多個員工屬於一個部門,domain:在員工這方建立一個部門:在多方有一個外鍵

 

一對多:

 

  一個部門有多個員工:Domain:在部門有一個員工list:在多方有一個外鍵

 

多對多:

 

   角色和權限:一個角色擁有對個權限,一個權限屬於多個角色

 

Domain:使用list表示:使用中間表維護關係

  parameterType ,入參的全限定類名或類型別名   keyColumn ,設置數據表自動生成的主鍵名。對特定數據庫(如PostgreSQL),若自動生成的主鍵不是第一個字段則必須設置   keyProperty ,默認值unset,用於設置getGeneratedKeys方法或selectKey子元素返回值將賦值到領域模型的哪一個屬性中   useGeneratedKeys ,取值範圍true|false(默認值),設置是否使用JDBC的getGenereatedKeys方法獲取主鍵並賦值到keyProperty設置的領域模型屬性中。MySQL和SQLServer執行auto-generated key field,所以當數據庫設置好自增加主鍵後,可經過JDBC的getGeneratedKeys方法獲取。但像Oralce等不支持auto-generated key field的數據庫就不能用這種方法獲取主鍵了   statementType ,取值範圍STATEMENT,PREPARED(默認值),CALLABLE   flushCache ,取值範圍true(默認值)|false,設置執行該操做後是否會清空二級緩存和本地緩存   timeout ,默認爲unset(依賴jdbc驅動器的設置),設置執行該操做的最大時限,超時將拋異常   databaseId ,取值範圍oracle|mysql等,表示數據庫廠家,元素內部可經過`<if test="_databaseId = 'oracle'">`來爲特定數據庫指定不一樣的sql語句--------------------- 做者:零下

相關文章
相關標籤/搜索