Spring同時集成JPA與Mybatis

目錄

ORM

Spring ORM

Spring ORM 同時集成JPA與Mybatis一收苏、創(chuàng)建一個SpringBoot項(xiàng)目二、建立用戶信息登記表三喉酌、Web應(yīng)用項(xiàng)目集成mysql四热凹、添加Spring Data JPA和Mybatis依賴五、添加數(shù)據(jù)表映射實(shí)體類六泪电、創(chuàng)建數(shù)據(jù)接口層6.1 聲明JPA接口6.2 聲明MyBatis接口七般妙、創(chuàng)建業(yè)務(wù)服務(wù)層八、創(chuàng)建控制器九相速、設(shè)計(jì)視圖模板9.1 設(shè)計(jì)一個用戶列表的視圖模板9.2 設(shè)計(jì)一個提交用戶信息的表單模板9.3 設(shè)計(jì)一個用戶模糊查找頁面模板十碟渺、運(yùn)行應(yīng)用10.1用戶列表10.2增加用戶10.3查找用戶

ORM

ORM的出現(xiàn),使得關(guān)系型數(shù)據(jù)庫映射成了對象突诬;簡單來說苫拍,有了ORM之后,JAVA程序員從面向JDBC編程轉(zhuǎn)化成面向JAVA對象編程攒霹。

Spring ORM

Spring對ORM的解決方案主要體現(xiàn)在以下方面:統(tǒng)一的資源管理方式與異常管理:Spring使用各種ORM框架怯疤,資源管理及使用方式都是統(tǒng)一的浆洗;同時Spring會將各個ORM框架的異常轉(zhuǎn)移到Spring異常體系下催束。統(tǒng)一的事務(wù)管理:Spring通過IoC和AOP技術(shù),形成了事務(wù)管理抽象層伏社,接管了各種ORM框架下的數(shù)據(jù)訪問的事務(wù)管理抠刺。

隨著版本的升級,Spring核心包中對ORM的各種解決方案也越來越精煉摘昌。本文我們重點(diǎn)將介紹同時集成Spring Data JPA和Mybatis兩個ORM框架速妖。

Spring ORM 同時集成JPA與Mybatis

在同一個項(xiàng)目中一般只會單獨(dú)集成Spring Data JPA,或者單獨(dú)集成Mybatis。但兩者也可以混合使用(一般沒這個必要)聪黎,本文為了更加深入探索Spring 罕容,將通過一個DEMO應(yīng)用兩者的并展示相似點(diǎn)與不同之處。

一稿饰、創(chuàng)建一個SpringBoot項(xiàng)目

在IntelliJ IDEA中創(chuàng)建新項(xiàng)目

通過地址https://start.spring.io/初始化項(xiàng)目锦秒;

指定項(xiàng)目通用信息:

選擇項(xiàng)目依賴Starter:

生成的項(xiàng)目結(jié)構(gòu):

二、建立用戶信息登記表

根據(jù)用戶信息模型類喉镰,設(shè)計(jì)用戶信息登錄表

DROPDATABASEIFEXISTSuser_info;

CREATEDATABASEuser_info

DEFAULTCHARACTERSETutf8

DEFAULTCOLLATEutf8_general_ci;

useuser_info;

SETNAMESutf8mb4;

SETFOREIGN_KEY_CHECKS =0;

-- ----------------------------

-- Table structure for user

