MyBatis?在?Spring?Boot?中的實(shí)踐記錄
一、什么是 MyBatis
通過 MyBatis中文網(wǎng)站我們了解到 “MyBatis 是一款優(yōu)秀的持久層框架 ” ,用于簡化JDBC的開發(fā),而此處 “ 持久層 ” :指的是持久化操作的層,通常指數(shù)據(jù)訪問層(Dao),用來操作數(shù)據(jù)庫

換句話說,MyBatis 是更簡單的完成程序與數(shù)據(jù)庫交互的框架,即更簡單方便地操作和讀取數(shù)據(jù)庫工具
二、 MyBatis 入門
2.1、創(chuàng)建項(xiàng)目
創(chuàng)建 Spring Boot 項(xiàng)目,并導(dǎo)入 MyBatis 啟動依賴和 MySQL 驅(qū)動包

創(chuàng)建用戶表,并創(chuàng)建對對應(yīng)的實(shí)體類 UserInfo

@Data
public class UserInfo {
private Integer id;
private String username;
private String password;
private Integer age;
private Integer gender;
private String phone;
private Integer deleteFlag;
private Date createTime;
private Date updateTime;
}
數(shù)據(jù)庫規(guī)范:全部小寫,單詞之間用下劃線分割( _ )
Java規(guī)范: 屬性使用小駝峰來表示
注意:我們創(chuàng)建表和實(shí)體類中,要把數(shù)據(jù)庫字段和Java屬性一一對應(yīng)起來
2.2、配置數(shù)據(jù)庫連接字符串
在 application.yml 配置文件中配置如下:
2.3、入門操作
MyBatis 采用 “ 接口+XML/注解 ” 的方式實(shí)現(xiàn)數(shù)據(jù)訪問層,實(shí)現(xiàn)了接口與實(shí)現(xiàn)的分離,其核心機(jī)制為:在運(yùn)行時為接口生成動態(tài)代理對象,即自動創(chuàng)建它的實(shí)現(xiàn)類,能夠輕松創(chuàng)建mock實(shí)現(xiàn)進(jìn)行單元測試
MyBatis 在運(yùn)行時通過 ??動態(tài)代理(Dynamic Proxy)?? 機(jī)制自動生成了接口的實(shí)現(xiàn)類
我們接下來查詢所有用戶
@Mapper
public interface UserInfoMapper {
@Select("SELECT * from user_info")
List<UserInfo> selectAll();
}@Mapper注解:標(biāo)識該接口為 MyBatis 的 Mapper 接口
• 運(yùn)行時框架會自動生成接口代理對象,并交由 Spring IOC 容器管理
• @Select 注解:用于標(biāo)記查詢方法,定義對應(yīng) SQL 查詢語句
2.4、單元測試

測試類已在 src/test 目錄下自動生成,可直接用于測試
@SpringBootTest
class UserInfoMapperTest {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
void selectAll() {
List<UserInfo> userInfos = userInfoMapper.selectAll();
System.out.println(userInfos);
}
}在該測試類上添加了 @SpringBootTest 注解后,運(yùn)行時將自動加載 Spring 運(yùn)行環(huán)境;方法加上@Test 注解后,該方法即可單獨(dú)運(yùn)行;通過@Autowired 注解注入待測試的類后,即可開始進(jìn)行測試
運(yùn)行結(jié)果:成功查詢了所有用戶的信息

三、MyBatis基礎(chǔ)操作(增刪改查)
3.1、配置日志
在MyBatis中我們可以借助日志,查看SQL語句的執(zhí)行,傳遞的參數(shù)以及執(zhí)行的結(jié)果,在application.yml 配置文件中配置(properties文件配置查閱前篇)
mybatis:
configuration: # 配置打印 MyBatis?志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl配置后可以看到

3.2、參數(shù)傳遞
查詢 ID 為 3 的用戶
@Mapper
public interface UserInfoMapper {
@Select("select username,password,age,gender,phone from user_info where id = #{id}")
UserInfo selectById(Integer id);
}當(dāng) Mapper 接口方法的形參僅有一個普通類型參數(shù)時,# {...} 中的屬性名稱可以任意指定,但是如果形參有多個普通類型的參數(shù)時,屬性名稱必須對應(yīng)(見3.3例中代碼)
生成測試用例:#{id}
@Test
void selectById() {
UserInfo userInfo = userInfoMapper.selectById(3);
System.out.println(userInfo);
}查詢結(jié)果:

