12.25 基於Spring Boot+JPA Restful 風格的數據

第一章 Restful簡介

Restful是一種軟件架構風格,設計風格而不是標準,只是提供了一組設計原則和約束條件。它主要用於客戶端和服

務器交互類的軟件。基於這個風格設計的軟件可以更簡潔,更有層次,更易於實現緩存等機制。

在服務器端,應用程序狀態和功能可以分為各種資源。資源是一個有趣的概念實體,它向客戶端公開。資源的例子

有:應用程序對象、數據庫記錄、算法等等。每個資源都使用 URI (Universal Resource Identifier) 得到一個唯一的

地址。所有資源都共享統一的接口,以便在客戶端和服務器之間傳輸狀態。使用的是標準的 HTTP 方法,比如 GET、

PUT、POST 和 DELETE。Hypermedia 是應用程序狀態的引擎,資源表示通過超鏈接互聯。

在基於Rest的設計中,使用一組通用的動詞來操作資源:

要創建資源:應使用HTTP POST

要檢索資源:應該使用HTTP GET

要更新資源:應使用HTTP PUT

要刪除資源:應該使用HTTP DELETE

第二章 基於 JPA 的 Restful 風格的數據

2.1、構建開發環境

JDK 1.8或更高版本

Maven的3.0+

IntelliJ IDEA集成開發環境

sql腳本:

DROP TABLE IF EXISTS `employee`;

CREATE TABLE `employee` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`name` varchar(50) NOT NULL,

`address` varchar(100) NOT NULL,

`photo` varchar(200) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=1006 DEFAULT CHARSET=utf8;

/*Data for the table `employee` */

insert into `employee`(`id`,`name`,`address`,`photo`) values

(1001,'張三','北京','a.jpg'),

2.2、pom.xml文件

(1002,'李四','上海','b.jpg');

<project>

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0

http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelversion>4.0.0/<modelversion>

<groupid>com.qianfeng.springboot/<groupid>

<artifactid>jpa-restful/<artifactid>

<version>0.0.1-SNAPSHOT/<version>

<packaging>jar/<packaging>

<name>springboot2-mybatis-annotation/<name>

<description>Demo project for Spring Boot/<description>

<parent>

<groupid>org.springframework.boot/<groupid>

<artifactid>spring-boot-starter-parent/<artifactid>

<version>2.0.3.RELEASE/<version>

<relativepath>

<properties>

<project.build.sourceencoding>UTF-8/<project.build.sourceencoding>

<project.reporting.outputencoding>UTF-8/<project.reporting.outputencoding>

<java.version>1.8/<java.version>

<dependencies>

<dependency>

<groupid>org.springframework.boot/<groupid>

<artifactid>spring-boot-starter-web/<artifactid>

<dependency>

<groupid>org.mybatis.spring.boot/<groupid>

<artifactid>mybatis-spring-boot-starter/<artifactid>

<version>1.3.2/<version>

<dependency>

<groupid>mysql/<groupid>

<artifactid>mysql-connector-java/<artifactid>

<scope>runtime/<scope>

<dependency>

<groupid>org.springframework.boot/<groupid>

2.1、配置application.properties屬性文件

主要是配置數據庫的連接、以及jpa的一些屬性

<artifactid>spring-boot-starter-test/<artifactid>

<scope>test/<scope>

<dependency>

<groupid>org.springframework.boot/<groupid>

<artifactid>spring-boot-starter-data-jpa/<artifactid>

<dependency>

<groupid>com.alibaba/<groupid>

<artifactid>druid-spring-boot-starter/<artifactid>

<version>1.1.9/<version>

<build>

<plugins>

<plugin>

<groupid>org.springframework.boot/<groupid>

<artifactid>spring-boot-maven-plugin/<artifactid>

/<project>

server:

port: 8080

spring:

datasource:

name: restful

type: com.alibaba.druid.pool.DruidDataSource

#druid相關配置

druid:

#監控統計攔截的filters

filters: stat

driver-class-name: com.mysql.jdbc.Driver

#基本屬性

url: jdbc:mysql://127.0.0.1:3306/restful?useUnicode=true&characterEncoding=UTF-

8&allowMultiQueries=true

username: root

password: weizhigang

#配置初始化大小/最小/最大

initial-size: 1

min-idle: 1

max-active: 20

#獲取連接等待超時時間

2.3、定義Restful風格訪問的URL

2.4、定義JPA 的Repository接口

max-wait: 60000

#間隔多久進行一次檢測,檢測需要關閉的空閒連接

