第一章 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,查询所有的纪录,见如下效果:
2.5.2 /emp/create
选择POST方式,输入http://localhost:8080/api/emp/create,创建纪录,见如下效果:
{"name": "张三","address": "北京","photo": "c.jpg"}
2.5.3 /emp/delete/{id}
选择GET方式,输入http://localhost:8080/api/emp/delete/1006,删除某条纪录,见如下效果:
2.5.4 /emp/update/{id}
选择POST方式,输入http://localhost:8080/api/emp/update/1001,更新某条纪录。
{"name": "王五","address": "天津","photo": "c.jpg"}
见如下效果:
2.5.5 /emp/findone/{id}
选择GET方式,输入http://localhost:8080/api/emp/findone/1001,查询某条纪录,见如下效果:
2.5.6 /emp/deleteall
选择GET方式,输入http://localhost:8080/api/emp/deleteall,删除所有纪录,见如下效果:
閱讀更多 指尖上的代碼 的文章