可通過@Param 注解設(shè)置參數(shù)別名。若使用 @Param 設(shè)置別名,#{...} 中的屬性名必須與 @Param 指定的別名保持一致
@Select("select username,password,age,gender,phone from user_info where id = #{userID}")
UserInfo selectById(@Param("userID") Integer id);
??注意:
@Select("SELECT * from user_info")
List<UserInfo> selectAll();
@Select("select username,password,age,gender,phone from user_info where id = #{userID}")
UserInfo selectById(@Param("userID") Integer id);
@Select("select username,password,age,gender,phone from user_info where age = #{age}")
List<UserInfo> selectAllByAge(Integer age);
3.3、增(Insert)
目標(biāo)SQL語句:

插入另一條數(shù)據(jù),并將SQL中的常量替換成動態(tài)的參數(shù):
@Insert("insert into user_info (username, password, age, gender, phone) values (#{username}, #{password}, #{age}, #{gender}, #{phone})")
Integer insert(UserInfo userInfo); @Test
void insert() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("楚子航");
userInfo.setPassword("123456");
userInfo.setGender(1);
userInfo.setAge(19);
userInfo.setPhone("122222222222");
int result=userInfoMapper.insert(userInfo);
System.out.println("影響的行數(shù)"+result);
}在 MyBatis 中,insert() 方法返回的結(jié)果和在MySQL中返回的結(jié)果是一樣的,都是返回影響的行數(shù),觀察測試結(jié)果:

返回主鍵
我們想在插入之后,拿到剛剛插入的數(shù)據(jù)ID
@Options(useGeneratedKeys = true,keyProperty = "id")
@Insert("insert into user_info (username, password, age, gender, phone) values (#{username}, #{password}, #{age}, #{gender}, #{phone})")
Integer insert(UserInfo userInfo); @Test
void insert() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("路鳴澤");
userInfo.setPassword("123456");
userInfo.setGender(1);
userInfo.setAge(16);
userInfo.setPhone("11111111111");
int result=userInfoMapper.insert(userInfo);
System.out.println("影響的行數(shù)"+result+" id:"+userInfo.getId());
}• useGeneratedKeys:啟用后,MyBatis 將調(diào)用 JDBC 的 getGeneratedKeys 方法來獲取數(shù)據(jù)庫自動生成的主鍵(如 MySQL 和 SQL Server 中的自增字段),默認(rèn)值為 false
• keyProperty:指定用于標(biāo)識對象的唯一屬性,MyBatis 會通過 getGeneratedKeys 的返回值或 insert 語句的 selectKey 子元素為其賦值

注意:
設(shè)置 useGeneratedKeys=true 后,方法返回值仍是受影響的行數(shù),自增 ID 會被自動賦給 keyProperty 指定的屬性
3.4、刪(delete)
將上述
SQL中的常量替換為動態(tài)參數(shù)
@Delete("delete from user_info where id = #{id}")
void deleteById(Integer id); @Test
void deleteById() {
userInfoMapper.deleteById(9);
}觀察運(yùn)行結(jié)果發(fā)現(xiàn)Id為 9 的數(shù)據(jù)已被刪除

3.5、改(update)

將上述SQL中的常量替換為動態(tài)參數(shù)
@Update("update user_info set username = #{username} where id = #{id}")
void updateById(UserInfo userInfo); @Test
void updateById() {
UserInfo userInfo = new UserInfo();
userInfo.setId(5);
userInfo.setUsername("喜羊羊");
userInfoMapper.updateById(userInfo);
}觀察運(yùn)行結(jié)果發(fā)現(xiàn)Id為 5 的數(shù)據(jù)名稱已經(jīng)更改為喜羊羊了

3.6、查(select)
我們再次查詢所有信息
@Select("select id,username,password,age,gender,phone,delete_flag,create_time,update_time from user_info")
List<UserInfo> selectById(); @Test
void selectById() {
List<UserInfo> userInfoList = userInfoMapper.selectById();
System.out.println(userInfoList);
}從運(yùn)行結(jié)果可以看出,SQL語句中查詢了 delete_flag、create_time 和 update_time 字段,但這些字段并未被賦值

為什么呢? 這時我們會想到是不是 Java 屬性和數(shù)據(jù)庫字段對應(yīng)的名稱不一致造成的原因呢?
@Select("select id,username,password,age,gender,phone," +
"delete_flag as deleteflag,create_time as createtime,update_time as updatetime " +
"from user_info")
List<UserInfo> selectById();
運(yùn)行結(jié)果:

