思路分析
在springboot_vue项目,进行前端代码开发(在上一篇)
在springboot_furn项目,进行后端代码开发(本篇完成)
感受前后端项目分离。
后端项目创建及环境配置
创建springboot_furn项目
创建成maven项目,不选模板,完成创建
2. 完成pom.xml依赖配置
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.5.3</version>
</parent>
<dependencies>
<!--web开发,场景启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--druid数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.17</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--配置处理器:配置application.yml文件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<!--test的项目启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
</dependencies>
3. 创建application.yml,配置port端口,以及DB连接信息
main/sources/application.yml
端口配置是为了防止与前端port冲突
server:
port: 8080
spring:
datasource:
password: root
username: root
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/monster?useSSL=true&useUnicode=true&charactorEncoding=utf-8
4. 创建main程序
com.stein.furn.Application.java
测试能否正常运行。已经能出现whitelabel的报错了
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
思路分析
1.完成后台代码从mapper->service->controller,并对每层代码进行测试,到controller这一层,使用Postman发送http请求完成测试
2.完成前台代码,使用axios发送json数据给后台,实现添加家居信息
创建数据库,完善数据
创建com/stein/furn/utils/Result.java该工具类用于返回结果(json格式)
这个工具类,在网上也可找到,直接拿来使用,SSM项目也用过类似的工具类
public class Result <T>{
private Integer code;
private String msg;
private T data;
//再添加 getter and setter
// 无参构造器
public Result(){
}
//有参构造器
public Result(T data){
this.data=data;
}
//成功方法返回-无参
public static Result success(){
Result result = new Result<>();
result.setCode("200");
result.setMsg("success");
return result;
}
// 泛型方法
public static <T>Result<T> success(T data){
Result<T> result = new Result<>(data);
result.setCode("200");
result.setMsg("success");
return result;
}
//错误-无返回data
public static Result error(String code,String msg){
Result result = new Result<>();
result.setCode(code);
result.setMsg(msg);
return result;
}
//错误-有返回data
public static <T> Result<T> error(String code,String msg,T data){
Result<T> result = new Result<>(data);
result.setCode(code);
result.setMsg(msg);
return result;
}
}
DAO层-开发Mapper
参考数据库表的属性,创建Bean
@TableName("furn")当名称与表名不一致时,使用该注解
@TableFiled(value = "img_path")。处理字段含有_下划线时,返回值为null的问题
java中的字段不要使用_下划线命名,否则也会返回null。
应该是有将下划线自动转驼峰命名。不使用注解@TableFiled也拿到了返回值
@Data
public class Furn {
private Integer id;
private String name;
private String maker;
private Double price;
private Integer sales;
private Integer stock;
//@TableField(value = "img_path")
private String imgPath;
}
2. 创建XxxMapper 接口 并extends BaseMapper<Furn>
可以使用@Mapper注解进行注入。(与下面的方法二选一)
//@Mapper
public interface FurnMapper extends BaseMapper<Furn> {
}
还可以在Application使用@MapperScan(basePackages = "com.stein.furn.mapper")
@MapperScan(basePackages = "com.stein.furn.mapper")
@SpringBootApplication
public class Application {...}
3. 测试
@Resource
private FurnMapper furnMapper;
@Test
public void testFurnMapper(){
System.out.println("furnMapper的类型:"+furnMapper.getClass());
Furn furn = furnMapper.selectById(3);
System.out.println("furn="+furn);
}
Service层
创建FurnService接口,extends IService
注意继承类型的泛型设置,没有设置会影响实现类
public interface FurnService extends IService<Furn> {
}
创建FurnServiceImpl实现类,implements接口,extends ServiceImpl
注意这儿的泛型设置
注意这儿的注解@Service,这个注解类标注在实现层的。区别于Mapper层的接口
@Service
public class FurnServiceImpl
extends ServiceImpl<FurnMapper, Furn>
implements FurnService {
}
测试
成功会返回表furn的数据
@Resource
private FurnService furnService;
@Test
public void testFurnService(){
List<Furn> list = furnService.list();
for (Furn furn : list) {
System.out.println("furn="+furn);
}
}
Controller层
创建映射
@RestController是一个复合注解=@ResponseBody+@Controller
@RequestBody 用于接收json格式的数据,不是json就不要使用它
个人小问题。操作的时候写错成了@RequestParam导致出错。问题原因
如果是通过url或者form传递的参数,会自动封装,不要使用@RequestBody
还要注意表头格式(Content-Type)的一致性。现在版本的postman已经自动变更了。
@RestController
@Slf4j
public class FurnController {
@Resource
private FurnService furnService;
@PostMapping("/save")
public Result save(@RequestBody Furn furn){
log.info("传入参数furn="+furn);
furnService.save(furn);
return Result.success();
}
}
2. 使用Postman进行测试
通过body->raw->json选择正确的格式测试
可以变换url或者form的方式传参,此时要删除@RequestBody,注意Content-Type
{
"id":400,
"name":"superdesk",
"maker":"stein",
"price":80,
"sales":20,
"stock":10,
"imgPath":"/assets/default"
}
3. 处理主键自增长问题
前面我们的参数是设置了"id":400,数据也这样保存到了Mysql。但是表的设计是自增长,所以这样并不是很合适。
如果我们把id的这一栏设置删除再提交,又会报错,不能保存。解决办法是:
使用在bean对应的主键添加注解@TableId(type = IdType.AUTO)来设置主键,参数表明自增
现在再提交删除了id的json数据,就不会报错了,而且id自增保存。
也可以提交包含id的数据,但不会生效,由数据库自动设置
本质还是数据库设置的id值