柚子快報激活碼778899分享:Mybatis
執(zhí)行方案出現(xiàn)如下情況,即有的數(shù)據(jù)沒有被成功賦值:
解決方式:
通過給字段起別名 通過resultMap的方式手動定義字段和屬性的映射
resultMap是Mybatis用于解決數(shù)據(jù)庫列名與POJO屬性名不匹配問題的強大工具,它可以在查詢,插入,更新操作中靈活地重命名參數(shù)。
標(biāo)簽
sql標(biāo)簽:將需要復(fù)用的sql片段放進(jìn)去 同時有很多個mapper接口可能會用到這一段sql,我們可以將其提取出來。往往結(jié)合include標(biāo)簽,將sql的id引入進(jìn)來
id, brand_name as brandName, company_name as companyName, ordered, description, status
select
from tb_brand;
resultMap標(biāo)簽:
在上面只需要指定字段名和屬性名不一樣的映射,而一樣的則不需要專門定義出來。 并且將來通過resultMap來指定id,而不是resultType
select *
from tb_brand;
?parameterType: 用于指定參數(shù)類型,這里我們mapper接口的方法中,傳入AddressBook的引用參數(shù) 當(dāng)然mapper接口無參不用指定 返回值為AddressBook類型,不用寫全類名 這里還涉及到動態(tài)sql,常用的where標(biāo)簽和if標(biāo)簽
select * from address_book
and user_id = #{userId}
and phone = #{phone}
and is_default = #{isDefault}
占位符
mybatis提供了兩種占位符: #{} :參數(shù)占位符,執(zhí)行SQL時,會將 #{} 占位符替換為?,將來自動設(shè)置參數(shù)值。從上述例子可以看出使用#{} 底層使用的是 PreparedStatement? ${} :變量占位符,拼接SQL。底層使用的是statement,會存在SQL注入問題
這里提一嘴statement與preparedStatement: statement 每條sql語句都會編譯一次,導(dǎo)致如果是相同的sql也會重復(fù)編譯,影響性能,并且存在sql注入的問題,不安全 而prepareddStatement 每條sql只會預(yù)編譯一次,即相同的sql不會編譯多次,并且能防止sql注入
SQL語句中特殊字段處理
< 和 > 在xml文件中有特殊含義,我們需要進(jìn)行轉(zhuǎn)義
動態(tài)SQL
if標(biāo)簽:條件判斷 ?test屬性:邏輯表達(dá)式
where標(biāo)簽: 替換where關(guān)鍵字 會動態(tài)的去掉第一個條件前的 and 如果所有的參數(shù)沒有值則不加where關(guān)鍵 注意:需要給每個條件前都加上 and 關(guān)鍵字。
and status = #{status}
and company_name like #{companyName}
and brand_name like #{brandName}
?插入操作
在數(shù)據(jù)添加成功后,有時候需要獲取插入數(shù)據(jù)庫數(shù)據(jù)的主鍵 我們通過useGeneratedKeys打開主鍵自增,并且將主鍵的返回值封裝到id屬性 id為主鍵,我們在插入的時候直接跳過即可,不需要我們賦值
insert into tb_brand (brand_name, company_name, ordered, description, status)
values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});
修改操作
set標(biāo)簽 :可以用于動態(tài)包含需要更新的列,忽略其它不更新的列。 當(dāng)然,也會用到if標(biāo)簽和where標(biāo)簽
update tb_brand
brand_name = #{brandName},
company_name = #{companyName},
where id = #{id};
刪除操作
刪除一行
delete from tb_brand where id = #{id};
刪除多行
會涉及到foreach標(biāo)簽,因為刪除多行,一般都是以集合或者數(shù)組的形式傳過來,我們可以遍歷獲取其中的值?
foreach標(biāo)簽:
用來迭代任何可迭代的對象(如數(shù)組,集合)。collection 屬性: mybatis會將數(shù)組參數(shù),封裝為一個Map集合。 默認(rèn):array = 數(shù)組 當(dāng)然,通過@Param注解,這樣map集合名稱和接口中的參數(shù)名一致item 屬性:本次迭代獲取到的元素。separator 屬性:集合項迭代之間的分隔符。foreach 標(biāo)簽不會錯誤地添加多余的分隔符。也就是最后一次迭代不會加分隔符open 屬性:該屬性值是在拼接SQL語句之前拼接的語句,只會拼接一次close 屬性:該屬性值是在拼接SQL語句拼接后拼接的語句,只會拼接一次
delete from tb_brand where id
in
#{id}
;
等價于
delete from tb_brand where id in (1,2,3);
?當(dāng)mapper接口參數(shù)有多個的時候,考慮用@Param注解,增加可讀性
User select(@Param("username") String username,@Param("password") String password);
原理:
我們在接口方法中定義多個參數(shù),Mybatis 會將這些參數(shù)封裝成 map?集合,其中value就是參數(shù)值,而key在沒有使用 @Param注解時有以下命名規(guī)則:
以 arg開頭 : 第一個參數(shù)就叫 arg0,第二個參數(shù)就叫 arg1,依次類推 以 param 開頭 : 第一個參數(shù)就叫 param1,第二個參數(shù)就叫 param2,依次類推
這樣的話可讀性會非常差,建議使用@Param注解,Mybatis 會將 arg 開頭的鍵名替換為對應(yīng)注解的屬性值。
Mybatis參數(shù)傳遞
這里涉及mapper接口參數(shù)是單個還是多個
多個參數(shù):就是一次傳了好幾個參數(shù),如上面代碼
單個參數(shù):一次傳一個參數(shù),這里的一個可以指一個集合、數(shù)組或者一個POJO對象 集合包括List、Collection、Map 實際代碼中,List、Collection、Array最好是通過@Param注解指定key的名稱,不然可讀性不高
以上需要@Param注解指定key名稱,因為當(dāng)沒有@Param注解時:
mybatis底層會自動將它們封裝為map集合,然后會給一套默認(rèn)的key,我們需要用它默認(rèn)的key,如arg0這樣的去獲得我們真正的集合對象。如果我們用默認(rèn)給的key,可讀性不高
說了這么多,List、Collection、Array這種用的都比較少,一般都是直接傳POJO對象,或者說傳集合過來,然后我們進(jìn)行批量刪除或批量添加【通過foreach標(biāo)簽】。
而POJO、Map不需要通過@Param注解來指定
原因是:Map對象本身就是一個map,它就不會走mybatis底層的map封裝;
而POJO對象,mybatis默認(rèn)情況下會通過反射機制,按照POJO的屬性名來與SQL中的占位符進(jìn)行映射。所以如果POJO對象的屬性名我們不需要去額外變動的話,就不需要@Param注解。 相反,如果我們需要去額外指定的話,我們可以通過@Param來指定名稱 或者 使用resultMap來手動完成映射
下面是一條update語句,參數(shù)為POJO,即addresBook對象,我們不需要通過@Param去指定
void update(AddressBook addressBook);
update address_book
consignee = #{consignee},
sex = #{sex},
phone = #{phone},
detail = #{detail},
label = #{label},
is_default = #{isDefault},
where id = #{id}
常見面試題
一、Dao接口中的方法,參數(shù)不同時,方法能重載嗎?
可以的,我們通過if標(biāo)簽和test屬性,通過動態(tài)sql進(jìn)行動態(tài)的判斷就可以了。
/**
* Mapper接口里面方法重載
*/
public interface StuMapper {
List
List
}
select * from student
id = #{id}
二、Mapper接口【Dao接口】的工作原理是什么?
通常一個 xml 映射文件,都會寫一個 Dao 接口與之對應(yīng)。Dao 接口就是人們常說的 Mapper 接口,接口的全限名,就是映射文件中的 namespace 的值,接口的方法名,就是映射文件中 MappedStatement 的 id 值,接口方法內(nèi)的參數(shù),就是傳遞給 sql 的參數(shù)。 Mapper 接口是沒有實現(xiàn)類的,當(dāng)調(diào)用接口方法時,接口全限名+方法名拼接字符串作為 key 值,可唯一定位一個 MappedStatement。 在 MyBatis 中,每一個?
三、Mybatis怎么執(zhí)行一對一、一對多的關(guān)聯(lián)查詢?
一對一,使用
柚子快報激活碼778899分享:Mybatis
參考閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。