Spring同時集成JPA與Mybatis
@
目錄
ORM
- ORM的出現,使得關係型數據庫映射成了對象;簡單來說,有了ORM之後,JAVA程序員從面向JDBC編程轉化成面向JAVA對象編程。
Spring ORM
-
Spring對ORM的解決方案主要體現在以下方面:
- 統一的資源管理方式與異常管理:Spring使用各種ORM框架,資源管理及使用方式都是統一的;同時Spring會將各個ORM框架的異常轉譯到Spring異常體系下。
- 統一的事務管理:Spring通過IoC和AOP技術,形成了事務管理抽象層,接管了各種ORM框架下的數據訪問的事務管理。
-
隨着版本的升級,Spring核心包中對ORM的各種解決方案也越來越精鍊。本文我們重點將介紹同時集成Spring Data JPA和Mybatis兩個ORM框架。
Spring ORM 同時集成JPA與Mybatis
- 在同一個項目中一般只會單獨集成Spring Data JPA,或者單獨集成Mybatis。但兩者也可以混合使用(一般沒這個必要),本文為了更加深入探索Spring ,將通過一個DEMO應用兩者的並展示相似點與不同之處。
一、創建一個SpringBoot項目
- 在IntelliJ IDEA中創建新項目
- 通過地址//start.spring.io/初始化項目;
- 指定項目通用信息:
- 選擇項目依賴Starter:
- 生成的項目結構:
二、建立用戶信息登記表
- 根據用戶信息模型類,設計用戶信息登錄表
DROP DATABASE IF EXISTS user_info;
CREATE DATABASE user_info
DEFAULT CHARACTER SET utf8
DEFAULT COLLATE utf8_general_ci;
use user_info;
SET NAMES utf8mb4;
SET FOREIGN_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應用項目集成mysql
- 增加依賴
<!--Mysql依賴包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
<scope>runtime</scope>
</dependency>
<!-- 數據庫連接池:druid數據源驅動 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
- Spring數據源配置
###數據源配置
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-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
五、添加數據表映射實體類
/**
* 用戶類--映射表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;
}
}
六、創建數據接口層
6.1 聲明JPA接口
- 藉助Spring Data JPA,我們可以通過繼承CrudRepository接口,快速定義應用的數據層。CrudRepository定義並實現了很多用於crud(創建、讀取、更新、刪除)操作的方法,我們根本就不用編寫實現類!當應用啟動的時候,Spring Data JPA會在運行期自動生成實現類。
/**
* 基於SpringMVC框架開發web應用--數據操作層
*/
public interface UserRepository extends CrudRepository<User,Long> {
}
- CrudRepository的一些默認實現
public interface CrudRepository<T, ID> extends Repository<T, ID> {
<S extends T> S save(S var1);
<S extends T> Iterable<S> saveAll(Iterable<S> var1);
Optional<T> findById(ID var1);
boolean existsById(ID var1);
Iterable<T> findAll();
Iterable<T> findAllById(Iterable<ID> var1);
long count();
void deleteById(ID var1);
void delete(T var1);
void deleteAll(Iterable<? extends T> var1);
void deleteAll();
}
6.2 聲明MyBatis接口
- 雖然強大的Spring Data JPA已經幫我們封裝了多種數據操作,但由於業務邏輯的複雜度及自定義 SQL的需求,我們仍然可以運用MyBatis框架完成ORM的處理。
/**
* mybatis數據層接口
*
*/
@Repository
public interface UserMapper {
// 自定義添加通過用戶名稱模糊查找用戶信息
List<User> findByName(String name);
}
- Mybatis Mapper映射
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"//mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mybatis.UserMapper">
<!-- 自定義模糊查找 SQL -->
<select id="findByName" resultType="com.example.demo.register.User">
select * from user where name like concat('%',#{name},'%')
</select>
</mapper>
- 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 {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
七、創建業務服務層
- 創建UserService服務層直接調用由Spring Data JPA及Mybatis接口各自提供的數據操作方法,以實現用戶信息的增刪改查。
/**
* 調用Spring Data JPA和Mybatis接口進行業務處理
*/
@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();
}
// 根據名稱查找用戶--Mybatis
public List<User> searchUser(String name) {
return userMapper.findByName(name);
}
}
八、創建控制器
-
控制器的主要職責是處理HTTP請求傳遞給視圖以便於渲染瀏覽器展現。
-
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);
}
// 查找提交並跳轉用戶列表
@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");
}
}
九、設計視圖模板
9.1 設計一個用戶列表的視圖模板
- Thymeleaf提供了一個屬性th:each,它會迭代一個元素集合,為集合中的每個條目渲染HTML,我們可以利用這個屬性,設計出用戶的列表視圖。
<!DOCTYPE html>
<html xmlns:th="//www.thymeleaf.org"
xmlns:layout="//www.ultrag.net.nz/thymeleaf/layout"
>
<head>
<meta charset="UTF-8">
</head>
<body>
<h3>用戶列表</h3>
<div>
<a th:href="@{/user/form}">創建用戶</a>
<a th:href="@{/user/index}">查找用戶</a>
</div>
<table border="1">
<thead>
<tr>
<td>ID</td>
<td>郵箱</td>
<td>名稱</td>
<td>操作</td>
</tr>
</thead>
<tbody>
<tr th:if="${userModel.userList.size()} eq 0">
<td colspan="3">沒有用戶信息!</td>
</tr>
<tr th:each="user:${userModel.userList}">
<td th:text="${user.id}"></td>
<td th:text="${user.email}"></td>
<td th:text="${user.name}"></td>
<td><a th:href="@{/user/form(id=${user.id})}"> 修改 </a> <a th:href="@{/user/del(id=${user.id})}"> 刪除 </a></td>
</tr>
</tbody>
</table>
</body>
</html>
9.2 設計一個提交用戶信息的表單模板
- 用戶通過這個視圖,錄入名稱與郵箱地址,提交保存新用戶的信息。
<!DOCTYPE html>
<html xmlns:th="//www.thymeleaf.org"
xmlns:layout="//www.ultrag.net.nz/thymeleaf/layout"
>
<head>
<meta charset="UTF-8">
</head>
<body>
<h3>登記用戶</h3>
<form action="/users" th:action="@{/user}" method="POST" th:object="${userModel.user}">
<input type="hidden" name="id" th:value="*{id}">
名稱:<br>
<input type="text" name="name" th:value="*{name}">
<br>
郵箱:<br>
<input type="text" name="email" th:value="*{email}">
<input type="submit" value="提交" >
</form>
</body>
</html>
9.3 設計一個用戶模糊查找頁面模板
<!-- index.html-->
<!DOCTYPE html>
<html xmlns:th="//www.thymeleaf.org" >
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
<h3>查找用戶</h3>
<form action="/users" th:action="@{/user/search}" method="POST" th:object="${userModel.user}">
名稱:<br>
<input type="text" name="name" th:value="*{name}" >
<br>
<input type="submit" value="查詢" >
</form>
</body>
</html>
十、運行應用
- 到目前為止,我們已經開發了User用戶類、JPA數據接口、Mybatis數據接口、UserService用戶服務類、UserController控制器、用戶列表視圖模板、用戶登記視圖模板、用戶模糊查找頁面模板,接下來我們嘗試啟動程序,並進行操作測試。
10.1用戶列表
10.2增加用戶
- 點擊頁面上的創建用戶,登記新用戶,並提交
10.3查找用戶
該web應用一切運行正常。