MyBatis在自動映射查詢結(jié)果時,會按以下步驟處理:
- 獲取查詢結(jié)果返回的列名
- 在目標(biāo)Java類中查找名稱匹配的屬性(不區(qū)分大小寫)
- 當(dāng)列名與屬性名匹配時(例如數(shù)據(jù)庫列"ID"對應(yīng)Java屬性"id"),自動將列值映射到對應(yīng)屬性
解決方法
3.6.1、起別名
如上猜測,將數(shù)據(jù)庫字段名稱通過起別名的方法與Java屬性名稱保持一致,另外我們從下方代碼可見SQL語句可以用 + 連接
@Select("select id,username,password,age,gender,phone," +
"delete_flag as deleteflag,create_time as createtime,update_time as updatetime " +
"from user_info")
List<UserInfo> selectById();3.6.2、結(jié)果映射
@Results 注解用于建立數(shù)據(jù)庫字段與 Java 對象屬性之間的映射關(guān)系,它包含一個由 @Result 元素組成的數(shù)組,其中每個元素通過 column 指定數(shù)據(jù)庫列名,property 指定對應(yīng)的 Java 屬性名,從而實(shí)現(xiàn)二者之間的映射關(guān)聯(lián)
@Results({
@Result(column = "delete_flag",property = "deleteFlag"),
@Result(column = "create_time",property = "createTime"),
@Result(column = "update_time",property = "updateTime")
})
@Select("select id,username,password,age,gender,phone,delete_flag,create_time,update_time from user_info")
List<UserInfo> selectResult();現(xiàn)在的問題是:我們上述代碼實(shí)現(xiàn)了眾多增刪改查方法,每個方法進(jìn)行結(jié)果映射都需要字段復(fù)制操作,如果其他方法涉及不同的數(shù)據(jù)庫字段,來回修改會非常不便。在Aokey看來,這并不比使用別名便利
針對這種情況,我們可以通過 Id 屬性為 Results 定義別名,然后使用 @ResultMap 注解來復(fù)用其他已經(jīng)定義的 ResultMap 配置

3.6.3、 配置駝峰自動轉(zhuǎn)換
在 application.yml 配置文件中配置如下:
mybatis:
configuration:
map-underscore-to-camel-case: true #配置駝峰?動轉(zhuǎn)換 @Select("select id,username,password,age,gender,phone,delete_flag,create_time,update_time from user_info where age = #{age}")
List<UserInfo> selectAllByAge(Integer age);查詢結(jié)果:

到此這篇關(guān)于破繭 JDBC:MyBatis 在 Spring Boot 中的輕量實(shí)踐指南的文章就介紹到這了,更多相關(guān)mybatis springboot使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot+MybatisPlus+jdbc連接池配置多數(shù)據(jù)源的實(shí)現(xiàn)
- SpringBoot+MybatisPlus實(shí)現(xiàn)sharding-jdbc分庫分表的示例代碼
- SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分庫分表
- SpringBoot多數(shù)據(jù)源配置詳細(xì)教程(JdbcTemplate、mybatis)
- SpringBoot 整合jdbc和mybatis的方法
- MyBatis框架簡介及入門案例詳解
- 淺談MyBatis-plus入門使用
- MyBatis Plus 入門使用詳細(xì)教程
相關(guān)文章
java中LinkedBlockingQueue與ArrayBlockingQueue的異同
這篇文章主要介紹了java中LinkedBlockingQueue與ArrayBlockingQueue的異同,需要的朋友可以參考下2016-08-08
Mybatis應(yīng)用mysql存儲過程查詢數(shù)據(jù)實(shí)例
下面小編就為大家分享一篇Mybatis應(yīng)用mysql存儲過程查詢數(shù)據(jù)實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12
利用hadoop查詢兩兩之間有共同好友及他倆的共同好友都是誰
一想到要實(shí)現(xiàn)求共同好友的功能,很多人都會想到redis來實(shí)現(xiàn)。但是redis存儲和數(shù)據(jù)和計(jì)算時需要耗費(fèi)較多的內(nèi)存資源。所以文本將介紹另一種方法,即利用Hadoop中的MapReduce來實(shí)現(xiàn),感興趣的可以了解一下2022-01-01
springboot連接訂閱OPCUA數(shù)據(jù)的實(shí)現(xiàn)
本文主要介紹了springboot連接訂閱OPCUA數(shù)據(jù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-07-07
java基于quasar實(shí)現(xiàn)協(xié)程池的方法示例
本文主要介紹了java基于quasar實(shí)現(xiàn)協(xié)程池的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧<BR>2022-06-06

