项目5-博客系统1(准备工作+博客列表+博客详情页)

1.创建项目

导入以下依赖

2.项目介绍

使⽤SSM框架实现⼀个简单的博客系统
共5个页面

2.1 前端页面展示

2.1.1 用户登录


2.1.2 博客发表页


2.1.3 博客编辑页


2.1.4 博客列表页


2.1.5博客详情页

2.2 功能描述:

⽤⼾登录成功后, 可以查看所有⼈的博客.

点击 <<查看全⽂>> 可以查看该博客的正⽂内容.

如果该博客作者为当前登录⽤⼾, 可以完成博客的修改和删除操作, 以及发表新博客

3.准备工作

3.1 数据准备

3.1.1 建立SQL

-- 建表SQL
create database if not exists java_blog_spring charset utf8mb4;
USE java_blog_spring;
-- 用户表
DROP TABLE IF EXISTS java_blog_spring.user;
CREATE TABLE java_blog_spring.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 java_blog_spring.blog;
CREATE TABLE java_blog_spring.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 java_blog_spring.user (user_name, password,github_url)values
("lay","107","https://www.weibo.com/u/2706896955?c=spr_qdhz_bd_360ss_weibo_mr");
insert into java_blog_spring.user (user_name, password,github_url)
values("muyierf","123456","https://gitee.com/muyierf");
insert into java_blog_spring.blog (title,content,user_id) values("第1篇博
客","lay的筑梦之旅",1);
insert into java_blog_spring.blog (title,content,user_id) values("第1篇博
客","muyierf的第一篇博客",2);

 创建成功!!!

3.2 前端代码引入项目中

3.3 配置配置文件

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/java_blog_spring?characterEncoding=utf8&useSSL=falseusername: rootpassword: 123456driver-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-book.log

3.4 测试项目能否启动成功

成功!!!

3.5 开发前的准备

3.5.1 项目流程

1.需求分析

2.技术方案设计
1)UML图,流程图,ER图

2)数据库设计

3)接口设计(我们需要完成的工作)

3.开发(我们需要完成的工作)

4.自测(我们需要完成的工作)

5.测试(QA)

6.联调

7. 验收

8.上线

3.5.2 数据库表的创建 

数据库表通常分两类:
1.实体表->对象 (员工表,部门表,图书表,博客表..)

2.关系表->实体之间的关系

我们的项目较为简单,所以我们只需要两个实体表即可。

用户表:用户名,密码,照片,昵称,github地址

1.根据用户名,查询用户信息
2.根据用户ID,查询用户信息

博客表: 标题,日期,内容,作者, 分类.. 

1.查询博客列表
2.根据博客ID, 查询博客信息
3.根据博客ID, 修改博客信息

4.插入博客

3.5.3 接口设计

1.用户登录
根据用户名和密码, 判断是否正确->根据用户名,查询用户信息,对比密码是否正确

2.查询用户信息
根据用户ID,查询用户信息->根据用户ID,去查询用户信息

3.博客列表

查询所有博客->查询所有博客

4.查询作者信息

1)根据博客, 拿到作者ID
2)根据作者ID,获取作者信息

->根据用户ID,去查询用户信息

5.查询博客详情

->根据博客ID, 查询博客信息

6.修改博客->根据博客ID, 修改博客信息

7.添加博客->插入博客信息

8.删除博客
1)物理删除
2)逻辑删除->根据博客ID,修改博客信息

3.5.4 建包 

  • controller
  • service
  • mapper
  • model
  • config
  • constants(里面写枚举类和常量类都可以)

4.代码部分 

4.1. 实体类(model包)

//要与数据库一致

package com.example.demo.model;import lombok.Data;import java.util.Date;@Data
public class BlogInfo {private Integer id;private String title;private String content;private Integer userId;private Integer deleteFlag;private Date createTime;private Date updateTime;
}
package com.example.demo.model;import lombok.Data;import java.util.Date;@Data
public class UserInfo {private Integer id;private String userName;private String password;private String githubUrl;private Byte deleteFlag;private Date createTime;private Date updateTime;
}

