MyBatis增刪改查快速上手
作為一個(gè)快樂(lè)的小碼農(nóng),在每一個(gè)階段往往都在重復(fù)寫(xiě)著不同版本的,學(xué)生管理,用戶(hù)管理,注冊(cè)登錄,從 JavaSE 的控制臺(tái)版,或者 GUI 版,再到 JavaWeb的 JSP版,再到純粹使用 HTML 作為前端展示的版本,以及使用一個(gè)更新的技術(shù),在此其中,我們用過(guò) txt 做數(shù)據(jù)庫(kù),用 XML 也可以,到現(xiàn)在常用的 MySQL,增刪改查一直是我們必不可少的一部分內(nèi)容,即使你不懂原理,即使你對(duì)這個(gè)技術(shù)的理解不是很深刻,拿出你的增刪改查,噼里啪啦就是一段亂敲,好歹還是能讓你著手先做起來(lái)(當(dāng)然,對(duì)技術(shù)的理解還是很重要的),今天就和大家聊一聊 MyBatis 這門(mén)技術(shù)的 CURD (增刪改查)
優(yōu)化測(cè)試方法
在測(cè)試方法中,讀取配置文件,生產(chǎn) SqlSession,釋放資源等等,在每一測(cè)試方法的時(shí)候,都是重復(fù)的,所以我們完全可以提出出這一部分,防止大量的重復(fù)代碼
@Before
public void init() throws Exception{
//讀取配置文件
inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//創(chuàng)建SqlSessionFactory工廠(chǎng)
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
//使用工廠(chǎng)生產(chǎn)SqlSession對(duì)象
sqlSession= factory.openSession();
//使用SqlSession創(chuàng)建Mapper接口的代理對(duì)象
userMapper = sqlSession.getMapper(UserMapper.class);
}
@After
public void destroy() throws Exception{
sqlSession.close();
inputStream.close();
}
在這兩個(gè)方法上增加 @Before 和 @Aftrer 注解,就可以保證,init() 和 destory() 這兩個(gè)方法,分別在我們真正被測(cè)試的方法的前后執(zhí)行
(一) 增添操作 (1) 編寫(xiě)代碼
首先,在 UserMapper 接口中 增加對(duì)應(yīng)的方法
public interface UserMapper {
/**
* 增加用戶(hù)
* @param user
*/
void addUser(User user);
}
接著,在SQL映射文件中,增加新增的映射配置,這些有關(guān)內(nèi)容放在 <insert></insert>標(biāo)簽對(duì)中,具體代碼如下
<insert id="addUser" parameterType="cn.ideal.domain.User">
insert into user(username,telephone,birthday,gender,address)values(#{username},# {telephone},#{birthday},#{gender},#{address})
</insert>
(2) 說(shuō)明:
1、id 屬性,自然是對(duì)應(yīng)的方法名,而由于這里,我們并不需要拿到返回信息,所以這里并沒(méi)有返回參數(shù) resultType,而方法中的參數(shù)又為一個(gè) JavaBean 類(lèi),也就是User實(shí)體類(lèi),所以需要在標(biāo)簽屬性中,添加一個(gè) parameterType 屬性,其中需要指定這個(gè)實(shí)體類(lèi)
2、在文本中書(shū)寫(xiě)插入的SQL語(yǔ)句,由于實(shí)體類(lèi)中已經(jīng)快捷生成了對(duì)應(yīng)的 get set 方法,所一可以使用 #{}的方式代表對(duì)應(yīng)的值
3、提示,數(shù)據(jù)庫(kù)中id為自增,所以并不需要設(shè)置 id
(3) 注意:
由于添加是更新類(lèi)的語(yǔ)句,所以在執(zhí)行插入語(yǔ)句后,需要提交事務(wù),也就是執(zhí)行對(duì)應(yīng)的 commit方法,以提交更新操作,若沒(méi)有這一句,即使不會(huì)報(bào)錯(cuò),也無(wú)法正常存入,會(huì)被回滾,且這個(gè)id被占用
(4) 測(cè)試代碼:
/**
* 測(cè)試新增用戶(hù)
* @throws Exception
*/
@Test
public void testUpdateUser() throws Exception{
User user = new User();
user.setId(17);
user.setUsername("修改");
user.setTelephone("18899999999");
user.setBirthday(new Date());
user.setGender("女");
user.setAddress("廣州");
//執(zhí)行方法
userMapper.updateUser(user);
}
(5) 執(zhí)行結(jié)果:
控制臺(tái):

(6) 獲取新增用戶(hù)的id值
首先對(duì)于 MySQL自增主鍵來(lái)說(shuō),在執(zhí)行 insert語(yǔ)句之前,MySQL 會(huì)自動(dòng)生成一個(gè)自增主鍵,insert執(zhí)行后,通過(guò) SELECT LAST_INSERT_ID() 可以獲取這條剛插入記錄的自增主鍵
在 SQL 映射配置文件中,需要借助 <selectKey></selectKey> 標(biāo)簽,有一個(gè)屬性比較特殊,order 屬性,它代表著相對(duì)于插入操作的執(zhí)行時(shí)間,before-之前,after-之后
注:該標(biāo)簽插入到 <select></select>中
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> SELECT LAST_INSERT_ID(); </selectKey>
測(cè)試一下
@Test
public void testAddUser() throws Exception{
User user = new User();
user.setUsername("增加");
user.setTelephone("12266660000");
user.setBirthday(new Date());
user.setGender("男");
user.setAddress("珠海");
System.out.println("執(zhí)行插入前" + user);
//執(zhí)行方法
userMapper.addUser(user);
System.out.println("執(zhí)行插入后" + user);
}
執(zhí)行效果


(二) 修改操作 (1) 編寫(xiě)代碼
在 UserMapper 接口中增加修改方法
public interface UserMapper {
/**
* 更新用戶(hù)
* @param user
*/
void updateUser(User user);
}
在 SQL 映射文件中增加語(yǔ)句,內(nèi)容包括在 <update></update> 中,需要注意的基本與添加操作是一致的
<update id="updateUser" parameterType="cn.ideal.domain.User">
update user set username=#{username},telephone=#{telephone},birthday=#{birthday},gender=#{gender},address=#{address} where id=#{id}
</update>
(2) 測(cè)試代碼
/**
* 測(cè)試新增用戶(hù)
* @throws Exception
*/
@Test
public void testAddUser() throws Exception{
User user = new User();
user.setUsername("增加");
user.setTelephone("12266668888");
user.setBirthday(new Date());
user.setGender("女");
user.setAddress("成都");
//執(zhí)行方法
userMapper.addUser(user);
}
(3) 執(zhí)行效果


(三) 刪除操作 (1) 編寫(xiě)代碼
接口中增加刪除方法
public interface UserMapper {
/**
* 刪除用戶(hù)
* @param uid
*/
void deleteUser(Integer uid);
}
在SQL映射文件中,使用 <delete></delete> 標(biāo)簽對(duì)進(jìn)行內(nèi)容的書(shū)寫(xiě),需要注意的是,由于我們傳入的參數(shù)是一個(gè) Integer類(lèi)型的用戶(hù)id,所以參數(shù)類(lèi)型的值為 parameterType
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>
(2) 測(cè)試代碼
/**
* 測(cè)試刪除用戶(hù)
* @throws Exception
*/
@Test
public void testDeleteUser() throws Exception{
//執(zhí)行方法
userMapper.deleteUser(17);
}
(3) 執(zhí)行效果


(四) 模糊查詢(xún)
由于查詢(xún)?nèi)糠浅:?jiǎn)單,這里就不展示了,基本流程都是一樣的
(1) 編寫(xiě)代碼
在 UserMapper 接口中編寫(xiě)方法
public interface UserMapper {
/**
* 通過(guò)姓名模糊查詢(xún)
* @param username
* @return
*/
List<User> findByName(String username);
}
在 SQL 映射文件中新增查詢(xún)語(yǔ)句
<select id="findByName" parameterType="java.lang.String" resultType="cn.ideal.domain.User">
select * from user where username like #{username}
</select>
(2) 測(cè)試代碼
/**
* 測(cè)試模糊查詢(xún)
* @throws Exception
*/
@Test
public void testFindByName() throws Exception{
List<User> users = userMapper.findByName("%張%");
for (User user : users){
System.out.println(user);
}
}
(3) 注意
在使用模糊查詢(xún)的時(shí)候,我們需要在查詢(xún)條件的兩側(cè)拼接兩個(gè) “%” 字符串,這個(gè)時(shí)候有兩種解決方案,一種就是像在我上述代碼中,在測(cè)試時(shí)將字符串補(bǔ)充完整,還有一種方式就是 使用 ${} ,它在 SQL配置文件中代表一個(gè) “拼接符號(hào)” ,也就是說(shuō)可以這樣寫(xiě) SQL語(yǔ)句
select * from user where username like '%{value}'
可接受的類(lèi)型有,普通類(lèi)型(此情況下{}內(nèi)部只能寫(xiě)value),JavaBean,HashMap
但是使用 %{} 拼接字符串的時(shí)候,會(huì)引起 SQL注入,所以不是很推薦使用
(4) 執(zhí)行效果