time-between-eviction-runs-millis: 60000

#一個連接在池中最小生存的時間

min-evictable-idle-time-millis: 300000

validation-query: SELECT 'x'

test-while-idle: true

test-on-borrow: false

test-on-return: false

#打開PSCache,並指定每個連接上PSCache的大小。oracle設為true,mysql設為false。分庫分表較多

推薦設置為false

pool-prepared-statements: false

max-pool-prepared-statement-per-connection-size: 20

jpa:

# 配置 DBMS 類型

database: MYSQL

# 配置是否將執行的 SQL 輸出到日誌

show-sql: true

properties:

hibernate:

hbm2ddl:

# update 只在第一次加載hibernate時自動生成數據庫表結構,以後再次加載hibernate時根據model類自

動更新表結構;

auto: update

package com.qianfeng.springboot.constants;

public class EmpRestURIConstants {

public static final String GET_EMP = "/emps";

public static final String CREATE_EMP = "/emp/create";

public static final String DELETE_EMP = "/emp/delete/{id}";

public static final String UPDATE_EMP = "/emp/update/{id}";

public static final String FIND_EMP = "/emp/findone/{id}";

public static final String DELETE_ALL = "/emp/deleteall";

}

2.4、定義JPA的POJO類(包含註解)

package com.qianfeng.springboot.repository;

import com.qianfeng.springboot.model.Employee;

import org.springframework.data.jpa.repository.JpaRepository;

public interface EmpRepository extends JpaRepository<employee> {/<employee>

}

package com.qianfeng.springboot.model;

import javax.persistence.*;

@Entity

@Table(name = "employee")

public class Employee {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Integer id;

@Column

private String name;

@Column

private String address;

@Column

private String photo;

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

2.3、定義Service組件以及實現類

服務接口:

public String getPhoto() {

return photo;

}

public void setPhoto(String photo) {

this.photo = photo;

}

@Override

public boolean equals(Object o) {

if (this == o) return true;

if (!(o instanceof Employee)) return false;

Employee employee = (Employee) o;

if (!id.equals(employee.id)) return false;

if (!name.equals(employee.name)) return false;

if (!address.equals(employee.address)) return false;

return photo.equals(employee.photo);

}

@Override

public int hashCode() {

int result = id.hashCode();

result = 31 * result + name.hashCode();

result = 31 * result + address.hashCode();

result = 31 * result + photo.hashCode();

return result;

}

}

package com.qianfeng.springboot.service;

import com.qianfeng.springboot.model.Employee;

import org.springframework.data.domain.Example;

import java.util.List;

import java.util.Optional;

public interface EmpService {

public List<employee> findAllEmps();/<employee>

public Optional<employee> findEmpByID(Integer id);/<employee>

public void deleteEmp(Integer id);

public void deleteAllEmp();

public void updateEmp(Employee employee);

public void saveEmp(Employee employee);

public boolean existEmp(Example<employee> example);/<employee>

}

實現類:

package com.qianfeng.springboot.service.impl;

import com.qianfeng.springboot.model.Employee;

import com.qianfeng.springboot.repository.EmpRepository;

import com.qianfeng.springboot.service.EmpService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.Example;

import org.springframework.stereotype.Service;

import java.util.List;

import java.util.Optional;

@Service