-- ----------------------------

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user`? (

? `id` bigint(20) NOT NULL AUTO_INCREMENT,

? `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? `email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,

? PRIMARY KEY (`id`) USING BTREE

) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

三旅择、Web應(yīng)用項(xiàng)目集成mysql

增加依賴

<!--Mysql依賴包-->

mysql

mysql-connector-java

5.1.47

runtime

<!-- 數(shù)據(jù)庫連接池:druid數(shù)據(jù)源驅(qū)動 -->

com.alibaba

druid-spring-boot-starter

1.1.10

Spring數(shù)據(jù)源配置

###數(shù)據(jù)源配置

spring:? datasource:? ? type: com.alibaba.druid.pool.DruidDataSource? ? username: root? ? password: root? ? driver-class-name:net.sf.log4jdbc.sql.jdbcapi.DriverSpy

url: jdbc:log4jdbc:mysql://localhost:3306/user_info?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true

四、添加Spring Data JPA和Mybatis依賴

<!--pom.xml-->

<!--Spring Data JPA-->

org.springframework.boot

spring-boot-starter-data-jpa

<!-- mybatis -->

org.mybatis.spring.boot

mybatis-spring-boot-starter

1.3.2

五侣姆、添加數(shù)據(jù)表映射實(shí)體類

/**

* 用戶類--映射表user

*

* @author zhuhuix

*/

@Entity

@Table(name="user_info")

public class User implements Serializable {// 用戶id

? ? @Id

? ? @GeneratedValue(strategy = GenerationType.IDENTITY)

? ? private Long id;

? ? // 用戶名

? ? @NotBlank(message = "用戶名稱不能為空")

? ? @Column(name="name")

? ? private String name;

? ? // 郵箱

? ? @Column(name="email")

? ? @Pattern(message ="郵箱格式不符", regexp = "^[A-Za-z0-9\\u4e00-\\u9fa5]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$")

? ? private String email;

? ? public User(Long id, String name, String email) {

? ? ? ? this.id = id;

? ? ? ? this.name = name;

? ? ? ? this.email = email;

? ? }

? ? public Long getId() {

? ? ? ? return id;

? ? }

? ? public void setId(Long id) {

? ? ? ? this.id = id;

? ? }

? ? public String getName() {

? ? ? ? return name;

? ? }

? ? public void setName(String name) {

? ? ? ? this.name = name;

? ? }

? ? public String getEmail() {

? ? ? ? return email;

? ? }

? ? public void setEmail(String email) {

? ? ? ? this.email = email;

? ? }

}

六生真、創(chuàng)建數(shù)據(jù)接口層

6.1 聲明JPA接口

借助Spring Data JPA沉噩,我們可以通過繼承CrudRepository接口,快速定義應(yīng)用的數(shù)據(jù)層柱蟀。CrudRepository定義并實(shí)現(xiàn)了很多用于crud(創(chuàng)建川蒙、讀取、更新产弹、刪除)操作的方法派歌,我們根本就不用編寫實(shí)現(xiàn)類!當(dāng)應(yīng)用啟動的時候痰哨,Spring Data JPA會在運(yùn)行期自動生成實(shí)現(xiàn)類胶果。

/**

* 基于SpringMVC框架開發(fā)web應(yīng)用--數(shù)據(jù)操作層

*/

publicinterfaceUserRepositoryextendsCrudRepository{

}

CrudRepository的一些默認(rèn)實(shí)現(xiàn)

publicinterfaceCrudRepositoryextendsRepository{

Ssave(S var1);

IterablesaveAll(Iterable<S> var1);

OptionalfindById(ID var1);

booleanexistsById(ID var1);

IterablefindAll();

IterablefindAllById(Iterable<ID> var1);

longcount();

voiddeleteById(ID var1);

voiddelete(T var1);

voiddeleteAll(Iterable<? extends T> var1);

voiddeleteAll();

}

6.2 聲明MyBatis接口

雖然強(qiáng)大的Spring Data JPA已經(jīng)幫我們封裝了多種數(shù)據(jù)操作,但由于業(yè)務(wù)邏輯的復(fù)雜度及自定義 SQL的需求斤斧,我們?nèi)匀豢梢赃\(yùn)用MyBatis框架完成ORM的處理早抠。

/**

* mybatis數(shù)據(jù)層接口

*

*/

@Repository

publicinterfaceUserMapper {

// 自定義添加通過用戶名稱模糊查找用戶信息

? ? List<User> findByName(String name);


}

Mybatis Mapper映射

<?xml version="1.0" encoding="UTF-8" ?>

PUBLIC"-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- 自定義模糊查找 SQL -->

select * from user where name like concat('%',#{name},'%')

Spring添加MyBatis配置

修改application.yml配置文件:定位mapper文件掃描路徑

#MyBatis掃描mapper文件配置

mybatis:

mapper-locations:classpath:mapper/*Mapper.xml

在啟動類里加上注解用于給出需要掃描的mapper文件路徑

@SpringBootApplication

@MapperScan(basePackages ="com.example.demo.register")

public class DemoApplication {publicstaticvoidmain(String[] args) {

SpringApplication.run(DemoApplication.class, args);

}}

七钦无、創(chuàng)建業(yè)務(wù)服務(wù)層

創(chuàng)建UserService服務(wù)層直接調(diào)用由Spring Data JPA及Mybatis接口各自提供的數(shù)據(jù)操作方法哪雕,以實(shí)現(xiàn)用戶信息的增刪改查邪财。

/**

* 調(diào)用Spring Data JPA和Mybatis接口進(jìn)行業(yè)務(wù)處理 */

@Service

public class UserService {

? ? // Spring Data JPA

? ? @Autowired

? ? private UserRepository userRepository;

? ? // Mybatis

? ? @Autowired

? ? private UserMapper userMapper;

? ? // 返回所有的用戶

? ? public List<User> listUsers() {

? ? ? ? return (List<User>) userRepository.findAll();

? ? }

? ? // 保存用戶

? ? public User saveUser(User user) {

? ? ? ? return userRepository.save(user);

? ? }

? ? // 刪除用戶

? ? public void deleteUser(Long id) {

? ? ? ? userRepository.deleteById(id);

? ? }

? ? // 查找用戶

? ? public User findUser(Long id) {

? ? ? ? return userRepository.findById(id).get();

? ? }

? ? // 根據(jù)名稱查找用戶--Mybatis

? ? public List<User> searchUser(String name) {

? ? ? ? return userMapper.findByName(name);

? ? }

}

加Q群:927953692? ?歡迎討論交流告嘲,另外可免費(fèi)領(lǐng)取一份(Java學(xué)習(xí)視頻昵观,技術(shù)文檔撵幽,電子書籍贵涵,基礎(chǔ)面試題)

八联喘、創(chuàng)建控制器

控制器的主要職責(zé)是處理HTTP請求傳遞給視圖以便于渲染瀏覽器展現(xiàn)烘豌。

SpirngMVC的請求注解

注解描述@RequestMapping通用的請求@GetMapping處理HTTP GET請示@PostMapping處理HTTP POST請示@PutMapping處理HTTP PUT請示@DeleteMapping處理HTTP DELETE請示

/**

* 用戶控制器 */

@RestController

@RequestMapping("/user")

public class UserController {

? ? @Autowired

? ? private UserService userService;

? ? // 保存用戶并返回到用戶列表頁面

? ? @PostMapping

? ? public ModelAndView saveUser(@Valid User user, Errors errors, Model model) {

? ? ? ? if (errors.hasErrors()) {

? ? ? ? ? ? model.addAttribute("user", user);

? ? ? ? ? ? if (errors.getFieldError("name") != null) {

? ? ? ? ? ? ? ? model.addAttribute("nameError", errors.getFieldError("name").getDefaultMessage());

? ? ? ? ? ? }

? ? ? ? ? ? if (errors.getFieldError("email") != null) {

? ? ? ? ? ? ? ? model.addAttribute("emailError", errors.getFieldError("email").getDefaultMessage());

? ? ? ? ? ? }

? ? ? ? ? ? return new ModelAndView("register", "userModel", model);

? ? ? ? }

? ? ? ? userService.saveUser(user);

? ? ? ? //重定向到list頁面

? ? ? ? return new ModelAndView("redirect:/user");

? ? }

? ? // 獲取用戶操作表單頁面

? ? @GetMapping("/form")

? ? public ModelAndView createForm(Model model, @RequestParam(defaultValue = "0") Long id) {

? ? ? ? if (id > 0) {

? ? ? ? ? ? model.addAttribute("user", userService.findUser(id));

? ? ? ? } else {

? ? ? ? ? ? model.addAttribute("user", new User());

? ? ? ? }

? ? ? ? return new ModelAndView("register", "userModel", model);

? ? }

? ? // 獲取用戶列表顯示頁面

? ? @GetMapping

? ? public ModelAndView list(Model model) {

? ? ? ? model.addAttribute("userList", userService.listUsers());

? ? ? ? return new ModelAndView("userlist", "userModel", model);

? ? }

? ? // 模糊查找輸入頁面

? ? @GetMapping("/index")

? ? public ModelAndView index(Model model) {

? ? ? ? model.addAttribute("user", new User());

? ? ? ? return new ModelAndView("index", "userModel", model);

? ? }

? ? // 查找提交并跳轉(zhuǎn)用戶列表

? ? @PostMapping("/search")

? ? public ModelAndView search(@ModelAttribute User user, Model model) {

? ? ? ? model.addAttribute("userList", userService.searchUser(user.getName()));

? ? ? ? return new ModelAndView("userlist", "userModel", model);

? ? }

? ? // 刪除用戶

? ? @RequestMapping(path = "/del")

? ? public ModelAndView del(@RequestParam(name = "id") Long id) {

? ? ? ? userService.deleteUser(id);

? ? ? ? return new ModelAndView("redirect:/user");

? ? }

}

九载庭、設(shè)計(jì)視圖模板

9.1 設(shè)計(jì)一個用戶列表的視圖模板

Thymeleaf提供了一個屬性th:each,它會迭代一個元素集合廊佩,為集合中的每個條目渲染HTML囚聚,我們可以利用這個屬性,設(shè)計(jì)出用戶的列表視圖标锄。

xmlns:layout="http://www.ultrag.net.nz/thymeleaf/layout"

>

用戶列表

創(chuàng)建用戶

查找用戶

ID

郵箱

名稱

操作

沒有用戶信息顽铸!

修改刪除

9.2 設(shè)計(jì)一個提交用戶信息的表單模板

用戶通過這個視圖,錄入名稱與郵箱地址料皇,提交保存新用戶的信息谓松。

xmlns:layout="http://www.ultrag.net.nz/thymeleaf/layout"

>

登記用戶

名稱:


郵箱:

9.3 設(shè)計(jì)一個用戶模糊查找頁面模板

<!-- index.html-->

Title

查找用戶

名稱:


十、運(yùn)行應(yīng)用

到目前為止践剂,我們已經(jīng)開發(fā)了User用戶類鬼譬、JPA數(shù)據(jù)接口、Mybatis數(shù)據(jù)接口舷手、UserService用戶服務(wù)類拧簸、UserController控制器、用戶列表視圖模板男窟、用戶登記視圖模板盆赤、用戶模糊查找頁面模板贾富,接下來我們嘗試啟動程序,并進(jìn)行操作測試牺六。

10.1用戶列表

10.2增加用戶

點(diǎn)擊頁面上的創(chuàng)建用戶颤枪,登記新用戶,并提交

10.3查找用戶

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末淑际,一起剝皮案震驚了整個濱河市畏纲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌春缕,老刑警劉巖盗胀,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異锄贼,居然都是意外死亡票灰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門宅荤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來屑迂,“玉大人,你說我怎么就攤上這事冯键∪桥危” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵惫确,是天一觀的道長手报。 經(jīng)常有香客問我,道長雕薪,這世上最難降的妖魔是什么昧诱? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任晓淀,我火速辦了婚禮所袁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凶掰。我一直安慰自己燥爷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布懦窘。 她就那樣靜靜地躺著前翎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪畅涂。 梳的紋絲不亂的頭發(fā)上港华,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天,我揣著相機(jī)與錄音午衰,去河邊找鬼立宜。 笑死冒萄,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的橙数。 我是一名探鬼主播尊流,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼灯帮!你這毒婦竟也來了崖技?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤钟哥,失蹤者是張志新(化名)和其女友劉穎迎献,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腻贰,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡忿晕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了银受。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片践盼。...
    茶點(diǎn)故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖宾巍,靈堂內(nèi)的尸體忽然破棺而出咕幻,到底是詐尸還是另有隱情,我是刑警寧澤顶霞,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布肄程,位于F島的核電站,受9級特大地震影響选浑,放射性物質(zhì)發(fā)生泄漏蓝厌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一古徒、第九天 我趴在偏房一處隱蔽的房頂上張望拓提。 院中可真熱鬧,春花似錦隧膘、人聲如沸代态。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蹦疑。三九已至,卻和暖如春萨驶,著一層夾襖步出監(jiān)牢的瞬間歉摧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叁温,地道東北人豆挽。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像券盅,于是被迫代替她去往敵國和親帮哈。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評論 2 359