基于spring的博客系统(二)
4. 业务代码
4.1 持久层
根据需求, 先⼤致计算有哪些DB相关操作, 完成持久层初步代码, 后续再根据业务需求进⾏完善
1. ⽤⼾登录⻚
a. 根据⽤⼾名查询⽤⼾信息
2. 博客列表⻚
a. 根据id查询user信息
b. 获取所有博客列表
3. 博客详情⻚
a. 根据博客ID查询博客信息
b. 根据博客ID删除博客(修改delete_flag=1)
4. 博客修改⻚
a. 根据博客ID修改博客信息
5. 发表博客
a. 插⼊新的博客数据
根据以上分析, 来实现持久层的代码:
package com.example.spring_blog_24_9_8.mapper;
import com.example.spring_blog_24_9_8.model.Blog;
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 {
@Select("Select id,title,content,user_id,delete_flag,create_time,update_time" +
"from blog where delete_flag = 0 order by create_time desc")
List<Blog> selectAllBlogs();
@Insert("insert into blog (title,content,user_id) values (#{title},#{content},#{userId})")
int insertBlog(Blog record);
@Select("select * from blog where id = #{id}")
Blog selectById(Integer id);
int updateBlog(Blog blog);
}
package com.example.spring_blog_24_9_8.mapper;
import com.example.spring_blog_24_9_8.model.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface UserMapper {
@Select("select id, user_name, password, github_url, delete_flag, create_time " +
"from user where id = #{id}")
User selectById(Integer id);
@Select("select id, user_name, password, github_url, delete_flag, create_time " +
"from user where user_name = #{userName}")
User selectByName(String name);
}
<?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.spring_blog_24_9_8.mapper.BlogMapper">
<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>
书写测试⽤例, 简单进⾏单元测试
package com.example.spring_blog_24_9_8.mapper;
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 UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
void selectById() {
System.out.println(userMapper.selectById(2));
}
@Test
void selectByName() {
System.out.println(userMapper.selectByName("shenmengyao"));
}
}
selectbyid结果如下:
selestbyname结果如下:
package com.example.spring_blog_24_9_8.mapper;
import com.example.spring_blog_24_9_8.model.Blog;
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 BlogMapperTest {
@Autowired
private BlogMapper blogMapper;
@Test
void selectAllBlogs() {
System.out.println(blogMapper.selectAllBlogs());
}
@Test
void insertBlog() {
Blog blog = new Blog();
blog.setTitle("测试接⼝");
blog.setContent("单元测试测试接⼝测试接⼝");
blog.setUserId(1);
blogMapper.insertBlog(blog);
}
@Test
void selectById() {
System.out.println(blogMapper.selectById(3));
}
@Test
void updateBlog() {
Blog blog = new Blog();
blog.setId(3);
blog.setDeleteFlag(1);
blog.setTitle("测试修改接⼝");
blog.setContent("测试修改接⼝测试修改接⼝测试修改接⼝");
blogMapper.updateBlog(blog);
}
}
selectallblogs结果如下:
insertblog结果如下:
selectbyid结果如下:
updateblog结果如下:
4.2 实现博客列表
4.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.2.2 实现服务器代码
控制层代码:
@RestController
@RequestMapping("/blog")
public class BlogController {
@Autowired
private BlogService blogService;
@RequestMapping("/getList")
public List<Blog> getList(){
return blogService.getBlogList();
}
}
服务层代码 :
@Service
public class BlogService {
@Autowired
private BlogMapper blogMapper;
public List<Blog> getBlogList(){
return blogMapper.selectAllBlogs();
}
}
运行程序,浏览器访问http://127.0.0.1:8087/blog/getList,结果如下:
4.2.3 实现客⼾端代码
修改 blog_list.html, 删除之前写死的博客内容, 并新增 js 代码处理 ajax 请求;
使⽤ ajax 给服务器发送 HTTP 请求.;
服务器返回的响应是⼀个 JSON 格式的数据, 根据这个响应数据使⽤ DOM API 构造⻚⾯内容.
响应中的 postTime 字段为 ms 级时间戳, 需要转成格式化⽇期.
跳转到博客详情⻚的 url 形如 blog_detail.html?blogId=1 这样就可以让博客详情⻚知道 当前是要访问哪篇博客.
前端代码修改如下:
function getBlogList() {
$.ajax({
type: "get",
url: "/blog/getList",
success: function (result) {
//逻辑不全
//可以再完善, 比如code==200, 但是data为空的, 页面可以提示: 当前还没有任何博客, 快去写博客吧...
if (result.code == 200 && result.data != null && result.data.length > 0) {
//循环拼接数据到document
var finalHtml = "";
//页面展示
for (var blog of result.data) {
finalHtml += '<div class="blog">';
finalHtml += '<div class="title">' + blog.title + '</div>';
finalHtml += '<div class="date">' + blog.createTime + '</div>';
finalHtml += '<div class="desc">' + blog.content + '</div>';
finalHtml += '<a class="detail" href="blog_detail.html?blogId=' + blog.id + '">查看全文>></a>';
finalHtml += '</div>';
}
$(".right").html(finalHtml);
}
},
error: function (error) {
console.log("后端返回失败");
}
});
}
如上图所示,我们当前博客列表页显示的时间为时间戳,我们从后端也⽇期进⾏处理;SimpleDateFormat,格式参考官⽅⽂档:
/**
* 日期工具类
*/
public class DateUtils {
public static String format(Date date){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
return simpleDateFormat.format(date);
}
}
重写获取博客创建时间:
@Data
public class Blog {
private Integer id;
private String title;
private String content;
private Integer userId;
private Integer deleteFlag;
private Date createTime;
private Date updateTime;
public String getCreateTime(){
return DateUtils.format(createTime);
}
}
重新访问博客列表页,查看页面结果:
4.3 实现博客详情
⽬前点击博客列表⻚的 "查看全⽂" , 能进⼊博客详情⻚, 但是这个博客详情⻚是写死的内容. 我们期望 能够根据当前的 博客 id 从服务器动态获取博客内容
4.3.1 约定前后端交互接⼝
[请求]
/blog/getBlogDetail?blogId=1
[响应]
{
"code": 200,
"msg": "",
"data": {
"id": 1,
"title": "第⼀篇博客",
"content": "我是神喵我是神喵我是神喵",
"userId": 1,
"deleteFlag": 0,
"createTime": "2023-10-21 16:56:57",
"updateTime": "2023-10-21T08:56:57.000+00:00"
}
}
4.3.2 实现服务器代码
在BlogController中添加getBlogDeatail ⽅法
@RequestMapping("/getBlogDetail")
public Blog getBlogDetail(Integer blogId){
return blogService.getBlogDetail(blogId);
}
在BlogService 中添加getBlogDeatil⽅法
public Blog getBlogDetail(Integer blogId){
return blogMapper.selectById(blogId);
}
访问http://127.0.0.1:8087/blog/getBlogDetail?blogId=1,结果如下:
4.3.3 实现客户端代码
修改 blog_content.html :
根据当前⻚⾯ URL 中的 blogId 参数(使⽤ location.search 即可得到形如 ?blogId=1 的数据), 给服务器发送 GET /blog 请求.
根据获取到的响应数据, 显⽰在⻚⾯上
1. 修改html⻚⾯, 去掉原来写死的博客标题, ⽇期和正⽂部分 ,代码如下:
<div class="content">
<div class="title"></div>
<div class="date"></div>
<div class="detail"></div>
<div class="operating">
<button onclick="window.location.href='blog_update.html'">编辑</button>
<button>删除</button>
</div>
</div>
2. 完善 js 代码, 从服务器获取博客详情数据.
$.ajax({
type: "get",
url: "/blog/getBlogDetail" + location.search,
success: function (result){
console.log(result);
if(result.code == 200 && result.data != null){
$(".title").text(result.data.title);
$(".date").text(result.data.createTime);
$(".detail").text(result.data.detail);
}
}
})
前进入到博客列表页,点击其中的查看全文进入到文章全文页面:
点击编辑进入到文章更新页面:
ps:谢谢观看!!!