4.2 公共模块

包括实体类和同一功能处理<1.拦截器2.统一功能处理3.统一结果返回>

4.2.1. 统一返回结果实体类

a. code: 业务状态码
▪ 200: 业务处理成功
▪ -1 : 业务处理失败
▪ -2 : ⽤⼾未登录
▪ 后续有其他异常信息, 可以再补充.
b. msg: 业务处理失败时, 返回的错误信息
c. data: 业务返回数据

定义业务状态码//我们将这些确定的状态码存入Constants包中,防止修改 

package com.example.demo.model;import com.example.demo.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.setData(Constant.RESULT_CODE_SUCCESS);result.setMsg("");result.setData(data);return result;}public static Result fail(int code,String msg){Result result=new Result();result.setData(Constant.RESULT_CODE_FAIL);result.setMsg(msg);result.setData("");return result;}public static Result unlogin(int code,String msg,Object data){Result result=new Result();result.setData(Constant.RESULT_CODE_UNLOGIN);result.setMsg("用户未登录");result.setData(data);return result;}
}

4.2.2 统一返回结果

4.2.2.1 统一功能处理
package com.example.demo.model.result;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
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.servlet.mvc.method.annotation.ResponseBodyAdvice;public class ResponseAdvice implements ResponseBodyAdvice {@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,Class selectedConverterType, ServerHttpRequest request,ServerHttpResponse response) {if(body instanceof Result){return body;}if(body instanceof String){ObjectMapper objectMapper=new ObjectMapper();try {return objectMapper.writeValueAsString(Result.success(body));} catch (JsonProcessingException e) {e.printStackTrace();}}return Result.success(body);}
}

 记得加此注解!!!

统⼀的数据返回格式使⽤ @ControllerAdvice 和 ResponseBodyAdvice 的⽅式实现
@ControllerAdvice 表⽰控制器通知类
添加类 ResponseAdvice , 实现 ResponseBodyAdvice 接⼝, 并在类上添加@ControllerAdvice 注解

4.2.2.2 统一异常处理

@ExceptionHandler 是异常处理器,两个结合表⽰当出现异常的时候执⾏某个通知,也就是执⾏某个⽅法事件

package com.example.demo.model.result;import com.example.demo.constants.Constant;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;@ControllerAdvice
@ResponseBody
public class ExceptionAdvice {@ExceptionHandlerpublic Result exceptionAdvice(Exception e){return Result.fail(Constant.RESULT_CODE_FAIL,e.getMessage());}
}

4.2.2.3 拦截器 

4.3 业务代码

4.3.1 持久层(mapper)

根据需求, 先⼤致计算有哪些DB相关操作, 完成持久层初步代码, 后续再根据业务需求进⾏完善

1. 用户登录页

  • 根据用户名查询用户信息(select语句)

2. 博客列表⻚

  • 根据id查询user信息(select语句->通过id查询用户表)
  • 获取所有博客列表(select语句->通过id查询博客表

3. 博客详情⻚

  • 根据博客ID查询博客信息
  • 根据博客ID删除博客(修改delete_flag=1,update)

4. 博客修改⻚

  • 根据博客ID修改博客信息(update)

5. 发表博客

  • 插⼊新的博客数据(insert)

1.BlogInfoMapper 

package com.example.demo.mapper;import com.example.demo.model.BlogInfo;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper
public interface BlogMapper {//a.获取所有博客列表@Select("select * from blog where delete_flag=0 order by create_time desc")List<BlogInfo> selectAllBlog();//b.根据博客id查询它的博客@Select("select * from blog where delete_flag=0 and id=#{id}")BlogInfo selectByIdBlog();//c.插⼊新的博客数据(insert)@Insert("insert into blog (title,content,user_id) values (#{title},#{content},#{userId})")Integer insertNewBlog(BlogInfo blogInfo);//d.博客修改页和博客删除页(update)-动态mybatis->xmlInteger updateBlog(BlogInfo blogInfo);}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.demo.mapper.BlogInfoMapper"><update id="updateBlog">update blog<set><if test="title!=null">title=#{title},</if><if test="content!=null">content=#{content},</if><if test="deleteFlag !=null">delete_flag = #{deleteFlag}</if></set>where id=#{id}</update>
</mapper>

2.UserInfoMapper

package com.example.demo.mapper;import com.example.demo.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;@Mapper
public interface UserInfoMapper {//1.根据id查询用户的信息@Select("select * from user where id = #{id}")UserInfo selectById(Integer id);//2.根据用户名查询用户的信息,登陆操作时用@Select("select * from user where user_name = #{userName}")UserInfo selectByName(String name);
}
4.3.1.1 测试持久层
package com.example.demo.mapper;import com.example.demo.model.BlogInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import static org.junit.jupiter.api.Assertions.*;@SpringBootTest
class BlogInfoMapperTest {@Autowiredprivate BlogInfoMapper blogInfoMapper;@Testvoid selectAllBlog() {System.out.println(blogInfoMapper.selectAllBlog());}@Testvoid selectByIdBlog() {System.out.println( blogInfoMapper.selectByIdBlog(1));}@Testvoid insertNewBlog() {BlogInfo blogInfo=new BlogInfo();blogInfo.setTitle("测试接口");blogInfo.setContent("单元测试测试接⼝测试接⼝");blogInfo.setUserId(5);blogInfoMapper.insertNewBlog(blogInfo);}@Testvoid updateBlog() {BlogInfo blogInfo=new BlogInfo();blogInfo.setId(3);blogInfo.setTitle("测试接口ing");blogInfo.setDeleteFlag(1);blogInfoMapper.updateBlog(blogInfo);}
}

测试成功!!!

测试结果

 数据库也成功录入信息!!!

4.3.2 实现博客列表

4.3.2.1 约定前后端交互接口
[请求]
/blog/getlist
[响应]
{"code": 200,"msg": "","data": [{"id": 1,"title": "第⼀篇博客","content": "111我是博客正⽂我是博客正⽂我是博客正⽂","userId": 1,"deleteFlag": 0,"createTime": "2023-10-21 16:56:57","updateTime": "2023-10-21T08:56:57.000+00:00"},.....]
}

客户端给服务器发送⼀个 /blog/getlist 这样的 HTTP 请求, 服务器给客⼾端返回了⼀个 JSON 格
式的数据.

4.3.2.2 实现服务器代码
1.service包

2.controller包

3.后端测试

失败!!!

与预想结果不符,我想要的code为200.经过检查,set错误,导致其为默认值。

修改之后重新测试

成功!!! 

4.3.2.3 前后端交互->实现客户端代码

4.3.2.3.1 前端测试

成功!!!

4.3.2.3.2 相关部署(时间的返回格式确定)

此时⻚⾯的⽇期显⽰为时间戳, 我们从后端也⽇期进⾏处理
SimpleDateFormat 格式参考官⽅⽂档

我们建立一个utils包,进行相关的部署

重写获取博客创建时间

 重新测试

成功!!!

4.3.3 实现博客详情

⽬前点击博客列表⻚的 "查看全⽂" , 能进⼊博客详情⻚, 但是这个博客详情⻚是写死的内容. 我们期望能够根据当前的 博客 id 从服务器动态获取博客内容.
4.3.3.1 约定前后端交互接⼝

[请求]

/blog/getBlogDetail?blogId=1
[ 响应 ]
{
        "code" : 200,
        "msg" : "" ,
        "data" : {
        "id" : 1,
        "title" : " 第⼀篇博客 " ,
        "content" : "111 我是博客正⽂我是博客正⽂我是博客正⽂ " ,
        "userId" : 1,
        "deleteFlag" : 0,
        "createTime" : "2023-10-21 16:56:57" ,
        "updateTime" : "2023-10-21T08:56:57.000+00:00"
}
}
4.3.3.2 实现服务器代码
1.service包

2.controller包

3.后端测试

成功!!!

 4.3.3.3 前后端交互

首先清除写死的代码

后续将获得的内容赋值到上面

 4.3.3.3.1 前后测试成功!!! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/820862.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Big Data and Cognitive Computing (IF=3.7) 计算机/大数据/人工智能期刊投稿

Special Issue: Artificial Cognitive Systems for Computer Vision 欢迎计算机/大数据/人工智能/计算机视觉相关工作的投稿&#xff01; 影响因子3.7&#xff0c;截止时间2024年12月31日 投稿咨询&#xff1a;lqyan18fudan.edu.cn 投稿网址&#xff1a;https://www.mdpi.com/j…

2024 计算机毕业设计之SpringBoot+Vue项目合集(源码+L文+PPT)

各位朋友大家好&#xff0c;有幸与屏幕前你们相识&#xff0c;博主现已经搬砖9年&#xff0c;趁着头发还充裕&#xff0c;希望给大家提供一些编程领域的帮助&#xff0c;深知计算机毕业生这个阶段的崩溃与闹心&#xff0c;让我们共同交流进步。 博主给大家列举了项目合集&#…

如何在PPT中获得网页般的互动效果

如何在PPT中获得网页般的互动效果 效果可以看视频 PPT中插入网页有互动效果 当然了&#xff0c;获得网页般的互动效果&#xff0c;最简单的方法就是在 PPT 中插入网页呀。 那么如何插入呢&#xff1f; 接下来为你讲解如何获得&#xff08;此方法在 PowerPoint中行得通&#…

吴恩达llama课程笔记:第七课llama安全工具

羊驼Llama是当前最流行的开源大模型&#xff0c;其卓越的性能和广泛的应用领域使其成为业界瞩目的焦点。作为一款由Meta AI发布的开放且高效的大型基础语言模型&#xff0c;Llama拥有7B、13B和70B&#xff08;700亿&#xff09;三种版本&#xff0c;满足不同场景和需求。 吴恩…

【笔记】探索生成范式:大型语言模型在信息提取中的作用

探索生成范式&#xff1a;大型语言模型在信息提取中的作用 摘要介绍 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光&#xff0c;感谢你的陪伴与支持 ~ &#x1f680; 欢迎一起踏上探险之旅&#xff0c;挖掘无限可能&#xff0c;共同成长&am…

基于Qt的二维码生成与识别

基于Qt的二维码生成与识别 一、获取QZxing开源库 1.通过封装的QZxing开源库生成和识别二维码&#xff0c;下载地址&#xff1a;GitCode - 开发者的代码家园https://gitcode.com/mirrors/ftylitak/qzxing/tree/master。 2.下载解压后&#xff0c;使用Qt Creator xx&#xff0…

解决npm run dev跑项目,发现node版本不匹配,怎么跑起来?【已解决】

首先问题点就是我们npm run dev 运行项目的时候发现出错&#xff0c;跑不起来&#xff0c;类型下面这种 这里的出错的原因在于我们的node版本跟项目的版本不匹配 解决办法 我这里的问题是我的版本是node14的&#xff0c;然后项目需要node20的&#xff0c;执行下面的就可以正…

Vue3(二):报错调试,vue3响应式原理、computed和watch,ref,props,接口

一、准备工作调试 跟着张天禹老师看前几集的时候可能会遇到如下问题&#xff1a; 1.下载插件&#xff1a;Vue Language Features (Volar)或者直接下载vue-offical 2.npm run serve时运行时出现错误&#xff1a;Error: vitejs/plugin-vue requires vue (&#xff1e;3.2.13) …

Linux系统(centos,redhat,龙芯,麒麟等)忘记密码,怎么重置密码

Linux系统&#xff08;centos,redhat,龙芯&#xff0c;麒麟等&#xff09;忘记密码&#xff0c;怎么重置密码&#xff0c;怎么设置新的密码 今天在操作服务器时&#xff0c;DBA忘记了人大金仓数据库的kingbase密码&#xff0c;他的密码试了好多遍&#xff0c;都不行。最后只能…

目标检测算法——YOLOV9——算法详解

一、主要贡献 深度网络输入数据在逐层进行特征提取和空间变换时&#xff0c;会丢失大量的信息。针对 信息丢失问题&#xff0c;研究问题如下&#xff1a; 1&#xff09;从可逆功能的角度对现有深度神经网络架构进行了理论分析&#xff0c;解释了许多过去难以解释的现象&#xf…

JavaScript基础:js介绍、变量、数据类型以及类型转换

目录 介绍 引入方式 内部方式 外部形式 注释和结束符 单行注释 多行注释 结束符 输入和输出 输出 输入 变量 声明 赋值 关键字 变量名命名规则 常量 数据类型 数值类型 字符串类型 布尔类型 undefined 类型转换 隐式转换 显式转换 Number ✨介绍 &a…

Module Federation微前端应用拆分后 - request请求优化、私有化request|分发拦截器

1. 背景及目的 1.1 需求背景 随着应用的拆分&#xff0c;目前子应用有12个&#xff0c;这些子应用都使用的是同一个request实例。 前端支持后端切流&#xff0c;增加多个拦截器用于灰度 经手动梳理&#xff1a; 目前所有应用中有26个在使用的拦截器&#xff0c; 其中用于灰…

imgcat 工具

如果经常在远程服务器或嵌入式设备中操作图片&#xff0c;要查看图片效果&#xff0c;就要先把图片dump到本地&#xff0c;比较麻烦。可以使用这个工具&#xff0c;直接在终端上显示。类似于这种效果。 imgcat 是一个终端工具&#xff0c;使用 iTerm2 内置的特性&#xff0c;允…

加强fou循环的坑

今天遇到了一个有趣的事情&#xff0c;使用加强fou循环操作list时&#xff0c;会报错并发操作异常。 直到看了编译类&#xff0c;才发现&#xff0c;加强fou循环其实就是通过迭代器操作&#xff1a; 这里就会出现一个问题&#xff0c;迭代器在取出值时&#xff0c;就回去检测这…

【数据结构】遍历二叉树(递归和非递归遍历的先序、中序和后序遍历、层次遍历法)

目录 【数据结构】遍历二叉树&#xff08;递归和非递归遍历的先序、中序和后序遍历、层次遍历法&#xff09;一、递归算法先&#xff08;根&#xff09;序的遍历算法中&#xff08;根&#xff09;序的遍历算法后&#xff08;根&#xff09;序的遍历算法 二、非递归算法层次遍历…

【漏洞复现】浙大恩特客户资源管理系统 i0004_openFileByStream.jsp 任意文件读取漏洞

0x01 产品简介 浙大恩特客户资源管理系统是一款外贸管理软件&#xff0c;它提供了多种功能&#xff0c;包括客户档案管理、邮件管理、OA外贸办公管理系统、分管权限管理、联系跟进及提醒、业务检查管理、统计分析管理等。 0x02 漏洞概述 浙大恩特客户资源管理系统存在任意文件…

ENSP-旁挂式AC

提醒&#xff1a;如果AC不能成功上线AP&#xff0c;一般问题不会出在AC上&#xff0c;优先关注AC-AP线路上的二层或三层组网的三层交换机 拓扑图 管理VLAN&#xff1a;99 | 业务VLAN&#xff1a;100 注意点&#xff1a; 1.连接AP的接口需要打上pvid为管理vlan的标签 2.AC和…

通用视觉大模型调研

humanbench HumanBench: Towards General Human-centric Perception with Projector Assisted Pretraining&#xff1b;为了解决不同任务之间的conflict以及不同dataset之间的差异(相同任务)&#xff0c;提出PATH&#xff0c;backbone是所有任务共享、projector是任务级别共享…

一个开源的全自动视频生成软件MoneyPrinterTurbo

只需提供一个视频 主题 或 关键词 &#xff0c;就可以全自动生成视频文案、视频素材、视频字幕、视频背景音乐&#xff0c;然后合成一个高清的短视频。 一&#xff1a;功能特性 完整的 MVC架构&#xff0c;代码 结构清晰&#xff0c;易于维护&#xff0c;支持 API 和 Web界面…