(五) 自定義包裝類(lèi)作為查詢(xún)條件
Mapper 的輸入映射樣例中,我們對(duì)于基本數(shù)據(jù)類(lèi)型和基本數(shù)據(jù)包裝類(lèi),都有了一定的了解,而下面我們來(lái)聊一聊關(guān)于相對(duì)復(fù)雜的一種情況,那就是自定義包裝類(lèi)
先講一個(gè)需求:還是關(guān)于用戶(hù)的查詢(xún),但是查詢(xún)條件復(fù)雜了一些,不僅僅局限于用戶(hù)的信息,而且可能還包括訂單,購(gòu)物車(chē),或者與用戶(hù)一些行為相關(guān)的信息,那么如何實(shí)現(xiàn)這樣一種需求呢?
那我們想,可不可以,在 User 類(lèi)中增加一些我們需要的信息
從代碼的角度來(lái)看,在 User 中添加的字段與數(shù)據(jù)庫(kù)不一定能對(duì)應(yīng)起來(lái),在原來(lái)的基礎(chǔ)上做修改,就會(huì)影響 User 作為數(shù)據(jù)庫(kù)映射對(duì)象的功能,所以我們可以創(chuàng)建一個(gè) UserInstance 類(lèi),繼承 User類(lèi)就可以在其中為某些業(yè)務(wù)添加一些不屬于數(shù)據(jù)庫(kù)的字段了
(1) 定義包裝類(lèi)
package cn.ideal.domain;
public class QueryUserVo {
private UserInstance userInstance;
public UserInstance getUserInstance() {
return userInstance;
}
public void setUserInstance(UserInstance userInstance) {
this.userInstance = userInstance;
}
//其他查詢(xún)條件,例如訂單,購(gòu)物車(chē)等等
}
(2) 配置 Mapper 文件
我們這里使用用戶(hù)的性別以及對(duì)姓名的模糊查詢(xún),來(lái)寫(xiě)SQL 當(dāng)然,你也可以自己通過(guò)別的信息寫(xiě)SQL
<select id="findUserByVo" parameterType="cn.ideal.domain.QueryUserVo" resultType="cn.ideal.domain.UserInstance">
select * from user where user.gender=#{userInstance.gender} and user.username like #{userInstance.username}
</select>
在QueryUserVo 中,封裝的是查詢(xún)信息的各種對(duì)象,為什么上述代碼可以直接通過(guò) userInstance.gender 直接取出對(duì)應(yīng)的屬性,這種方式叫做 OGNL 表達(dá)式,在類(lèi)中 我們的寫(xiě)法通常是 user.getUsername 但在寫(xiě)法上,OGNL 表達(dá)式將get給省略了
(3) 測(cè)試代碼
/**
* 包裝對(duì)象作為查詢(xún)參數(shù)
* @throws Exception
*/
@Test
public void testFindUserByVo() throws Exception{
//創(chuàng)建包裝對(duì)象,設(shè)置查詢(xún)條件
QueryUserVo queryUserVo = new QueryUserVo();
UserInstance userInstance = new UserInstance();
userInstance.setGender("女");
userInstance.setUsername("%張%");
queryUserVo.setUserInstance(userInstance);
//調(diào)用 UserMapper 的方法
List<UserInstance> userInstances
= userMapper.findUserByVo(queryUserVo);
for (UserInstance u : userInstances){
System.out.println(u);
}
}
(4) 執(zhí)行效果

