Mapper XML的寫法 [Mybatis]
MyBatis是半ORM(java對象 & DB數據 映射)框架,封裝JDBC。(Hibernate全自動ORM不用寫SQL,MyBatis要寫SQL)
MyBatis的強大在於映射語句,針對SQL構建,比JDBC節約代碼。
SQL映射文件的頂級元素:
cache、cache-ref
resultMap 自己寫ORM映射
最復雜最強大的元素,用來描述如何從數據庫結果 集中來加載對象。
sql 可被其他語句引用的 可重用語句塊
<resultMap id="resultMapInput" type="domain.InputDo" > <id column="PARAM_ID" property="paramId"/> <result column="PLAN_ID" property="planId"/> <result column="PARAM_NAME" property="paramName"/> <result column="VALUE" property="value"/> <result column="PARAM_UNIT" property="paramUnit"/> </resultMap>
//使用resultMap進行映射:左邊一排colomn是數據庫里面的名稱,右邊是java后端里面的駝峰式;
然后可以在后面多次使用:
<select id="getParamInput" resultMap="resultMapInput"> select ID as PARAM_ID,PARAM_NAME,PARAM_UNIT,PARAM_PART from t_biz_params where PARAM_MODULE = #{paramModule} and DEL_FLAG = 0 order by ORDER_NUM </select> <select id="getParamInputAndValue" resultMap="resultMapInput"> select t_biz_params.ID as PARAM_ID,t_biz_params.PARAM_NAME,t_biz_params.PARAM_UNIT,t_biz_params.PARAM_PART,t_biz_plan_input.VALUE from t_biz_params,t_biz_plan_input where t_biz_plan_input.PLAN_ID=#{planId} and t_biz_plan_input.PARAM_ID = t_biz_params.ID and t_biz_params.PARAM_MODULE = #{paramModule} and t_biz_plan_input.DEL_FLAG =0 and t_biz_params.DEL_FLAG=0 order by t_biz_params.ORDER_NUM </select>
namespace
這個要與dao文件對應起來,類似於mapper.xml來實現dao文件里的抽象方法
select
<select id="selectPerson" parameterType="int" resultType="hashmap"> SELECT * FROM PERSON WHERE ID = #{id} </select>
id: 對應方法的名字(與dao文件中的方法名字對應) selectPerson,
parameterType: 接受一個 int(或 Integer)類型的參數,
resultType: 返回一個 HashMap 類型的對象,
insert update delete
動態SQL
動態SQL根據不同條件生成不同的SQL語句。
動態 sql 語句的編寫往往就是一個拼接的問題,為了保證拼接准確,我們最好首先要寫原生的 sql 語句出來,然后在通過 mybatis 動態sql 對照着改,防止出錯。
- if
- choose (when*n,otherwise)
- trim (prefix,suffix)
- foreach
if 條件SQL語句(滿足條件才執行)
select會用到where:
update會用到set (不舉例了)
choose (when*n個,otherwise)相當於switch
相當於java里面的switch case break;(遇到符合的一個后不會繼續往下,而普通的case需要break來攔截繼續向下)
trim (prefix,suffix)自定義拼湊SQL
trim用於改寫上面的where、set:
- where-->trim
- set-->trim
foreach 用於遍歷
1)
2)
建議是先把SQL語句寫出來,再轉換成Mybatis.xml里面的"條件SQL語句"
內嵌SQL
對mybatis 之數據庫 include refid ="base_column_list" 的粗略見解:
<sql>用來封裝SQL語句, <include refid>來調用,
如果用了refid="base_column_list"則:
1、首先定義一個sql標簽,一定要定義唯一id<sql id="Base_Column_List" >字段名1,字段名2</sql>
2、然后通過id引用
<select id="selectAll">
select
<include refid="Base_Column_List" />
from 表名
</select>
這時<include refid="Base_Column_List" />會自動把上面的代碼貼過來。
數據庫中查詢的語句就可以解析為:select 字段名1,字段名2 from 表名
<include refid="Base_Column_List" > 這個在MyBatis查詢數據庫的sql中經常會出現。它的在上面已經定義,作用相當於 * ,
Base_Column_List是固定的幾個字段,而用*號的話會降低查詢效率,因為后期數據庫的字段會不斷增加。
Mybatis緩存
適合緩存的場景:
查詢多,改變少【讀多寫少】
Mybatis緩存
查詢時:
先找二級緩存(硬盤) ==》一級緩存(內存)==》數據庫
一級緩存在內存,二級緩存在硬盤
一級緩存(默認,內存上,1個CRUD)
一級緩存是個Map
使用場景:一個用戶不斷刷新頁面
二級緩存(手動開啟,硬盤上,1個Mapper.xml——多個CRUD)
在mapper.xml里面加上:
60s刷新,最多512個引用,返回對象只讀
我們需要使用SqlSession對象的close()方法(關閉連接),達到手動序列化:
session.close();//手動序列化二級緩存:關閉會話,讓一級緩存==》二級緩存中
ehcache 用在Hibernate多;
后面重點學redis就好了
https://www.bilibili.com/video/BV1NE411Q7Nx?p=30
日志
日志工廠
如果數據庫操作,出現bug,日志幫助排錯
下面是兩種常用的日志:
STDOUT_LOGGING 標准日志輸出
在中引入:
打印整個使用數據庫的流程:
Log4j
配置步驟:
1. 導入log4j的包(maven)
2. log4j.properties(詳細配置)
3. 在中引入:
注意:LOG4J全大寫
使用步驟:
其他
多對一 association
比如多個學生對應一個老師
在domain里面:
查詢學生信息,以及學生對應老師的信息:
完整的pid子查詢(重要,記憶):
對應的mapper.xml:
1. 按照查詢嵌套(子查詢)處理:
2. 按照結果嵌套(聯表查詢)處理:
結果是Student類型:
一對多 collection
不清楚再回去看看:https://www.bilibili.com/video/BV1NE411Q7Nx?p=21
sqlSessionFactory
我寫的時候並沒有遇到??
配置解析
核心配置文件mybatis-config.xml
https://www.bilibili.com/video/BV1NE411Q7Nx?p=6 1:47
Junit中測試代碼:
(不寫測試類行不行??)
我寫的時候,因為mabatis和controller、service層都比較簡答,所以就直接全部走通、用postman來測試的;
如果各個部分比較復雜的話,可以從中間切斷、直接像這樣來測dao+mybatis部分的代碼:
增刪改(查不用)需要提交事務:
一些雜碎的技術細節:
mybatis.xml里面 &;相當於and
resource用斜杠隔開;class用點隔開;
${} 解析參數 => 存在sql注入的風險。
- 如果傳入的是基礎數據類型; 大括號中只能寫一個叫做value, 也就是說
${value}
; - 如果傳入的pojo或者map類型, 那么只能寫屬性名或key名:
${username}
;
#{} 拼接參數 => 防止sql注入風險:
如果傳入的是字符串;預編譯時會自動帶上單引號'
Select 書寫順序
SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY
Select 執行順序(select調后,到排序前)
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
HAVING和WHERE的區別:在GROUP BY的前后
GROUP BY的作用是按屬性(列)進行分組【通常針對COUNT/MAX/...】
HAVING和WHERE都是針對行的篩選
JOIN 和 UNION 的理解:
- 表的加法 (UNION) //行數變多
- 以列為單位對表進行聯結 (JOIN) //屬性變多(橫向擴展)//如果沒有where進行篩選,就是笛卡爾積
//內連接:兩張表的連接id都有的記錄(行)才可以
//左連接:左表的每行只多不少,不匹配的就使右表相應字段為空