Spring笔记1——极简入门教程

环境准备

系统:MacOS
开发:IntelliJ IDEA
语言:Java8
其它:Mysql、Redis

脚手架代码
Spring提供了一个创建项目脚手架的官网,在这里可以直接定制项目的框架代码。例如:

注意:在Dependencies中,添加了Web依赖。
点击【Generate Project】,即可下载项目框架代码。
创建工程
将框架代码包解压后放到工作目录。打开IDEA,点击【File] -> 【Open】,打开对应目录。
启动工程
找到com.spring.demo.demo下的DemoApplication,右键点击运行后,console中即可显示Spring启动的信息。
Controller
在传统MVC架构中,Controller负责接收Http请求并返回相应的应答,这个应答可以是一个页面,也可以是一个JSON对象。方便起见,本教程使用RestfulAPI为例。
添加RestController
创建一个UserController,负责响应User相关的业务请求。对于纯数据的API接口,使用@RestControll进行标注,这样每一个API接口的返回值就会被转化为JSON结构的数据。
package com.spring.demo.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

@RequestMapping(“/user”)
public String find() {
return “UserA”;
}
}
重启应用,在浏览器中请求http://localhost:8080/user,即可看到请求的返回内容:UserA。
路径参数
对于带路径参数的请求,可以通过@PathVariable 标注来获取参数值。如:
package com.spring.demo.demo.controller;

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

@RestController
public class UserController {

@RequestMapping(“/user/{id}”)
public String find(@PathVariable int id) {
return “用户ID[” + id + “]”;
}
}
POST请求
对于POST请求,可以使用@PostMapping 来标注方法,接收的JSON数据需要使用@RequestBody来标注。

@PostMapping(“/user”)
public void create(@RequestBody UserCreateRequest user) {
System.out.println(user.getName());
}

这里的UserCreateRequest,用来接收并转换JSON数据。
package com.spring.demo.demo.dto;

public class UserCreateRequest {

private String name;
private boolean gender;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public boolean isGender() {
return gender;
}

public void setGender(boolean gender) {
this.gender = gender;
}
}
在IDEA的Terminal中,使用curl来进行测试。
curl -XPOST ‘http://127.0.0.1:8080/user’ -H ‘Content-Type: application/json’ -d'{“name”:”用户A”,”gender”:0}’
参数校验
有时我们需要对传入参数进行非空或有效值的校验,这个处理应该在正式进入controller前进行。
1. 添加@Validated标注
在SpringMVC中,对输入参数进行校验通常使用@Validated标注。

@PostMapping(“/user”)
public void create(@RequestBody @Validated UserCreateRequest user) {
System.out.println(user.getName());
}

2. 添加校验规则标注@
在对应的字段上,加上对应的校验规则标注。
package com.spring.demo.demo.dto;

import javax.validation.constraints.NotNull;

public class UserCreateRequest {

@NotNull
private String name;

private boolean gender;

// Getters & Setters

}

添加后重启服务,发送不含name字段的POST请求,结果如下:
Service
MVC框架中,Controller负责接收请求和相应,Service则负责具体的业务处理,即Model层。
Service在定义是需要使用@Service标注,SpringBoot在启动中将会注册该Service并在Controller通过DI来实例化并使用该Service。
一般来说,我们会创建一个Service的接口类和一个对应的实现类。
IUserService
package com.spring.demo.demo.service;

public interface IUserService {
public String findUser(int id);
}
UserService
package com.spring.demo.demo.service;

import org.springframework.stereotype.Service;

@Service
public class UserService implements IUserService {

public String findUser(int id) {
return “用户” + id;
}
}

在调用时,Controller会直接应用接口类,并添加@Autowired标签。这里的调用原理,即是Sping最著名的DI(依赖注入)和IoC(控制反转)。
package com.spring.demo.demo.controller;

import com.spring.demo.demo.dto.UserCreateRequest;

@RestController
public class UserController {

@Autowired
IUserService userService;

@RequestMapping(“/user/{id}”)
public String find(@PathVariable int id) {
return userService.findUser(id);
}

@PostMapping(“/user”)
public void create(@RequestBody @Validated UserCreateRequest user) {
System.out.println(user.getName());
}
}
此时重启Spring,并使用curl进行请求,可以得到结果:
$ curl -XGET ‘http://127.0.0.1:8080/user/100’
$ 用户100
Repository
Spring本身集成了Spring Data JPA,用来作为访问数据库的ORM工具,它采用了Hibernate实现。在本教程,我们将实现User的增和查的工作。
添加依赖
修改pom.xml,添加对mysql和jpa的支持。

<dependencies>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
服务配置
修改/resources/application.properties,添加相关的设置。

spring.datasource.url=jdbc:mysql://localhost:3306/demo?useSSL=false
spring.datasource.username=root
spring.datasource.password=123456

spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true
添加Repository和Entity
Repository在DDD中是一个非常重要的概念,字面意思来讲它就是一个仓库。它屏蔽了SQL和数据库操作的细节,使得业务代码无需再考虑更细节的数据处理。它和Mybatis可以说是两个完全相反的流派。
Spring Data JPA中,默认实现了Crud操作的Repository,可以直接继承并使用这个框架进行快速的CRUD实现。
package com.spring.demo.demo.repo.repository;

import com.spring.demo.demo.repo.entity.User;

@Repository
public interface UserRepository extends CrudRepository<User, Integer> { }
对应数据库中的数据表,会有一个实体Entity来定义它的表结构。
package com.spring.demo.demo.repo.entity;

import javax.persistence.*;

@Entity
@Table(name=”t_user”)
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private Integer gender;

// Getter & Setter

}

在Service调用中,即可简单的使用save方法来保存新的User数据。
package com.spring.demo.demo.service;

import com.spring.demo.demo.repo.entity.User;

@Service
public class UserService implements IUserService {

@Autowired
UserRepository userRepo;

public String findUser(int id) {
return “用户” + id;
}

public User createUser(User user) {
return userRepo.save(user);
}
}
最后在Controller中,修改Service方法并创建User。
package com.spring.demo.demo.controller;

import com.spring.demo.demo.dto.UserCreateRequest;

@RestController
public class UserController {

@Autowired
IUserService userService;

@RequestMapping(“/user/{id}”)
public String find(@PathVariable int id) {
return userService.findUser(id);
}

@PostMapping(“/user”)
public void create(@RequestBody @Validated UserCreateRequest userReq) {

User user = new User();
user.setName(userReq.getName());
user.setGender(userReq.getGender());

user = userService.createUser(user);
System.out.println(“创建用户 ID=” + user.getId() + ” 用户名=” + user.getName());
}
}
重启Spring并提交创建请求。
$ curl -XPOST ‘http://127.0.0.1:8080/user’ -H ‘Content-Type: application/json’ -d'{“name”:”用户A”,”gender”:0}’
可以看到,在console中有创建成功的提示信息。
Hibernate: insert into t_user (gender, name) values (?, ?)创建用户 ID=1 用户名=用户A

缓存
对于不常改变的数据,常常需要进行缓存以提高系统性能和增加系统吞吐量。对此,Spring Cache提供了缓存的基本实现。
添加依赖
修改pom.xml,添加对cache的支持。

<dependencies>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
服务配置
修改/resources/application.properties,添加相关的设置。

spring.cache.type=simple
打开开关
需要在Application中,打开Cache开关。
package com.spring.demo.demo;

import org.springframework.boot.SpringApplication;

@SpringBootApplication
@EnableCaching
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}

}

使用Cacheable标注
对于Cache内容,需要添加一个key名来保存内容。
package com.spring.demo.demo.service;

import com.spring.demo.demo.repo.entity.User;

@Service
public class UserService implements IUserService {

@Autowired
UserRepository userRepo;

@Cacheable(cacheNames = “user”)
public User findUser(Integer id) {
System.out.println(“取得用户操作 ID=” + id);
return userRepo.findById(id).get();
}

public User createUser(User user) {
return userRepo.save(user);
}
}
重启Spring,发送GET请求后可以看到,只有第一次执行了SQL操作,说明缓存处理已经完成。
$ curl -XGET ‘http://127.0.0.1:8080/user/1’
$ 用户A
$ 用户A
> 取得用户操作 ID=1=
> Hibernate: select user0_.id as id1_0_0_, user0_.gender as gender2_0_0_, user0_.name as name3_0_0_ from t_user user0_ where user0_.id=?
Redis
Spring的默认Cache处理并不使用Redis,要使用Redis作为缓存应用,需要添加Redis的框架支持。
添加依赖
修改pom.xml,添加对cache的支持。

<dependencies>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
服务配置
修改/resources/application.properties,添加相关的设置。

spring.redis.host=127.0.0.1
spring.redis.password=123456
spring.redis.port=6379
spring.redis.jedis.pool.max-active=8
序列化对象
由于要保存到redis中,保存的实体对象需要进行序列化。
package com.spring.demo.demo.repo.entity;

import java.io.Serializable;

@Entity
@Table(name=”t_user”)
public class User implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private Integer gender;

// Getter & Setter

}

重启Spring,再试一遍上节的操作,仍然是一样的结果,但缓存已经换为redis。
$ curl -XGET ‘http://127.0.0.1:8080/user/1’
$ 用户A
$ 用户A
> 取得用户操作 ID=1
> Hibernate: select user0_.id as id1_0_0_, user0_.gender as gender2_0_0_, user0_.name as name3_0_0_ from t_user user0_ where user0_.id=?

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理