相關(guān)文章
java入門(mén)概念個(gè)人理解之package與import淺析
下面小編就為大家?guī)?lái)一篇java入門(mén)概念個(gè)人理解之package與import淺析。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08
idea全局設(shè)置Maven配置的實(shí)現(xiàn)步驟
本文主要介紹了idea全局設(shè)置Maven配置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
關(guān)于JwtToken使用-重點(diǎn)看一下過(guò)期時(shí)間
這篇文章主要介紹了關(guān)于JwtToken使用-重點(diǎn)看一下過(guò)期時(shí)間,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
SpringBoot?如何通過(guò)?Profile?實(shí)現(xiàn)不同環(huán)境下的配置切換
SpringBoot通過(guò)profile實(shí)現(xiàn)在不同環(huán)境下的配置切換,比如常見(jiàn)的開(kāi)發(fā)環(huán)境、測(cè)試環(huán)境、生產(chǎn)環(huán)境,SpringBoot常用配置文件主要有?2?種:properties?文件和yml文件,本文給大家詳細(xì)介紹SpringBoot?通過(guò)?Profile?實(shí)現(xiàn)不同環(huán)境下的配置切換,感興趣的朋友一起看看吧2022-08-08
關(guān)于@RequestParam注解的使用(簡(jiǎn)單易懂)
這篇文章主要介紹了關(guān)于@RequestParam注解的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
使用Spring?Batch實(shí)現(xiàn)大數(shù)據(jù)處理的操作方法
通過(guò)使用Spring?Batch,我們可以高效地處理大規(guī)模數(shù)據(jù),本文介紹了如何配置和實(shí)現(xiàn)一個(gè)基本的Spring?Batch作業(yè),包括讀取數(shù)據(jù)、處理數(shù)據(jù)和寫(xiě)入數(shù)據(jù)的全過(guò)程,感興趣的朋友跟隨小編一起看看吧2024-07-07

