创建项目
创建Spring项目,pom文件中主要包含如下依赖:
// jpa - Java持久化API
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
// web开发
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
// mysql连接
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
下面以Customer对象的持久化为例。
创建Curtomer实体类
创建一个Customer实体类,包含三个域和有参、无参构造函数(有参和无参构造函数必须存在,否则项目运行会报错)。由于id会由注解自动生成,构造函数无需包括id域。
@Entity
@Data
@RequiredArgsConstructor
@NoArgsConstructor
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NonNull
private String name;
@NonNull
private int age;
}
注解@Id表示类Customer类的数据在数据库中的主键为被标注的域id,注解@GeneratedValue表示该类的域id会在类被创建时自动创建,免去了手动生成不重复ID的麻烦。
GenerationType有多种选择,包括:
- AUTO - 由连接到的数据库的偏好决定
- SEQUENCE
- TABLE
- IDENTITY - 数据库ID自增长
- UUID
- CUSTOM
- NONE - 相当于不加
@GeneratedValue注解,一般在由自己写的代码生成ID时使用
创建Repository接口
创建一个继承了CrudRepository的接口CustomerRepository。Spring Data JPA会在运行时自动生成实现类。该类会继承用于数据库操作的函数,直接调用类中的方法就能对数据库进行增删改查。
import org.springframework.data.repository.CrudRepository;
public interface CustomerRepository extends CrudRepository<Customer, Long> {
}
传递给CrudRepository的类型参数<S, ID>表示数据库存储的是S实例,主键为ID类型。
在Idea的结构页面中可以看到从CrudRepository继承到的方法。
配置配置文件
在配置文件aplication.properties中配置数据库连接。
spring.jpa.hibernate.ddl-auto=update
# 数据源,指定MySQL端口和保存的数据库,注意该数据库必须存在
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/hat
# 用户名
spring.datasource.username=root
# 密码
spring.datasource.password=
# 数据库驱动
spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver
# 是否在操作数据库时记录日志输出
spring.jpa.show-sql: false
其中spring.jpa.hibernate.ddl-auto属性的意义在这篇文章中讲得很清楚。
编写RESTful服务
在类CustomerController中编写处理Customer类的Web服务。
@RestController
@RequestMapping("/customer")
public class CustomerController {
@Autowired // 自动装配customerRepository类
private CustomerRepository customerRepository;
@PostMapping("/") // 处理`/customer`路径的HTTP POST请求
public String postHandler(@RequestParam String name,
@RequestParam int age) {
customerRepository.save(new Customer(name, age));
return "saved!";
}
@GetMapping(path = "/{id}", produces = "application/json") // 处理`/customer`路径的HTTP GET请求,指定输出对象为json格式
public Customer getHandler(@PathVariable Long id) {
// 调用`orElse`方法,当`findById`给出的`Optional`对象中不包含对象时返回null
return customerRepository.findById(id).orElse(null);
}
}
这样,每当/customer路径接收到HTTP GET或者POST请求时,程序就会查询或修改数据库。
测试
启动项目,使用Idea自带的HTTP客户端发送请求。
POST请求存储数据:
POST http://localhost:1000/customer/?name=alice&age=30
HTTP/1.1 200
Content-Length: 6
Connection: keep-alive
Content-Type: text/plain;charset=UTF-8
Date: Sat, 12 Jun 2021 10:10:06 GMT
Keep-Alive: timeout=4
Proxy-Connection: keep-alive
saved!
Response code: 200; Time: 331ms; Content length: 6 bytes
数据被正常存储到数据库中,存储的表结构为id,name,age。
GET请求查询数据:
GET http://localhost:1000/customer/3
HTTP/1.1 200
Transfer-Encoding: chunked
Connection: keep-alive
Content-Type: application/json
Date: Sat, 12 Jun 2021 10:10:21 GMT
Keep-Alive: timeout=4
Proxy-Connection: keep-alive
{
"id": 3,
"name": "alice",
"age": 30
}
Response code: 200; Time: 109ms; Content length: 32 bytes
正常返回了请求的json对象。