一、 前言
在前面我們已經知道在springboot中如何使用freemark
與thymeleaf
之類的視圖模板引擎去渲染我們的視圖頁面,但是沒涉及跟數據庫交互的東西,所以今天在這裏我們將介紹了一下如何在springboot
中通過spring data jpa
操作mysql
數據庫,並且構建一套簡單的rest api
接口。
## 1.1、Spring Data Jpa 介紹
Spring Data JPA是Spring基於Hibernate開發的一個JPA框架。如果用過Hibernate或者MyBatis的話,就會知道對象關係映射(ORM)框架有多麼方便。但是Spring Data JPA框架功能更進一步,爲我們做了 一個數據持久層框架幾乎能做的任何事情。並且提供了基礎的增刪改查方法,具體api請看官網。
2.2
REST是所有Web應用都應該遵守的架構設計指導原則。
Representational State Transfer,翻譯是”表現層狀態轉化”。
面向資源是REST最明顯的特徵,對於同一個資源的一組不同的操作。資源是服務器上一個可命名的抽象概念,資源是以名詞爲核心來組織的,首先關注的是名詞。REST要求,必須通過統一的接口來對資源執行各種操作。對於每個資源只能執行一組有限的操作。(7個HTTP方法:GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS)
關於rest api
如何涉及我也是從阮一峯老師那裏學習的。
二、目標
首先我們有一個user
表,我們希望能通過構建出對應的rest api
對錶中的數據完成增刪改查操作。
jpa的依賴如下
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
接下來那麼第一步就是創表了
1、創表
由於我們使用的spring data jpa 而jpa的底層實現是hibernate,用過hibernate的同學知道 hibernate可以通過實體類逆向創建表,只需要配置一下ddl-auto
就可以
所以我們需要在application.yml
配置一下
server:
port: 8989
spring:
datasource:
username: root
password: root
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8
driver-class-name: com.mysql.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
show-sql: true
在上面的配置文件中 我們配置了一個數據源跟tomcat端口還有jpa的配置。其中 show-sql: true
代表會在日誌中打印我們操作的sql、
而另外 ddl-auto
有四個值可選,分別是
* create
啓動時刪數據庫中的表,然後創建,退出時不刪除數據表
* create-drop
啓動時刪數據庫中的表,然後創建,退出時刪除數據表 如果表不存在報錯
* update
最常用的屬性,第一次加載hibernate時根據model類會自動建立起表的結構(前提是先建立好數據庫),以後加載hibernate時根據 model類自動更新表結構,即使表結構改變了但表中的行仍然存在不會刪除以前的行。要注意的是當部署到服務器後,表結構是不會被馬上建立起來的,是要等 應用第一次運行起來後纔會。
* validate
項目啓動表結構進行校驗 如果不一致則報錯
所以這裏我們希望當表創建成功後 下次啓動數據還在我們就選擇了update
模式,其次我們需要在本地的mysql
數據庫新建一個test
數據庫。
接下來我們需要編寫的我們實體類User.java
了 hibernate
將會通過實體類的結構在test
數據庫中創建一個對應的user
表
新建包entity
創建User.java
代碼如下:
@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})
@Entity
public class User {
@Id
@GeneratedValue
private Long id;
/**
* 用戶名
*/
@Column(name = "username", nullable = true, length = 32)
private String username;
/**
* 密碼
*/
@Column(name = "password", nullable = true, length = 32)
private String password;
/**
* 年齡
*/
@Column(name = "age", nullable = true, length = 11)
private Integer age;
/**
* 性別 1=男 2=女 其他=保密
*/
@Column(name = "sex", nullable = true, length = 11)
private Integer sex;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
至此,我們的user表也算是創建好了,當我們的程序第一個啓動的時候jpa
會自動在test
數據庫中創建與之對應的表。
2、構建rest api
這裏我們需要構建如下的rest api
url | method | 介紹 |
---|---|---|
/user/ |
get |
獲取所有的用戶信息 |
/user/id/{id} |
get |
根據id獲取用戶信息 |
/user/username/{username} |
get |
根據username獲取用戶信息 |
/user |
post |
新增用戶信息 |
/user |
put |
更新用戶信息 |
/user/id/{id} |
delete |
根據id刪除用戶信息 |
那麼這就是我們需要構建的rest api
,那麼對應的由mvc
模式可知我們的rest api
是controller
層的,所以我們的service
跟repository
層(備註在使用 jpa的時候我們喜歡把dao層命名爲repository)需要提供對應的接口。
首先我們首先需要編寫UserRepository
接口,並且讓它基礎JpaRepository
接口
新建包repository
創建UserRepository.java
代碼如下:
public interface UserRepository extends JpaRepository<User, Long> {
/**
* 根據用戶名查找用戶信息
* @param username
* @return
*/
User findUserByUsername(String username);
}
解釋一下上面的代碼,爲什麼只有一個方法,而前面我們是五個接口,因爲是在JpaRepository中提供較爲基礎的增刪改查方法,我們無需編寫就看使用。如果大家不信按住ctrl
點擊JpaRepository看源碼就知道了。
從上面就可以看出JpaRespository提供了哪些基礎方法了。怎麼樣 是不是覺得很方便。那麼接下來的第二點就Jpa可以根據你的命名規則來推斷你這個方法作用,簡單的來說findUserByUsername
根據這個方法名,jpa可以知道這個方法是通過用戶名去查找用戶。 具體的規則大家可以看文檔
如果大家用的idea的話,那麼它會用智能提示功能,如圖
所以我們只需要編寫方法名就可以輕輕鬆鬆的實現我們的查詢方法,怎麼樣jpa是不是特別簡單,但是需要注意的是方法名一定要命名規範,不要嫌太長了。
接下來就是編寫我們的service層了,
新建service
包創建UserService.java
代碼如下:
public interface UserService {
/**
* 添加用戶信息
* @param user
* @return
*/
User saveUser(User user);
/**
* 更新用戶信息
* @param user
*/
User updateUser(User user);
/**
* 根據id獲取用戶
* @param id
* @return
*/
User getById(Long id);
/**
* 根據名稱獲取用戶
* @param username
* @return
*/
User getByUserName(String username);
/**
* 查詢所有用戶
* @return
*/
List<User> queryAll();
/**
* 根據id刪除用戶信息
* @param id
*/
void deleteById(Long id);
}
接下里就下service的實現類,帶service包下新建impl
包並且創建實現類UserServiceImpl.java
代碼如下
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public User saveUser(User user) {
return userRepository.save(user);
}
@Override
public User updateUser(User user) {
return userRepository.save(user);
}
@Override
public User getById(Long id) {
return userRepository.getOne(id);
}
@Override
public User getByUserName(String username) {
return userRepository.findUserByUsername(username);
}
@Override
public List<User> queryAll() {
return userRepository.findAll();
}
@Override
public void deleteById(Long id) {
userRepository.deleteById(id);
}
}
那麼緊接着就是控制層的代碼了,新建controller
包,並且創建UserController.java
@RestController
@RequestMapping(value = "/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public User save(@RequestBody User user) {
return userService.saveUser(user);
}
@PutMapping
public User update(@RequestBody User user) {
return userService.saveUser(user);
}
@DeleteMapping(value = "/id/{id}")
public String delete(@PathVariable Long id) {
userService.deleteById(id);
return "刪除成功";
}
@GetMapping(value = "/id/{id}")
public User findById (@PathVariable Long id) {
return userService.getById(id);
}
@GetMapping(value = "/username/{username}")
public User findByUsername (@PathVariable String username) {
return userService.getByUserName(username);
}
@GetMapping(value = "/")
public List<User> findAll () {
return userService.queryAll();
}
}
這樣我們就完成了一個簡單的rest api
了啊。
接下來我們來測試一下把。
3、測試
由於我們這裏測試的是rest api普通的瀏覽器是沒法支持 post delet put
方式的訪問的,所以這裏我們就用postman
來測試。
1、首先我們看到test數據庫中現在是一張表都沒有的
啓動程序,注意觀察日誌。
我們看到了日誌打印了創建表的ddl
那麼我們再看看數據庫中有沒有表
此時我們看到了有兩張表,一張是我們user表,而另一張就是主鍵生成序列表。
接下來就開始我們的rest api
測試了。
首先測試新增用戶
打開postman
選擇post模式,輸入訪問的url,然後選擇body中的raw,因爲我們使用的@RequestBody註解,所以我們選擇raw中的Json,如圖
因爲我們的id是自增的,所以我們不要輸入,直接點擊send訪問,如果返回的數據有id那麼就是代表新增成功。如下圖就是新增成功。
打開數據庫中的user表,看看數據有沒有保存成功。
由圖可知,保存成功。
接下來我們就多添加幾條數據。
那麼我們測試一下查詢所有數據的方法。操作如圖
我們剛剛一共添加三條數據,全部都查詢出來了。
我們繼續測試一下修改方法把。我們把id爲2的數據密碼修改爲跟用戶名一樣,具體操作如圖,
點擊send操作成功,我們用根據id查詢的方法來查詢一下剛剛id爲2的數據有沒有修改成功,那麼我們查詢一下id爲2的數據,操作如圖。
由圖中可以看到我們的修改是成功的,用戶名跟密碼已經一樣的,那麼代表我們的根據id查詢方法也是沒問題的。那麼另外幾個方法我們不測試了,留給大家測試。
三、總結
這裏我們通過這次選擇對於jpa的使用有了一個初步的瞭解,並且對於rest api的規範也有了個瞭解。
最後配套教程的代碼全部在這裏
github https://github.com/YuKongEr/SpringBoot-Study。