Mybatis 多參處理 模糊查詢 主鍵獲取 動態sql
目錄
MyBatis高階查詢
標籤中
入參:
int 可以忽略parameterType
String 可以忽略parameterType
HashMap
Person
List
多參 不寫parameterType
返回值:
int
Person
List
ResultMap標籤
如果資料庫結果集中的列名和要封裝的javaBean的屬性名有不一致的情況下,我們查詢的結果中不一致的屬性值會為null,這個時候我們可以使用 resultMap 標籤手動的建立對映關係,可以很好的解決資料不對應的問題。
PersonMapper.xml
<!--類中的屬性名和表中的欄位名一樣時 可以使用resultMap 類中的屬性名和表中的欄位名不一樣時 不使用resultType 使用resultMap 可以只配置不相同的欄位名 --> <!--手動對映物件--> <resultMap id="personResultMap" type="person"> <id column="id" property="id"></id> <result column="name" property="name"></result> <result column="bir" property="bir"></result> <result column="address" property="address"></result> </resultMap> <!--查詢所有 resultMap--> <select id="findAllResultMap" resultMap="personResultMap"> select id as id, name, bir, address from person </select>
MyBatis多引數處理
MyBatis 方法中出現了多個引數的處理方式:
第一種
select * from person where pname = #{0} and address = #{1}
是否生效與jdk版本有關
第二種 使用方法索引
select * from person where pname = #{param1} and address = #{param2}
不加註解的情況下 會報錯:
Parameter ‘pname’ not found. Available parameters are [1, 0, param1, param2]
Parameter ‘pname’ not found. Available parameters are [1, 0, arg0, arg1]
第三種 使用註解
抽象方法定義 使用Param註解
List<Person> selectPersonByNameAndAddress(@Param("pname") String pname, @Param("address") String address);
select * from person where pname = #{pname} and address = #{address}
第四種 使用Map
<!--
解決多參問題 方式四:
對於多參型別》》我們推出了一款新產品: Map
-->
<!--List<Person> selectPersonByPnameAndAddress(Map<String,Object> map);-->
<select id="selectPersonByPnameAndAddress" parameterType="java.util.Map" resultType="com.offcn.pojo.Person">
select * from person where pname = #{pname} and address = #{address}
</select>
不是多參方式的解決辦法,同理還有將入參的資料封裝成一個自定義物件,如Person
坑:注意 標籤內部不能註釋
模糊查詢
直接使用 $ 拼接
<!-- ${} 直接編譯 容易出現sql注入 -->
<select id="selectPersonByMoHu" parameterType="per" resultType="per">-->
SELECT * FROM person WHERE pname LIKE '%${pname}%' AND address LIKE '%${address}%'
</select>
利用佔位符 #{}
這種方式只能在mysql資料庫中使用,其他 不承認雙引號
<!-- #{} sql語句會提前編譯好 -->
<select id="selectPersonByMoHu" parameterType="per" resultType="per">
SELECT * FROM person WHERE pname LIKE "%"#{pname}"%" AND address LIKE "%"#{address}"%"
</select>
利用 concat 函式 拼接資料
<!-- 推薦使用,concat() 字串拼接函式 注意:在Oracle中,concat() 函式只能傳遞二次引數,我們解決方案是巢狀拼接 -->
<select id="selectPersonByMoHu" parameterType="per" resultType="per">
SELECT * FROM person WHERE pname LIKE CONCAT("%",CONCAT(#{pname},"%")) AND address LIKE CONCAT("%",CONCAT(#{address},"%"))
</select>
總結: ${} 與 #{} 區別
#{} :表示一個佔位符號
通過 #{} 可以實現preparedStatement向佔位符中設定值,自動進行java型別和jdbc型別轉換,#{}可以有效防止sql注入。#{} 可以接收簡單型別值或pojo屬性值。
如果parameterType傳輸單個簡單型別值, #{} 括號中可以是value或其它名稱。
${} :表示拼接sql串
通過 ${} 可以將parameterType傳入的內容拼接在sql中且不進行jdbc型別轉換,會出現sql注入問題。
${} 可以接收簡單型別值或pojo屬性值。如果parameterType傳輸單個簡單型別值, ${} 括號中可以使任意名稱。
主鍵欄位值的獲取
應用場景
我們很多時候有這種需求,向資料庫插入一條記錄後,希望能立即拿到這條記錄在資料庫中的自動生成的主鍵值。以便後續業務的使用
方式一 設定insert標籤屬性
useGeneratedKeys=“true” 開啟主鍵自增獲取 主鍵值的模式
keyProperty=“pid” 物件中的屬性名:將獲取的主鍵賦值到物件屬性上
<insert id="insertPerson" parameterType="per" useGeneratedKeys="true" keyProperty="pid" >
INSERT INTO person (pname , address) VALUES (#{pname},#{address})
</insert>
方式二 使用selectKey標籤:
selectKey 即將執行一次 查詢
keyProperty 配置物件中的主鍵對應的屬性
keyColumn 配置表中的主鍵對應的欄位
resultType 返回的型別(必須和類中的屬性型別相同)
order 先執行此函式查詢,還是先執行下列的sql
<insert id="insertPerson" parameterType="per">
<selectKey keyProperty="pid" keyColumn="pid" resultType="String" order="AFTER">
select LAST_INSERT_ID();
</selectKey>
INSERT INTO person (pname , address) VALUES (#{pname},#{address})
</insert>
動態sql語句
sql語句塊
<sql id="sql001">
select * from person
</sql>
<select id="selectPersonByNameAndAddress" resultType="com.offcn.pojo.Person">
<include refid="sql01"></include> where pname = #{pname} and address = #{address}
</select>
xml對映檔案 常用比較符
< | < | 小於 |
> | > | 大於 |
& | & | 與 |
' | ’ | 單引 |
" | " | 雙引 |
動態sql之 <if> <where>
坑! and 儘量打在 where之內的標籤內
where標籤相當於 where 1=1,但是如果沒有條件,就不會拼接where關鍵字
同時where標籤可以 忽略我們 成立條件前面的 第一個and 或者是or關鍵字
第二個不可以
<select id="findByIdAndNameIf" parameterType="person" resultType="person">
SELECT * FROM `person`
<where>
<if test="id != null">
AND id = #{id}
</if>
<if test="name != null">
AND name= #{name}
</if>
</where>
</select>
動態sql之 <choose> <when>
如果有id只使用id做查詢,沒有id的話看是否有name,有name就根據name做查詢,如果都沒有,就不帶條件查詢全部內容。
choose標籤相當於swtich語句 when標籤相當於case語句 otherwise標籤相當於default語句
<select id="findByIdAndNameChoose" parameterType="person" resultType="person"> SELECT * FROM `person`
<where>
<choose>
<when test="id != null">
AND id = #{id}
</when>
<when test="name!= null">
AND name= #{name}
</when>
<otherwise>
AND 1=1
</otherwise>
</choose>
</where>
</select>
動態sql之 <set>
坑:set標籤只能自動清除sql拼接的if標籤最後一個逗號
動態更新user表資料,如果該屬性有值就更新,沒有值不做處理。
<update id="updateIf" parameterType="person">
UPDATE `person`
<set>
<if test="name!= null"> name= #{name}, </if>
<if test="bir!= null"> bir= #{bir}, </if>
<if test="address !=null"> address = #{address}, </if>
</set>
WHERE id = #{id}
</update>
動態sql之 <trim>(瞭解)
重寫set標籤 消除標籤中內容兩端的空格
<update id="updateIf" parameterType="person">
UPDATE `person`
<trim prefix="set" suffixOverrides=",">
<if test="name!= null"> name= #{name}, </if>
<if test="bir!= null"> bir= #{bir}, </if>
<if test="address !=null"> address = #{address}, </if>
</trim>
WHERE id = #{id}
</update>