來(lái)源:北大青鳥(niǎo)總部 2023年03月03日 14:08
伴隨著微服務(wù)的如此火爆的趨勢(shì),SpringBoot逐漸成為了目前Java開(kāi)發(fā)領(lǐng)域的必備技能,如果不會(huì)點(diǎn)SpringBoot感覺(jué)都沒(méi)臉在這個(gè)程序猿的森林里混。所以在掌握SpringBoot已經(jīng)成為了大家的共識(shí),同時(shí)SpringBoot和其他的無(wú)縫集成也成了程序員的必備技能,比如:MyBatis、Redis等......
SpringBoot作為Spring家族的明星產(chǎn)品,一出世就受到了廣泛的關(guān)注。Spring作為這座森林里的"森林之王",除了自家的技術(shù)給予了無(wú)縫的鏈接的支持,對(duì)于其他優(yōu)秀的技術(shù),也是抱著開(kāi)放的態(tài)度,支持各種優(yōu)秀的開(kāi)源技術(shù)主動(dòng)向SpringBoot的靠攏,MyBatis就是其中之一。
我們都知道在使用SpringBoot的過(guò)程中,常用的持久化解決方案主要有兩種,一種是Mybatis框架,另一個(gè)就是SpringData JPA。
而 SpringData Jpa和MyBatis最大的區(qū)別就是SpringData Jpa是Spring親生的,這個(gè)從名字的命名方式上也能看出來(lái),當(dāng)然是因?yàn)樗鼈兪且患胰肆恕?/p>
為什么這么說(shuō)呢?如果大家用過(guò)Mybatis的話(huà)應(yīng)該會(huì)發(fā)現(xiàn),Mybatis依賴(lài)的artifactId是mybatis-spring-boot-starter,而接下來(lái)我們要講的SpringDataJPA依賴(lài)的artifactId卻是spring-boot-starter-data-jpa,從這個(gè)名字關(guān)鍵字(mybatis、jpa)的順序上,我們就能看出來(lái)誰(shuí)才是親生的。
雖然不是親生的,但是Mybatis憑借自己輕巧靈活的身姿(易上手、動(dòng)態(tài)SQL等),贏得了廣大開(kāi)發(fā)者的喜愛(ài),大有奪嫡的之勢(shì)。
所以這篇文章咱么就來(lái)聊聊SpringBoot整合MyBatis的技術(shù)細(xì)節(jié)。
常言道,兵馬未動(dòng),糧草先行;沒(méi)有穩(wěn)重的大后方,前線(xiàn)的將士如何安心打仗,飯都沒(méi)了,即使打贏了也是會(huì)餓死的,所以在整合Mybatis之前呢,咱么還得先做一些準(zhǔn)備工作,咱么首先使用SpringInitializer來(lái)構(gòu)建SpringBoot的基礎(chǔ)工程,然后在此基礎(chǔ)上再進(jìn)行整合Mybatis
創(chuàng)建數(shù)據(jù)庫(kù)
建數(shù)據(jù)庫(kù)表
通常情況下,建議數(shù)據(jù)庫(kù)名字以英文命名,數(shù)據(jù)庫(kù)的名字就叫kgc(課工場(chǎng)拼音首字母),字符集選擇utf8,排序規(guī)則選擇utf8generalci。字符集和排序規(guī)則也可以不選使用默認(rèn)設(shè)置。設(shè)置完成之后點(diǎn)擊“確定”。
創(chuàng)建好數(shù)據(jù)庫(kù)之后,我們就要?jiǎng)?chuàng)建數(shù)據(jù)庫(kù)表,表名叫t_user,這張用戶(hù)表有三個(gè)屬性,分別是:
id 唯一標(biāo)記
username 用戶(hù)名稱(chēng)
age 年齡
并插入三條數(shù)據(jù):
# 數(shù)據(jù)庫(kù)腳本文件 SET NAMES utf8mb4; -- ---------------------------- -- Table structure for t_user -- ---------------------------- DROP TABLE IF EXISTS `t_user`; CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) NOT NULL, `age` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8; # 插入數(shù)據(jù) INSERT INTO `t_user`(username, age) VALUES ('張三', '18'); INSERT INTO `t_user`(username, age) VALUES ( '李四', '20'); INSERT INTO `t_user` (username, age) VALUES ('王五', '22'); |
做好準(zhǔn)備工作之后,接下來(lái)最重要的就是要在pom.xml文件中添加數(shù)據(jù)庫(kù)驅(qū)動(dòng)和數(shù)據(jù)庫(kù)連接池依賴(lài)。
添加MySQL驅(qū)動(dòng),這里如果不指定版本默認(rèn)是8.0的版本,當(dāng)然你也可以指定版本,8.0的版本這里有一問(wèn)比較坑的問(wèn)題:
MySQL數(shù)據(jù)庫(kù)默認(rèn)使用的是美國(guó)的時(shí)區(qū),而我們連接的時(shí)候用的是中國(guó)的北京時(shí)間,然后比美國(guó)晚上8個(gè)小時(shí),所以當(dāng)我們?cè)谶B接數(shù)據(jù)庫(kù)的時(shí)候要設(shè)置一下時(shí)區(qū)為東八區(qū)ServerTimezone=UTC
驅(qū)動(dòng)類(lèi)
MySQL5.x的版本使用的驅(qū)動(dòng)類(lèi)是com.mysql.jdbc.Driver
MySQL8.x的版本使用的驅(qū)動(dòng)類(lèi)是com.mysql.cj.jdbc.Driver
所以這兩個(gè)問(wèn)題需要大家去注意一下,以免出現(xiàn)莫名其妙的bug
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> |
接著,添加數(shù)據(jù)庫(kù)連接池,這里咱們使用最火的阿里開(kāi)源的Druid。
Druid首先是一個(gè)數(shù)據(jù)庫(kù)連接池。Druid是目前最好的數(shù)據(jù)庫(kù)連接池,在功能、性能、擴(kuò)展性方面,都超過(guò)其他數(shù)據(jù)庫(kù)連接池,包括DBCP、C3P0、BoneCP、Proxool、JBossDataSource。Druid已經(jīng)在阿里巴巴部署了超過(guò)600個(gè)應(yīng)用,經(jīng)過(guò)一年多生產(chǎn)環(huán)境大規(guī)模部署的嚴(yán)苛考驗(yàn)。Druid是阿里巴巴開(kāi)發(fā)的號(hào)稱(chēng)為監(jiān)控而生的數(shù)據(jù)庫(kù)連接池!
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.9</version> </dependency> |
添加Mybatis的依賴(lài),我們使用最新的版本2.0.1
番外篇:
如果大家細(xì)心的話(huà)可能會(huì)發(fā)現(xiàn),通常我們?cè)诩梢恍㏒pringBoot提供支持的技術(shù)的時(shí)候,所添加的依賴(lài)都是以spring-boot-starter開(kāi)頭,格式:spring-boot-starter-xxx;但是剛才我們添加的Mybatis的依賴(lài)卻是mybatis-spring-boot-starter,是以mybatis開(kāi)頭的,這個(gè)能其實(shí)是SpringBoot默認(rèn)是不支持mybatis的,它默認(rèn)支持的是它自己生態(tài)內(nèi)的持久層框架JPA,由于SpringBoot是大勢(shì)所趨,所以mybatis就主動(dòng)去迎合SpringBoot生態(tài),自己開(kāi)發(fā)了mybatis的stater。以后大家凡是看到xxx-spring-boot-starter的依賴(lài),都是SpringBoot沒(méi)有主動(dòng)提供支持的技術(shù)。
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency> |
在pojo包下創(chuàng)建User對(duì)象,并實(shí)現(xiàn)序列化接口Serializable
public class User implements Serializable{ private Integer id; //用戶(hù)id private String username; //用戶(hù)名 private Integer age; //年齡 // 省略 setter、getter方法 } |
在application.properties屬性配置文件中配置數(shù)據(jù)源和mybatis相關(guān)配置
# 端口號(hào) server.port=8080 # mapper xml 文件地址 mybatis.mapper-locations=classpath*:mapper/*Mapper.xml # 數(shù)據(jù)庫(kù)url spring.datasource.url=jdbc:mysql://localhost:3306/kgc?characterEncoding=utf8&serverTimezone=UTC # 數(shù)據(jù)庫(kù)用戶(hù)名 spring.datasource.username=root # 數(shù)據(jù)庫(kù)密碼 spring.datasource.password=root # 數(shù)據(jù)庫(kù)驅(qū)動(dòng) spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver |
在mapper包下創(chuàng)建UserMapper接口,并在接口中定義各一個(gè)方法
并在resource包下創(chuàng)建依次創(chuàng)建com/example/demo/mapper/UserMapper.xml
這里要注意的是接口名稱(chēng)要和映射文件的名稱(chēng)一致
在測(cè)試之前我還需要在SpringBoot的主啟動(dòng)類(lèi)上加上一段注解配置@MapperScan,這個(gè)注解的意思是掃描我們com.example.demo.mapper包下的mapper接口并創(chuàng)建代理對(duì)象。
@SpringBootApplication @MapperScan(basePackages = {"com.example.demo.mapper"}) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } |
然后在我們的controller中寫(xiě)一個(gè)測(cè)試的方法,可以直接使用@Autowired注解注入U(xiǎn)serMapper,有同學(xué)可能會(huì)有這樣的疑問(wèn)?接口是不能創(chuàng)建對(duì)象怎么能注入呢,因?yàn)樵赟pringBoot啟動(dòng)的時(shí)候,會(huì)創(chuàng)建UserMapper的代理對(duì)象,所以實(shí)際上我們注入的是代理對(duì)象,這個(gè)跟咱么上一步說(shuō)加@MapperScan正好可以對(duì)應(yīng)上的。
@RestController public class DemoController { @Autowired private UserMappper userMappper; /** * 查詢(xún)所有用戶(hù)信息 */ @GetMapping("/hello") public List<User> hello() { List<User> users = userMappper.selectUserList(); return users; } } |
然后在瀏覽器地址欄輸入http://localhost:8080/hello,就可以看到瀏覽器已經(jīng)查詢(xún)出來(lái)數(shù)據(jù),這些數(shù)據(jù)和我們插入數(shù)據(jù)的數(shù)據(jù)是一樣的。這就說(shuō)明我們SpringBoot集成Mybatis成功跑通了,是不是很簡(jiǎn)單呢?
在實(shí)際的開(kāi)發(fā)過(guò)程中,SpringBoot和MyBatis的整合也是這么簡(jiǎn)單。如果你認(rèn)真看完這篇文章,那么恭喜你又掌握了一新技能!