通过前⾯课程的学习, 我们掌握了Spring框架和MyBatis的基本使⽤, 并完成了图书管理系统的常规功能 开发, 接下来我们系统的从0到1完成⼀个项⽬的开发;
1. 项⽬介绍
使⽤SSM框架实现⼀个简单的博客系统 共5个⻚⾯
用户登录
博客发表⻚
博客编辑⻚
博客列表⻚
博客详情⻚
1.1 功能描述
⽤⼾登录成功后, 可以查看所有⼈的博客. 点击 《查看原文》 可以查看该博客的正⽂内容;
如果该博客作者为当前登录⽤⼾, 可以完成博客的修改和删除操作, 以及发表新博客 ;
1.2 ⻚⾯预览
登录页面:
博客列表和博客详情⻚:
博客发表和更新页:
2. 准备工作
2.1 数据准备
创建user表和blog表;
sql
create database if not exists spring_blog_240908 charset utf8mb4;
use spring_blog_240908;
drop table if exists user;
create table user (
`id` INT NOT NULL AUTO_INCREMENT,
`user_name` VARCHAR ( 128 ) NOT NULL,
`password` VARCHAR ( 128 ) NOT NULL,
`github_url` VARCHAR ( 128 ) NULL,
`delete_flag` TINYINT ( 4 ) NULL DEFAULT 0,
`create_time` DATETIME DEFAULT now(),
`update_time` DATETIME DEFAULT now(),
PRIMARY KEY ( id ),
UNIQUE INDEX user_name_UNIQUE ( user_name ASC ))
ENGINE = INNODB DEFAULT
CHARACTER set = utf8mb4 comment = '用户表';
drop table if exists blog;
CREATE TABLE blog (
`id` INT NOT NULL AUTO_INCREMENT,
`title` VARCHAR(200) NULL,
`content` TEXT NULL,
`user_id` INT(11) NULL,
`delete_flag` TINYINT(4) NULL DEFAULT 0,
`create_time` DATETIME DEFAULT now(),
`update_time` DATETIME DEFAULT now(),
PRIMARY KEY (id))
ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '博客表';
insert into user (user_name,password,github_url)values("shenmengyao","111111","https://gitee.com/smollye/projects");
insert into user (user_name,password,github_url)values("yuanyiqi","222222","https://gitee.com/smollye/projects");
insert into blog (title,content,user_id) values("第⼀篇博客","我是神喵我是神喵我是神喵",1);
insert into blog (title,content,user_id) values("第⼆篇博客","我是小黑我是小黑我是小黑",2);
数据库信息如下所示:
2.2 创建项⽬
创建SpringBoot项⽬, 添加Spring MVC 和MyBatis对应依赖
2.3 准备前端页面
把课博客系统静态⻚⾯拷⻉到static⽬录下
2.4 配置配置⽂件
java
server:
port: 8087
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/spring_blog_240908?characterEncoding=utf8&useSSL=false
username: root
password: ******
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
configuration:
map-underscore-to-camel-case: true #配置驼峰自动转换
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印Sql语句
mapper-locations: classpath:mapper/**Mapper.xml
# 设置日志路径
logging:
file:
name: spring_blog_240908.log
2.5 测试
访问前端⻚⾯:
前端⻚⾯可以正确显⽰, 说明项⽬初始化成功;
3. 项⽬公共模块
项⽬分为控制层(Controller), 服务层(Service), 持久层(Mapper). 各层之间的调⽤关系如下:
先根据需求完成实体类和公共层代码的编写;
3.1 实体类
java
@Data
public class Blog {
private Integer id;
private String title;
private String content;
private Integer userId;
private String deleteFlag;
private Date createTime;
private Date updateTime;
}
java
@Data
public class User {
private Integer id;
private String userName;
private String password;
private String githubUrl;
private Byte deleteFlag;
private Date createTime;
private Date updateTime;
}
3.2 公共层
3.2.1 统⼀返回结果实体类
a. code: 业务状态码
200: 业务处理成功
-1 : 业务处理失败
-2 : ⽤户未登录
后续有其他异常信息, 可以再补充.
b. msg: 业务处理失败时, 返回的错误信息
c. data: 业务返回数据
业务状态码设置代码如下:
java
public class Constant {
//返回业务的状态码设置
public final static Integer SUCCESS_CODE = 200;
public final static Integer FAIL_CODE = -1;
public final static Integer UNLOGIN_CODE = -2;
}
返回结果实体类设置代码:
java
package com.example.spring_blog_24_9_8.model;
import com.example.spring_blog_24_9_8.constants.Constant;
import lombok.Data;
@Data
public class Result {
private int code;
private String msg;
private Object data;
/**
* 业务成功时执行的方法
*/
public static Result success(Object data){
Result result = new Result();
result.setCode(Constant.SUCCESS_CODE);
result.setMsg("");
result.setData(data);
return result;
}
/**
* 业务执⾏失败时返回的⽅法
*/
public static Result fail(int code, String msg){
Result result = new Result();
result.setCode(Constant.FAIL_CODE);
result.setMsg(msg);
result.setData("");
return result;
}
/**
* ⽤⼾未登录时返回的⽅法
*/
public static Result unlogin(int code,String msg,Object data){
Result result = new Result();
result.setCode(Constant.UNLOGIN_CODE);
result.setMsg("用户未登录");
result.setData(data);
return result;
}
}
3.2.2. 统⼀返回结果
java
package com.example.spring_blog_24_9_8.config;
import com.example.spring_blog_24_9_8.model.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
//哪个接口执行统一结果返回
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;
}
@SneakyThrows
@Override
//统一结果返回的具体逻辑
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType, Class selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
if (body instanceof Result){
return body;
}
//对String 类型单独处理
if (body instanceof String){
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(Result.success(body));
}
return Result.success(body);
}
}
3.3.3. 统⼀异常处理
java
@ControllerAdvice
@ResponseBody
public class ExceptionAdvice {
@ExceptionHandler(Exception.class)
public Result exceptionAdvice(Exception e){
return Result.fail(-1,e.getMessage());
}
}
ps:本文就到这里结束了,该项目未完待续,谢谢观看;