柚子快報(bào)邀請(qǐng)碼778899分享:MyBatis
目錄
MyBatis快速入門(mén)解決SQL映射文件警告提示
Mapper代理開(kāi)發(fā)MyBatis核心配置文件sql映射文件問(wèn)題及解決方法查詢數(shù)據(jù)數(shù)據(jù)庫(kù)字段名與實(shí)體類(lèi)中的屬性名不同傳參轉(zhuǎn)義字符
查詢多條件查詢動(dòng)態(tài)條件查詢if標(biāo)簽:條件判斷choose[相當(dāng)于switch]、when[相當(dāng)于case]、otherwise[相當(dāng)于default]foreach
添加主鍵返回
修改修改全部字段修改動(dòng)態(tài)字段
刪除刪除一個(gè)批量刪除
MyBatis參數(shù)傳遞使用注解開(kāi)發(fā)
MyBatis
什么是MyBatis?
MyBatis是一款優(yōu)秀的持久層框架,用于簡(jiǎn)化 JDBC 開(kāi)發(fā)MyBatis是Apache的一個(gè)開(kāi)源社區(qū)iBatis,2010年項(xiàng)目由apache software foundation遷移到google code,并改名為MyBatis,2013年11月遷移到Github官網(wǎng):MyBatis中文網(wǎng)
持久層:
負(fù)責(zé)將數(shù)據(jù)保存到數(shù)據(jù)庫(kù)的那一層代碼JavaEE三層架構(gòu):表現(xiàn)層、業(yè)務(wù)層、持久層
框架:
框架就是一個(gè)半成品軟件,是一套可重用的、通用的、軟件基礎(chǔ)代碼模型在框架的基礎(chǔ)上構(gòu)建軟件編寫(xiě)更加高效、規(guī)范、通用、可擴(kuò)展
JDBC缺點(diǎn):(MyBatis幾乎免除了所有的JDBC代碼以及設(shè)置參數(shù)和獲取結(jié)果的工作)
硬編碼(優(yōu)化:寫(xiě)入配置文件)
注冊(cè)驅(qū)動(dòng),獲取連接SQL語(yǔ)句 操作繁瑣(優(yōu)化:自動(dòng)完成)
手動(dòng)設(shè)置參數(shù)手動(dòng)封裝結(jié)果集
快速入門(mén)
創(chuàng)建模塊(Maven),導(dǎo)入坐標(biāo)(pom.xml中通過(guò)標(biāo)簽中導(dǎo)入) 編寫(xiě) MyBatis 核心配置文件 ——> 替換連接信息 解決硬編碼問(wèn)題
編寫(xiě) SQL 映射文件 ——> 統(tǒng)一管理sql語(yǔ)句,解決硬編碼問(wèn)題
編碼
定義 POJO 類(lèi) 加載核心配置文件,獲取 SqlSessionFactory 對(duì)象
從官網(wǎng)上復(fù)制固定的創(chuàng)建SqlSession對(duì)象的代碼
String resource = "mybatis-config.xml的路徑地址";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
獲取 SqlSession 對(duì)象,執(zhí)行SQL語(yǔ)句
// 獲取SQLSession對(duì)象,用它來(lái)執(zhí)行sql
SqlSession sqlSession = sqlSessionFactory.openSession();//可以設(shè)置參數(shù):true/false,用于設(shè)置是否自動(dòng)提交事務(wù),true自動(dòng)提交、false手動(dòng)提交,未傳參數(shù)的時(shí)候需要在關(guān)閉資源之前使用sqlSssion.commit();手動(dòng)提交一下事務(wù)
// 執(zhí)行sql
List
釋放資源
sqlSession.close();
解決SQL映射文件警告提示
產(chǎn)生原因:
IDEA和數(shù)據(jù)庫(kù)沒(méi)有建立連接,不識(shí)別表信息
解決方法:
在IDEA中配置MySQL數(shù)據(jù)庫(kù)連接信息
社區(qū)版本需下載插件:Database Navigator
在主面板View -> Tool Windows -> DB Browser
在面板右邊Maven下有個(gè)Database模塊 -> 點(diǎn)擊+ -> Data Source -> 選擇對(duì)應(yīng)數(shù)據(jù)庫(kù)類(lèi)型 -> 填寫(xiě)Host(主機(jī)名)、User(用戶名)、Password(密碼)、Database(數(shù)據(jù)庫(kù)名)
Mapper代理開(kāi)發(fā)
目的:
解決原生方式中的硬編碼(執(zhí)行Sql對(duì)象里的方法是固定字符串)
簡(jiǎn)化后期執(zhí)行SQL
步驟:
定義SQL映射文件同名的Mapper接口,并且將Mapper接口和SQL映射文件放置在統(tǒng)一目錄下
細(xì)節(jié):
在 resource 下創(chuàng)建包的層次結(jié)構(gòu)用 " / " 作為分隔符才能創(chuàng)建包的層次結(jié)構(gòu)
設(shè)置SQL映射文件的namespace屬性為Mapper接口的全限定名
在Mapper接口中定義方法,方法名就是SQL映射文件中sql語(yǔ)句的id,并保持參數(shù)類(lèi)型和返回值類(lèi)型一致
注意:mybatis-config.xml 配置文件中的路徑要保證可以加載到
編碼
通過(guò)SqlSession的 getMapper 方法獲取 Mapper 接口的代理對(duì)象 調(diào)用對(duì)應(yīng)方法完成sql的執(zhí)行
細(xì)節(jié):
如果 Mapper 接口名稱和 SQL 映射文件名稱相同,并在同一個(gè)目錄下,則可以使用包掃描的方式簡(jiǎn)化 SQL 映射文件的加載
代碼:
// 1.加載MyBatis的核心配置文件,獲取其 SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2. 獲取SQLSession對(duì)象,用它來(lái)執(zhí)行sql
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 3. 獲取 UserMapper 接口的代理對(duì)象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 4. 執(zhí)行方法
List
// 5. 釋放資源
sqlSession.close();
MyBatis核心配置文件
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
sql映射文件問(wèn)題及解決方法
查詢數(shù)據(jù)
數(shù)據(jù)庫(kù)字段名與實(shí)體類(lèi)中的屬性名不同
出現(xiàn)結(jié)果:
會(huì)導(dǎo)致查詢結(jié)果不能自動(dòng)封裝數(shù)據(jù)
解決方案:
在映射文件中的sql語(yǔ)句中起別名
缺點(diǎn):每次寫(xiě)sql都要定義一次別名,比較麻煩 Mapper.xml文件示例:
select 數(shù)據(jù)庫(kù)中的字段名 as 實(shí)體類(lèi)中的屬性名 from 表名;
sql片段
缺點(diǎn):不靈活 Mapper.xml文件示例:
數(shù)據(jù)庫(kù)中的字段 as 實(shí)體類(lèi)中的屬性名
select
from 表名;
resultMap
定義resultMap標(biāo)簽,其中(id屬性:唯一標(biāo)識(shí) ;type屬性:映射類(lèi)型,支持別名) 在select標(biāo)簽中,使用resultMap屬性替換resultType屬性 Mapper.xml文件示例:
-- result標(biāo)簽:完成一般字段的映射
-- column:表的列名
-- property:實(shí)體類(lèi)屬性名
-- id標(biāo)簽:完成主鍵字段的映射
-- column:表的列名
-- property:實(shí)體類(lèi)屬性名
select * from tb_user;
傳參
出現(xiàn)結(jié)果:
可能出現(xiàn)sql注入問(wèn)題
解決方案:
#{}:會(huì)替換為 ? ,防止 SQL 注入
使用時(shí)機(jī):參數(shù)傳遞時(shí) ${}:拼接 sql ,會(huì)存在 SQL 注入問(wèn)題
表名或者列名不固定的情況下
轉(zhuǎn)義字符
出現(xiàn)結(jié)果:
由于在 xml 中是使用的標(biāo)簽方式,有些符號(hào)使用會(huì)報(bào)錯(cuò)
解決方案:
轉(zhuǎn)義字符(字符比較少)
比如:<,使用<; CDATA區(qū)(字符比較多)
CD通過(guò) Tab 鍵補(bǔ)齊,格式:
<(特殊符號(hào)寫(xiě)此處)
]]>
查詢
參數(shù)接收:
散裝參數(shù):如果方法中有多個(gè)參數(shù),需要使用@Param(“SQL語(yǔ)句中的參數(shù)占位符名”)對(duì)象參數(shù):對(duì)象的屬性名稱要和參數(shù)占位符名一致map集合參數(shù):map集合的 key 值要和SQL中的參數(shù)占位符名一樣,value 值則為map用戶傳遞的數(shù)據(jù)
多條件查詢
步驟:
編寫(xiě)接口方法:Mapper接口確定參數(shù)(個(gè)數(shù)、順序、類(lèi)型):所有查詢條件
多參數(shù)的時(shí)候除了第一個(gè)使用等值連接 ‘=’,之后的條件使用模糊查詢(like),記住使用 ‘%’ 或者 ‘_’ 明確返回結(jié)果的類(lèi)型:List或者單個(gè)對(duì)象編寫(xiě)SQL語(yǔ)句:SQL 映射文件執(zhí)行方法,測(cè)試
動(dòng)態(tài)條件查詢
SQL語(yǔ)句會(huì)隨著用戶的輸入或外部條件的變化而變化——?jiǎng)討B(tài)SQL
if標(biāo)簽:條件判斷
用法:
標(biāo)簽里面有個(gè) test 屬性,在屬性里面來(lái)寫(xiě)邏輯表達(dá)式,判斷條件里不可以使用&&,而是使用and
步驟:
編寫(xiě)接口方法:Mapper接口
確認(rèn)要傳遞的參數(shù):查詢的相關(guān)字段 確認(rèn)返回結(jié)果的類(lèi)型:對(duì)象等 編寫(xiě) SQL 語(yǔ)句:SQL映射文件 執(zhí)行方法,測(cè)試
出現(xiàn)問(wèn)題:
當(dāng)使用where判斷之后跟這多個(gè)條件的時(shí)候第一個(gè)開(kāi)頭無(wú)and,而第二個(gè)第三……之后開(kāi)頭都有and,如果查詢時(shí),沒(méi)有第一個(gè)條件的參數(shù),導(dǎo)致where后面直接跟上and,會(huì)出現(xiàn)語(yǔ)法錯(cuò)誤
或者末尾的 ‘,’ 也會(huì)導(dǎo)致查詢語(yǔ)句的語(yǔ)法錯(cuò)誤
解決方法:
使用恒等式讓所有條件都一樣
select *
from
tb_user
where 1 = 1
and status = #{status}
and ……
使用標(biāo)簽替換where關(guān)鍵字,where會(huì)自動(dòng)去掉后面的and
select *
from
tb_user
where
and status = #{status}
and ……
choose[相當(dāng)于switch]、when[相當(dāng)于case]、otherwise[相當(dāng)于default]
多用于單條件的動(dòng)態(tài)查詢
用法:
最外層用標(biāo)簽,和標(biāo)簽處于并列關(guān)系 #使用
select *
from
tb_user
status = #{status}
companyName = #{companyName}
brandName = #{brandName}
1 = 1
#也可以使用
select *
from
tb_user
status = #{status}
companyName = #{companyName}
brandName = #{brandName}
foreach
添加
步驟:
編寫(xiě)接口方法:Mapper接口
確認(rèn)要傳遞的參數(shù):相關(guān)屬性,可以使用對(duì)象封裝 確認(rèn)返回結(jié)果的類(lèi)型:void 編寫(xiě) SQL 語(yǔ)句:SQL映射文件 執(zhí)行方法,測(cè)試
主鍵返回
新增完數(shù)據(jù)之后,返回該新增信息的主鍵的值,使用標(biāo)簽的useGeneratedKeys屬性和keyProperty屬性
步驟:
編寫(xiě)接口方法:Mapper接口
確認(rèn)要傳遞的參數(shù):相關(guān)屬性,可以使用對(duì)象封裝 確認(rèn)返回結(jié)果的類(lèi)型:void 編寫(xiě) SQL 語(yǔ)句:SQL映射文件 執(zhí)行方法,測(cè)試
解決方案:
通過(guò)在標(biāo)簽中通過(guò)useGeneratedKeys屬性和keyProperty屬性來(lái)進(jìn)行開(kāi)啟主鍵返回
#使用useGeneratedKeys屬性來(lái)開(kāi)啟, 通過(guò)keyProperty屬性來(lái)將主鍵的值綁定到主鍵名稱id上面
insert into tb_user(id, name, gender, addr)
values(#{id}, #{name}, #{gender}, #{addr});
修改
修改全部字段
使用update標(biāo)簽
步驟:
編寫(xiě)接口方法:Mapper接口
確定要傳遞的參數(shù):id等可以確定該條記錄的字段確定返回的結(jié)果類(lèi)型:void或者int 編寫(xiě) SQL 語(yǔ)句:SQL映射文件執(zhí)行方法,測(cè)試
SQL文件示例:
update tb_user
set
status = #{status},
name = #{name},
gender = #{gender},
addr = #{addr}
where
id = #{id};
修改動(dòng)態(tài)字段
使用標(biāo)簽和標(biāo)簽,注意test屬性是判斷條件
步驟:
編寫(xiě)接口方法:Mapper接口
確定要傳遞的參數(shù):id等可以確定該條記錄的字段確定返回的結(jié)果類(lèi)型:void或者int 編寫(xiě) SQL 語(yǔ)句:SQL映射文件執(zhí)行方法,測(cè)試
SQL文件示例:
update tb_user
status = #{status},
name = #{name},
gender = #{gender},
addr = #{addr}
where
id = #{id};
刪除
刪除一個(gè)
使用標(biāo)簽
步驟:
編寫(xiě)接口方法:Mapper接口
確定要傳遞的參數(shù):id等可以確定該條記錄的字段確定返回的結(jié)果類(lèi)型:void 編寫(xiě) SQL 語(yǔ)句:SQL映射文件執(zhí)行方法,測(cè)試
SQL文件示例:
delete from tb_user where id = #{id}
批量刪除
使用標(biāo)簽下的標(biāo)簽的 collection(遍歷的集合數(shù)組名)屬性、 item(遍歷出的每一個(gè)元素)屬性、separator(分隔符)屬性、open(開(kāi)頭前拼的字符等)屬性、close(結(jié)尾后拼的字符等)屬性 并且通過(guò) sql 語(yǔ)句的 in 關(guān)鍵字
MaBatis會(huì)將數(shù)組參數(shù),封裝為一個(gè)Map集合:
默認(rèn)集合的Key名叫 array ,value值為對(duì)應(yīng)的數(shù)組也可以使用@Param注解,來(lái)改變map集合的默認(rèn)名稱
步驟:
編寫(xiě)接口方法:Mapper接口
確定要傳遞的參數(shù):id數(shù)組確定返回的結(jié)果類(lèi)型:void 編寫(xiě) SQL 語(yǔ)句:SQL映射文件執(zhí)行方法,測(cè)試
SQL文件示例:
delete from tb_user where id
in
#{id}
;
MyBatis參數(shù)傳遞
MyBatis接口方法中可以接受各種各樣的參數(shù),MyBatis底層對(duì)于這些參數(shù)進(jìn)行不同的封裝處理方式
單個(gè)參數(shù):
POJO類(lèi)型:直接使用,POJO的屬性名和參數(shù)的占位符名稱一致Map集合:直接使用,Map的鍵名和參數(shù)的占位符名稱一致Collection:封裝為Map集合
map.put(“arg0”, collection集合);map.put(“collection”, collection集合); List:封裝為Map集合
map.put(“arg0”, list集合);map.put(“collection”, list集合);map.put(“l(fā)ist”, list集合); Array:封裝為Map集合
map.put(“arg0”, 數(shù)組);map.put(“array”, 數(shù)組); 其他類(lèi)型:直接使用 多個(gè)參數(shù):封裝為Map集合,可以使用@Param注解,替換Map集合中默認(rèn)的arg鍵名
假如接口中傳遞的是兩個(gè)參數(shù),MyBatis底層會(huì)通過(guò)封裝將第一個(gè)參數(shù)進(jìn)行:map.put(“arg0”, 參數(shù)值1);map.put(“Param1”, 參數(shù)值1);封裝第二個(gè)參數(shù):map.put(“arg1”, 參數(shù)值2);map.put(“Param2”, 參數(shù)值2) ;但是經(jīng)過(guò)@Param(“username”)注解:則會(huì)變?yōu)?,封裝第一個(gè)參數(shù):map.put(“username”, 參數(shù)值1);map.put(“Param1”, 參數(shù)值1);也就是說(shuō),通過(guò)@Param注解將參數(shù)argN替換
MyBatis提供了 ParamNameResolver 類(lèi)來(lái)進(jìn)行參數(shù)封裝
結(jié)論:
最好都使用@Param注解來(lái)修改Map集合中默認(rèn)的鍵名,并使用修改后的名稱來(lái)獲取值,這樣可讀性更高
使用注解開(kāi)發(fā)
注解開(kāi)發(fā)會(huì)比配置文件開(kāi)發(fā)更加方便
查詢:@Select添加:@Insert修改:@Update刪除:@Delete
提示:
注解完成簡(jiǎn)單功能配置文件完成復(fù)雜功能
直接在接口文件的定義接口上使用,示例:
@Select(“select * from tb_user where id = #{id}”)
public User selectById(int id);
柚子快報(bào)邀請(qǐng)碼778899分享:MyBatis
參考文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。