public class EmpServiceImp implements EmpService {

@Autowired

private EmpRepository repository;

@Override

public List<employee> findAllEmps() {/<employee>

return repository.findAll();

}

@Override

public Optional<employee> findEmpByID(Integer id) {/<employee>

Optional<employee> employee = repository.findById(id);/<employee>

return employee;

}

@Override

public void deleteEmp(Integer id) {

repository.deleteById(id);

}

@Override

public void deleteAllEmp() {

repository.deleteAll();

}

@Override

public boolean existEmp(Example<employee> example) {/<employee>

return repository.exists(example);

}

@Override

public void updateEmp(Employee employee) {

repository.saveAndFlush(employee);

}

2.4、定義Controller控制器

package com.qianfeng.springboot.controller;

import com.qianfeng.springboot.constants.EmpRestURIConstants;

import com.qianfeng.springboot.model.Employee;

import com.qianfeng.springboot.service.EmpService;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.Example;

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

import org.springframework.web.bind.annotation.*;

import org.springframework.web.util.UriComponentsBuilder;

import java.util.List;

@RestController

@RequestMapping("/api")

public class EmpController {

public static final Logger logger = LoggerFactory.getLogger(EmpController.class);

@Autowired

private EmpService service;

/**

* @param id

* @return

*/

@RequestMapping(value = EmpRestURIConstants.FIND_EMP, method = RequestMethod.GET)

public ResponseEntity> findEmpByID(@PathVariable("id") Integer id) {

logger.info("employee id is " + id);

Employee employee = service.findEmpByID(id).get();

if (employee == null) {

logger.info("employee is not found");

return new ResponseEntity<object>("employee is not found",/<object>

HttpStatus.NOT_FOUND);

}

return new ResponseEntity<employee>(employee, HttpStatus.OK);/<employee>

}

/**

* @return

*/

@RequestMapping(value = EmpRestURIConstants.GET_EMP, method = RequestMethod.GET)

@Override

public void saveEmp(Employee employee) {

repository.save(employee);

}

}

public ResponseEntity> findAllEmp() {

List<employee> list = service.findAllEmps();/<employee>

if (list.isEmpty()) {

return new ResponseEntity(HttpStatus.NO_CONTENT);

}

return new ResponseEntity<list>>(list, HttpStatus.OK);/<list>

}

/**

* @param id

* @return

*/

@RequestMapping(value = EmpRestURIConstants.DELETE_EMP, method = RequestMethod.GET)

public ResponseEntity> deleteEmp(@PathVariable("id") Integer id) {

logger.info("delete employee by id");

Employee employee = service.findEmpByID(id).get();

if (employee == null) {

return new ResponseEntity("unable to delete with id:" + id,

HttpStatus.NOT_FOUND);

}

service.deleteEmp(id);

return new ResponseEntity<employee>(HttpStatus.OK);/<employee>

}

@RequestMapping(value = EmpRestURIConstants.CREATE_EMP, method = RequestMethod.POST)

public ResponseEntity> createEmp(@RequestBody Employee employee, UriComponentsBuilder

builder) {

// logger.info("employee:" + employee);

System.out.println("----->>");

if (service.existEmp(Example.of(employee))) {

logger.info("對象已經存在了");

return new ResponseEntity<object>("name is exist" + employee.getName(),/<object>

HttpStatus.CONFLICT);

}

service.saveEmp(employee);

return new ResponseEntity<employee>(HttpStatus.OK);/<employee>

}

@RequestMapping(value = EmpRestURIConstants.UPDATE_EMP, method = RequestMethod.POST)

public ResponseEntity> updateEmp(@PathVariable("id") Integer id, @RequestBody Employee

employee) {

Employee current = service.findEmpByID(id).get();

if (current == null) {

return new ResponseEntity(HttpStatus.NOT_FOUND);

}

current.setAddress(employee.getAddress());

current.setName(employee.getName());

current.setPhoto(employee.getPhoto());

service.saveEmp(current);

return new ResponseEntity<employee>(current, HttpStatus.OK);/<employee>

}

@RequestMapping(value = EmpRestURIConstants.DELETE_ALL, method = RequestMethod.GET)

public ResponseEntity> deleteALlEmp() {

service.deleteAllEmp();

return new ResponseEntity<employee>(HttpStatus.OK);/<employee>

}

}

2.5 測試

啟動項目,打開postman工具。

2.5.1 emps

選擇GET方式,輸入http://localhost:8080/api/emps,查詢所有的紀錄,見如下效果:

基於Spring Boot+JPA Restful 風格的數據

2.5.2 /emp/create

選擇POST方式,輸入http://localhost:8080/api/emp/create,創建紀錄,見如下效果:

{"name": "張三","address": "北京","photo": "c.jpg"}

基於Spring Boot+JPA Restful 風格的數據

2.5.3 /emp/delete/{id}

選擇GET方式,輸入http://localhost:8080/api/emp/delete/1006,刪除某條紀錄,見如下效果:

基於Spring Boot+JPA Restful 風格的數據

2.5.4 /emp/update/{id}

選擇POST方式,輸入http://localhost:8080/api/emp/update/1001,更新某條紀錄。

{"name": "王五","address": "天津","photo": "c.jpg"}

見如下效果:

基於Spring Boot+JPA Restful 風格的數據


2.5.5 /emp/findone/{id}

選擇GET方式,輸入http://localhost:8080/api/emp/findone/1001,查詢某條紀錄,見如下效果:

基於Spring Boot+JPA Restful 風格的數據

2.5.6 /emp/deleteall

選擇GET方式,輸入http://localhost:8080/api/emp/deleteall,刪除所有紀錄,見如下效果:

基於Spring Boot+JPA Restful 風格的數據


分享到:


相關文章: