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 {@Autowiredprivate UserMapper userMapper;@Testvoid selectById() {System.out.println(userMapper.selectById(2));}@Testvoid 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 {@Autowiredprivate BlogMapper blogMapper;@Testvoid selectAllBlogs() {System.out.println(blogMapper.selectAllBlogs());}@Testvoid insertBlog() {Blog blog = new Blog();blog.setTitle("测试接⼝");blog.setContent("单元测试测试接⼝测试接⼝");blog.setUserId(1);blogMapper.insertBlog(blog);}@Testvoid selectById() {System.out.println(blogMapper.selectById(3));}@Testvoid 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 {@Autowiredprivate BlogService blogService;@RequestMapping("/getList")public List<Blog> getList(){return blogService.getBlogList();}
}
服务层代码 :
@Service
public class BlogService {@Autowiredprivate 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) {//循环拼接数据到documentvar 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:谢谢观看!!!