当前位置: 首页 > article >正文

基于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 + '">查看全文&gt;&gt;</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:谢谢观看!!!


http://www.kler.cn/a/302745.html

相关文章:

  • Redis - 集群(Cluster)
  • MySQL重难点(一)索引
  • C++ 数组与结构 编程练习
  • Android Framework AMS(16)进程管理
  • const限定符-C语言中指针的“可变与不可变”法则
  • 去地面算法——depth_clustering算法调试(1)
  • Go Playground 在线编程环境
  • 优购电商小程序的设计与实现+ssm(lw+演示+源码+运行)
  • MySql8.x---开窗函数
  • HTTP 协议介绍
  • JS手写实现深拷贝
  • mysql性能优化-云服务与数据库即服务(DBaaS)优化
  • [论文笔记] LLM大模型剪枝篇——2、剪枝总体方案
  • 【JAVA入门】Day34 - Stream流
  • facebook广告和谷歌广告如何选择效果最大化?
  • eclipse配置maven
  • 第T11周:优化器对比实验
  • 【TCP】相关机制:异常处理
  • 泰州高新区法院多层面强化固定资产管理
  • 【数据结构篇】~排序(1)之插入排序
  • 众店绿色积分模式:引领消费新风尚,共筑商业新生态
  • 数据结构算法和算法分析
  • 数据结构第二周做题总结_顺序表
  • [000-01-008].第05节:OpenFeign高级特性-日志打印功能
  • C语言宏参数的使用
  • 【排序算法】之基数排序