博客系统(升级(Spring))(四)(完)基本功能(阅读,修改,添加,删除文章)

news2025/1/11 0:32:27

博客系统 (三)

  • 博客系统
  • 博客主页
    • 前端
    • 后端
    • 个人博客
      • 前端
      • 后端
        • 显示个人文章
        • 删除文章
    • 修改文章
      • 前端
      • 后端
        • 提取文章
        • 修改文章
      • 显示正文内容
        • 前端
        • 后端
        • 文章阅读量功能

博客系统

博客系统是干什么的?
CSDN就是一个典型的博客系统。而我在这里就是通过模拟实现一个博客系统,这是一个较为简单的博客系统,但是主要功能一个不缺,不过就是 UI 有些 low,我学习前端是为了写后端更加顺手。不至于前后端完全分离,但是有个问题设计的 web 页面不是很好看。

首先我将整体的业务流程展现
在这里插入图片描述
我们继博客系统(二)继续,编写,到了主页的业务逻辑了

接下来的流程是通过,网页端,后端统一数据结构交互的数据结构。

博客主页

前端

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>博客列表</title>
    <link rel="stylesheet" href="css/list.css">
    <link rel="stylesheet" href="css/blog_list.css">
    <link rel="stylesheet" href="css/conmmon.css"></lin>
    <script src="js/jquery.min.js"></script>
    <style>
        .nav{
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            height: 50px;
        }
        .container{
            padding-top: 80px;
            height: auto;
        }
        .container-right{
            width: auto;
        }
        .blog-pagnation-wrapper{
            height: 40px;
            margin: 16px 0;
            text-align: center;
        }
        .blog-pagnation-item{
            display: inline-block;
            padding: 8px;
            border: 1px solid #d0d0d5;
            color: #333;
        }
        .blog-pagnation-item:hover{
            background: #4e4eeb;
            color: #fff;
        }
        .blog-pagnation-item.actvie{
            background: #4e4eeb;
            color: #fff;
        }

    </style>
    <script src="js/urluitils.js"></script>
</head>

<body>

    <!-- 导航栏 -->
    <div class="nav">
        <img src="img/sleep.jpg" alt="">
        <span class="title">我的博客系统</span>
        <!-- 用来占据中间位置 -->
        <span class="spacer"></span>
        <a href="blog_list.html">主页</a>
        <a href="blog_add.html">写博客</a>
        <a href="myblog_list.html">我的博客</a>
        <a href="javascript:logout()">注销</a>
    </div>
    <!-- 版心 -->
    <div class="container">
        <!-- 右侧内容详情 -->
        <div class="container-right" style="width: 100%;">
            <div id="artListDiv">
                <!-- 每一篇博客包含标题, 摘要, 时间 -->
            </div>
            <div class="blog-pagnation-wrapper">
                <button class="blog-pagnation-item" onclick="doFirst()">首页</button> 
                <button class="blog-pagnation-item" onclick="doBefore()">上一页</button>  
                <button class="blog-pagnation-item" onclick="doNext()">下一页</button>
                <button class="blog-pagnation-item" onclick="doLast()">末页</button>
                &nbsp; &nbsp; &nbsp; &nbsp;
                当前在第<span id="pindex"></span>页
                共:<span id="psize"></span></div>
        </div>
    </div>
    <script>
        var psize=2;
        var pindex=1;
        var totalpage=1;//总页
        //初始化数据
        function init(){
            //得到url中的分页参数
            psize=getParamValue("psize");
            if(psize==null){
                psize=2;
            }
            pindex=getParamValue("pindex");
            if(pindex==null){
                pindex=1;
            }
            jQuery("#pindex").html(pindex);
            //请求后端接口
            jQuery.ajax({
                url:"/article/getlistbypage",
                type:"get",
                data:{
                    "pindex":pindex,
                    "psize":psize
                },
                success:function(res){
                    if(res.code==200&&res.data!=null){
                        var createHtml="";
                        if(res.data.list!=null&&res.data.list.length>0){
                            //文章
                            totalpage =res.data.list.szie;
                            jQuery("#psize").html(totalpage);
                            var artList=res.data.list;
                            for(var i=0;i<artList.length;i++){
                                var art=artList[i];
                                createHtml+='<div class="blog">';
                                createHtml+='<div class="title">'+art.title+'</div>';
                                createHtml+='<div class="date">'+art.createtime+'</div>';
                                createHtml+='<div class="desc">'+art.content+'</div>';
                                createHtml+=' <a href="blog_content.html?aid='+art.id+'" class="detail">查看全文 &gt;&gt;</a>';
                                createHtml+='</div>';
                            }
                        }else{
                            createHtml+='<h3 style="margin-top:20px;margin-left:20px">暂无文章!</h3>';

                        }
                        jQuery("#artListDiv").html(createHtml);
                    }else{
                        alert("抱歉:查询失败"+res.msg);
                    }
                }
            });
        }
        init();
        function doFirst(){
            //判断是否在首页
            if(pindex<=1){
                alert("已经在首页了,不需跳转");

                return false;
            }
            location.href="blog_list.html";

        }

        function doLast(){
            if(pindex>=totalpage){
                alert("已经在末页了,不需跳转");
                return false;
            }
            location.href="blog_list.html?pindex="+(parseInt(totalpage));
        }
        function doBefore(){
            if(pindex<=1){
                alert("已经在首页了,不需跳转");
                return false;
            }
            location.href="blog_list.html?pindex="+(parseInt(pindex-1));
        }
        function doNext(){
            if(pindex>=totalpage){
                alert("已经在末页了,不需跳转");
                return false;
            }
            location.href="blog_list.html?pindex="+(parseInt(pindex+1));
        }
    </script>
</body>
</html>

后端

首先在主页中需要注意的是,我在这里添加了分页功能,如何解决分页问题,诺是将整个数据库里的文章全部读取到内存里,对于内存的消耗极大,所以这里我用sql语言中的 limt 语言进行分页读取(不知道的可以看我Mysql的文章)

通过mapper接口调用数据库

@Mapper
public interface ArticleMapper {
    @Select("select * from articleinfo order by id desc limit #{psize} offset #{offset}")
    List<Articleinfo> getListByPage(@Param("pszie") int pszie,@Param("offset") int offset);
}

通过service层调用mapper接口

@Service
public class ArticleService {
    @Autowired
    private ArticleMapper articleMapper;

    public List<Articleinfo> getListByPage (int psize,int offset){
        return articleMapper.getListByPage(psize, offset);
    } 
}

通过Controller层调用service层方法

@RestController
@RequestMapping("/article")
public class ArticleController {
    @Autowired
    private ArticleService articleService;

    @Resource
    private ThreadPoolTaskExecutor taskExecutor;
    
    public ResultAjax getListByPage(Integer pindex,Integer psize) throws ExecutionException, InterruptedException {
        if (pindex==null||pindex<1){
            pindex=1;
        }
        if (psize==null||psize<1){
            psize=1;
        }
        Integer finalPsize=psize;
        int offset=psize*(pindex-1);
        FutureTask<List<Articleinfo>> listFutureTask=new FutureTask<>(()->{
            return articleService.getListByPage(finalPsize,offset);
        });
        taskExecutor.submit(listFutureTask);
        FutureTask<Integer> sizeTask=new FutureTask<>(()->{
           int count= articleService.getCount(); 
           double sizeTemp=((count*1.0)/(finalPsize*1.0));
           return (int)Math.ceil(sizeTemp);
        });
        taskExecutor.submit(sizeTask);
        
        List<Articleinfo> articleinfos=listFutureTask.get();
        int size=sizeTask.get();
        HashMap<String ,Object> map=new HashMap<>();
        map.put("list",articleinfos);
        map.put("szie",size);
        
        return ResultAjax.success(map);
    }
}

解释:

  1. 我在页面中每页所展示两个文章。而 limit finalPsize offset offset 我定位为 finalPsize 为第 几 行,offset 显示几个数据(具体原则在我的myslq 文章中有体现)(LIMIT [位置偏移量,] 行数)
  2. 使用多线程可以避开,有读者写数据,有读者读数据的情况。并且可以以最快速度反应的客户端
  3. 这个线程池Spring提供的,线程池,可以不需要去设置参数。
  4. 第一个线程池用来查找页面每页的内容,第二个线程池用来查找文章的总数。

个人博客

前端

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>博客列表</title>
    <link rel="stylesheet" href="css/conmmon.css">
    <link rel="stylesheet" href="css/blog_list.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/logout.js"></script>
</head>

<body>

    <!-- 导航栏 -->
    <div class="nav">
        <img src="img/sleep.jpg" alt="">
        <span class="title">我的博客系统</span>
        <!-- 用来占据中间位置 -->
        <span class="spacer"></span>
        <a href="blog_list.html">主页</a>
        <a href="blog_add.html">写博客</a>
        <a href="myblog_list.html">我的博客</a>
        <a href="javascript:logout()">注销</a>
    </div>
     <!-- 版心 -->
     <div class="container">
        <!-- 左侧个人信息 -->
        <div class="container-left">
            <div class="card">
                <img src="img/sleep.jpg" class="avtar" alt="">
                <h3 id="username"></h3>
                <a href="http:www.github.com">github 地址</a>
                <div class="counter">
                    <span>文章</span>
                </div>
                <div class="counter">
                    <span id="artcount"></span>
                </div>
            </div>
        </div>
        <!-- 右侧内容详情 -->
        <div id="artListDiv" class="container-right" >
        </div>
    </div>

    <script>
        function init(){
            jQuery.ajax({
                url:"/article/mylist",
                type:"get",
                data:{},
                success:function(res){
                    if(res.code==200){
                        var creatHtml="";
                        var arrList=res.data.artList;
                        if(res.code==200&&res.data!=null){
                            var user=res.data.user;
                            var size=res.data.size;
                            var art=res.data.artList;
                            if(user!=null){
                                if(user.photo!=""){
                                    jQuery("#photo").att("src",user.photo);
                                }
                                jQuery("#username").html(user.username);
                                jQuery("#artcount").html(size);

                            }else{
                                alert("抱歉查询失败"+res.msg);
                                }
                        }
                        if(arrList!=null&&arrList.length>0){                    
                            for( var i=0;i<arrList.length;i++){
                                var art =arrList[i];
                                creatHtml+='<div class="blog">';
                                creatHtml+='<div class="title">'+art.title+'</div>';
                                creatHtml+='<div class="date">'+art.createtime+'</div>';
                                creatHtml+='<div class="desc">'+ art.content+' </div>';
                                creatHtml+='  <a href="blog_content.html?aid='+art.id+'" class="detail">查看全文 &gt;&gt;</a>&nbsp;&nbsp;';
                                creatHtml+='<a href="blog_edit.html?aid='+art.id+'" class="detail">修改 &gt;&gt;</a>&nbsp;&nbsp;';
                                creatHtml+='<a οnclick="del('+art.id+')" class="detail">删除 &gt;&gt;</a>';
                                creatHtml+=' </div>';
                            }
                        }else{
                            creatHtml+='<h3 style="margin-top:20px;margin-left:20px">暂无文章,请先添加<a href="blog_add.html">添加</a> </h3>';
                        }
                        jQuery("#artListDiv").html(creatHtml);
                    }else{
                        alert("抱歉,操作失败"+res.msg);
                    }
                }
            });
        }
        init();
        function del(aid){
            //1.参数校验
            if(aid=""||aid<=0){
                alert("参数错误!");
                return false;
            }
            jQuery.ajax({
                url:"/art/del",
                type:"post",
                data:{
                    "aid":aid
                },
                success:function(res){
                    if(res.code==200&& res.data==1){
                        alert("恭喜:删除成功");
                        location.href=location.href;
                    }else{
                        alert("删除失败"+res.msg);
                    }
                }
            });
        }
    </script>
</body>

</html>

后端

显示个人文章

调用mapper层控制数据库

@Mapper
public interface ArticleMapper {

    @Select("select * from articleinfo where uid=#{uid}")
    List<Articleinfo> getUidByArticle(@Param("uid") int uid);
}

调用service层调用mapper接口

@Service
public class ArticleService {
    @Autowired
    private ArticleMapper articleMapper;

    
    public List<Articleinfo> getUidByArticle(int uid){
        return articleMapper.getUidByArticle(uid);
    }
}

调用Controller 层调用service层

@RestController
@RequestMapping("/article")
public class ArticleController {
    @Autowired
    private ArticleService articleService;

    @Resource
    private ThreadPoolTaskExecutor taskExecutor;

    @Resource
    private UserinfoVO userinfoVO;
 	 
	@RequestMapping("/mylist")
    public ResultAjax getUidByArticle(HttpServletRequest request){
        Userinfo userinfo= SessionUtis.getUser(request);
        if (userinfo==null){
            return ResultAjax.fail(-1,"请先登录");
        }
        List<Articleinfo> list =articleService.getUidByArticle(userinfo.getUid());
        int size=articleService.getArtCountById(userinfo.getUid());

        if (list!=null&&list.size()>0){
            list.stream().forEach(articleinfo -> {
                if (articleinfo.getContent().length()>120){
                    articleinfo.setContent(articleinfo.getContent().substring(0,120));
                }
            });
        }
        HashMap<String ,Object> map=new HashMap<>();
        map.put("artList",list);
        map.put("user",userinfo);
        map.put("size",size);
        return ResultAjax.success(map);
    }
}

删除文章

调用mapper层控制数据库

@Mapper
public interface ArticleMapper {
    @Delete("delete from articleinfo where aid=#{aid} and uid=#{uid}")
    int delArt(@Param("aid")int aid,@Param("uid") int uid);
}

调用service层调用mapper接口

@Service
public class ArticleService {
    @Autowired
    private ArticleMapper articleMapper;

    
}

Controller层调用service
这个代码太多了我只展示主要代码

@RestController
@RequestMapping("/article")
public class ArticleController {
    @Autowired
    private ArticleService articleService;

    @Resource
    private ThreadPoolTaskExecutor taskExecutor;
	@RequestMapping("/del")
    public ResultAjax delArt(Integer aid,HttpServletRequest request){
        if (aid==null||aid<=0){
            return ResultAjax.fail(-1,"请先登录");
        }
        Userinfo userinfo=SessionUtis.getUser(request);
        int result= articleService.delArt(aid,userinfo.getUid());
        return ResultAjax.success(result);
    }
 }

修改文章

前端

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>博客编辑</title>

    <!-- 引入自己写的样式 -->
    <link rel="stylesheet" href="css/conmmon.css">
    <link rel="stylesheet" href="css/blog_edit.css">

    <!-- 引入 editor.md 的依赖 -->
    <link rel="stylesheet" href="editor.md/css/editormd.min.css" />
    <script src="js/jquery.min.js"></script>
    <script src="js/urluitils.js"></script>
    <script src="editor.md/editormd.js"></script>
</head>

<body>

    <!-- 导航栏 -->
    <div class="nav">
        <img src="img/sleep.jpg" alt="">
        <span class="title">我的博客系统</span>
        <!-- 用来占据中间位置 -->
        <span class="spacer"></span>
        <a href="blog_list.html">主页</a>
        <a href="javascript:logout()">注销</a>
    </div>
    <!-- 编辑框容器 -->
    <div class="blog-edit-container">
        <!-- 标题编辑区 -->
        <div class="title">
            <input type="text" placeholder="在这里写下文章标题" id="title">
            <button onclick="doUpdate()">修改文章</button>
        </div>
        <!-- 创建编辑器标签 -->
        <div id="editorDiv">
            <textarea id="editor-markdown" style="display:none;"></textarea>
        </div>
    </div>

    <script>
        var editor;
        var aid=getParamValue("aid");
        function initEdit(md){
            // 编辑器设置
            editor = editormd("editorDiv", {
                // 这里的尺寸必须在这里设置. 设置样式会被 editormd 自动覆盖掉. 
                width: "100%",
                // 高度 100% 意思是和父元素一样高. 要在父元素的基础上去掉标题编辑区的高度
                height: "calc(100% - 50px)",
                // 编辑器中的初始内容
                markdown: md,
                // 指定 editor.md 依赖的插件路径
                path: "editor.md/lib/",
                saveHTMLToTextarea: true // 
            });
        }
        initEdit("# 在这里写下一篇博客"); // 初始化编译器的值
        // 提交
        function doUpdate(){
            var title=jQuery("#title");
           if(title.val()==""){
                 alert("输入标题");
                 title.focus();
                 return false;
           }
           if(editor.getValue()==""){
             alert("请先输入正文");
             return false;
           }
           jQuery.ajax({
                url:"/article/update",
                type:"post",
                data:{
                    "aid":aid,
                    "title":title.val(),
                    "content":editor.getValue()
                },
                success:function(res){
                    if(res.code==200&&res.data==1){
                        alert("恭喜,修改成功");
                        location.href="myblog_list.html";
                    }else if(res.code==-2){
                        alert("未登录")
                        location.href="login.html";
                    }else{
                        alert("抱歉,修改失败!"+res.msg);
                    }
                }
           });

        }
        //初始化页面
        function init(){
           //校验aid
           if(aid==null||aid<0){
            alert("非法参数");
            return false;
           }
           //查询文章详情
           jQuery.ajax({
                url:"/article/update_init",
                type:"get",
                data:{
                    "aid":aid
                },
                success: function(res){
                    if(res.code==200&&res.data!=null&&res.data.id>0){
                        jQuery("#title").val(res.data.title);
                        initEdit(res.data.content);
                    }else if(res.code==-2){
                        alert("未登录")
                        location.href="login.html";
                    }else{
                        alert("抱歉查询失败"+res.msg);
                    }
                }

           });
           //将文章内容展示到页面
            
        }
        init();
    </script>
</body>

</html>

后端

提取文章

调用mapper层控制数据库

@Mapper
public interface ArticleMapper {
    @Select("select * from articleinfo where aid=#{aid} and uid=#{uid}")
    Articleinfo getArtByaidAnduid(@Param("aid")int aid,@Param("uid") int uid);
}

调用service层调用mapper接口

@Service
public class ArticleService {
    @Autowired
    private ArticleMapper articleMapper;

    public Articleinfo getArtByaidAnduid(int aid,int uid){
        return articleMapper.getArtByaidAnduid(aid,uid);
    }
}

Controller层调用service

@RestController
@RequestMapping("/article")
public class ArticleController {
    @Autowired
    private ArticleService articleService;

    @Resource
    private ThreadPoolTaskExecutor taskExecutor;

    @Resource
    private UserinfoVO userinfoVO;
 	@RequestMapping("/update_init")
    public ResultAjax updataInti(Integer aid,HttpServletRequest request){
        if (aid<=0||aid==null){
            return ResultAjax.fail(-1,"参数有误");

        }
        Userinfo userinfo=SessionUtis.getUser(request);
        if (userinfo==null){
            return ResultAjax.fail(-2,"请先登录");

        }
        Articleinfo articleinfo=articleService.getArtByaidAnduid(aid,userinfo.getUid());
        return ResultAjax.success(articleinfo);
    }
    }

修改文章

调用mapper层控制数据库

@Mapper
public interface ArticleMapper {

    @Update("Update articleinfo set title=#{title},content=#{content} where aid=#{aid} and uid=#{uid}")
    int setArt(Articleinfo articleinfo);
}

调用service层调用mapper接口

@Service
public class ArticleService {
    @Autowired
    private ArticleMapper articleMapper;

    public int setArt(Articleinfo articleinfo){
        return articleMapper.setArt(articleinfo);
    }
}

Controller层调用service

@RestController
@RequestMapping("/article")
public class ArticleController {
    @Autowired
    private ArticleService articleService;

    @Resource
    private ThreadPoolTaskExecutor taskExecutor;

    @Resource
    private UserinfoVO userinfoVO;
    @RequestMapping("/update")
    public ResultAjax setArt(Articleinfo articleinfo,HttpServletRequest request){
        if (articleinfo==null||
                !StringUtils.hasLength(articleinfo.getContent())||
                !StringUtils.hasLength(articleinfo.getTitle())){
            return ResultAjax.fail(-1,"参数非法");
        }
        Userinfo userinfo=SessionUtis.getUser(request);
        if (userinfo==null){
            return ResultAjax.fail(-2,"请先登录");
        }
        articleinfo.setUid(userinfo.getUid());
        int result=articleService.setArt(articleinfo);
        return ResultAjax.success(result);
    }
}

显示正文内容

前端

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>博客正文</title>
    <link rel="stylesheet" href="css/conmmon.css">
    <link rel="stylesheet" href="css/blog_content.css">
    <link rel="stylesheet" href="editor.md/css/editormd.preview.min.css" />
    <script src="js/jquery.min.js"></script>
    <script src="editor.md/editormd.js"></script>
    <script src="editor.md/lib/marked.min.js"></script>
    <script src="editor.md/lib/prettify.min.js"></script>
    <script src="js/urluitils.js"></script>
</head>

<body>

    <!-- 导航栏 -->
    <div class="nav">
        <img src="img/sleep.jpg" alt="">
        <span class="title">我的博客系统</span>
        <!-- 用来占据中间位置 -->
        <span class="spacer"></span>
        <a href="blog_list.html">主页</a>
        <a href="blog_edit.html">写博客</a>
        <a href="myblog_list.html">我的博客</a>
        <a href="login.html">登陆</a>
        <a href="javascript:logout()">注销</a>
    </div>
    <!-- 版心 -->
    <div class="container">
        <!-- 左侧个人信息 -->
        <div class="container-left">
            <div class="card">
                <img src="img/sleep.jpg" class="avtar" id="photo">
                <h3 id="username"></h3>
                <a href="http:www.github.com">github 地址</a>
                <div class="counter">
                    <span>文章</span>
                </div>
                <div class="counter">
                    <span id="artcount"></span>
                </div>
            </div>
        </div>
        <!-- 右侧内容详情 -->
        <div class="container-right">
            <div class="blog-content">
                <!-- 博客标题 -->
                <h3 id="title"></h3>
                <!-- 博客时间 -->
                <div class="date" >
                   发布时间: <span id="createtime"></span>
                        |               
                   阅读量: <span id="rcount"></span>
                </div>
                <!-- 博客正文 -->
                <div id="editorDiv">

                </div>
            </div>
        </div>
    </div>
    <script type="text/javascript">
            var aid=getParamValue("aid");
            var editormd;
            function initEdit(md){
                editormd = editormd.markdownToHTML("editorDiv", {
                markdown : md, 
                });
            }
            //初始化页面
            function init(){
          
                if(aid==null||aid<=0){
                    alert("参数有误");
                    return false;
                }
                jQuery.ajax({
                    url:"/article/detail",
                    type:"get",
                    data:{
                        "aid":aid
                    },
                    success:function(res){
                        if(res.code==200&&res.data!=null){
                            var user=res.data.user;
                            var art=res.data.art;
                            if(user!=null){
                                if(user.photo!=""){
                                    jQuery("#photo").att("src",user.photo);
                                }
                                jQuery("#username").html(user.username);
                                jQuery("#artcount").html(user.artCoout);

                            }else{
                                alert("抱歉查询失败"+res.msg);
                            }
                            if(art!=null){
                                jQuery("#title").html(art.title);
                                jQuery("#createtime").html(art.createtime);
                                jQuery("#rcount").html(art.rcount);
                                initEdit(art.content);
                            }else{
                                alert("抱歉查询失败"+res.msg);
                            }
                        }else{
                            alert("抱歉查询失败"+res.msg);
                        }
                    }
                });
            }
            init();

            function incrementRCount(){
                if (aid==null||aid<=0) {
                        return false;
                 }
                jQuery.ajax({
                    
                    url:"/article/increment_rcount",
                    type:"post",
                    data:{
                        "aid":aid
                    },
                    success:function(res){

                    }
                })
            }
            incrementRCount();
    </script> 
</body>

</html>

后端

调用mapper层控制数据库
UserMapper

@Mapper
public interface UserMapper {

    @Select("select * from userinfo where uid=#{uid}")
    UserinfoVO getUserById(@Param("uid")int uid);
}

ArticleMapper

@Mapper
public interface ArticleMapper {

    @Update("Update articleinfo set title=#{title},content=#{content} where aid=#{aid} and uid=#{uid}")
    int setArt(Articleinfo articleinfo);

    @Select("select * from articleinfo where aid=#{aid}")
    Articleinfo readDetail(@Param("aid")int aid);

}

调用service层调用mapper接口
UserServie

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public UserinfoVO getUserByUid(int uid){
        return userMapper.getUserById(uid);
    }
}

ArticleService

@Service
public class ArticleService {
    @Autowired
    private ArticleMapper articleMapper;

    public Articleinfo readDetail(int aid){
        return articleMapper.readDetail(aid);
    }
}

Controller层调用service

ArticleController

@RestController
@RequestMapping("/article")
public class ArticleController {
    @Autowired
    private ArticleService articleService;

    @Resource
    private ThreadPoolTaskExecutor taskExecutor;

    @Resource
    private UserService userService;
    @Resource
    private UserinfoVO userinfoVO;
	@RequestMapping("/detail")
    public ResultAjax readDetail(Integer aid) throws ExecutionException, InterruptedException {
        if (aid<=0||aid==null){
            return ResultAjax.fail(-1,"非法参数");
        }
        Articleinfo articleinfo=articleService.readDetail(aid);
        if (articleinfo==null){
            return ResultAjax.fail(-1,"非法参数");
        }
        FutureTask<UserinfoVO> userTask=new FutureTask<>(()->{
            return  userService.getUserByUid(articleinfo.getUid());
        });
        taskExecutor.submit(userTask);

        FutureTask<Integer> artCountTask=new FutureTask<>(()->{
            return articleService.getArtCountById(articleinfo.getUid());
        });
        taskExecutor.submit(artCountTask);
        UserinfoVO userinfoVO=userTask.get();
        int artCount=artCountTask.get();
        userinfoVO.setArtCount(artCount);
        HashMap<String,Object> map=new HashMap<>();
        map.put("user",userinfoVO);
        map.put("art",articleinfo);
        return ResultAjax.success(map);
    }
}

文章阅读量功能

调用mapper层控制数据库

@Mapper
public interface ArticleMapper {

    @Update("upate articleinfo set readcount=readcount+1 where aid=#{aid}")
    int readArtCount(@Param("aid")int aid);

}

调用service层调用mapper接口

@Service
public class ArticleService {
    @Autowired
    private ArticleMapper articleMapper;

    public int readArtCount(int aid){
        return articleMapper.readArtCount(aid);
    }
}

Controller层调用service

@RestController
@RequestMapping("/article")
public class ArticleController {
    @Autowired
    private ArticleService articleService;

    @Resource
    private ThreadPoolTaskExecutor taskExecutor;

    @Resource
    private UserService userService;
    @Resource
    private UserinfoVO userinfoVO;
 	 @RequestMapping("/increment_rcount")
    public ResultAjax readArtCount(Integer aid){
        if (aid==null||aid<=0){
            return ResultAjax.fail(-1,"参数有误");
        }
        int result = articleService.readArtCount(aid);

        return ResultAjax.success(result);
    }
}

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

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

相关文章

ARM接口编程—WDT(exynos 4412平台)

WDT简介 Watch Dog Timer即看门狗定时器&#xff0c;其主要作用是当发生软件故障时可产生复位信号使SOC复位&#xff0c;其本质是一个计数器 WDT工作原理 WTD寄存器 wtd控制寄存器 用于设置一级分频、二级分频、使能、产生复位和中断信号 WTD数据寄存器 用于获取计数值&…

如何在Windows系统搭建filebrowser私人网盘并实现在外网访问本地内网

Windows系统搭建网盘神器filebrowser结合内网穿透实现公网访问 文章目录 Windows系统搭建网盘神器filebrowser结合内网穿透实现公网访问前言1.下载安装File Browser2.启动访问File Browser3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3…

JBoss JMXInvokerServlet 反序列化漏洞复现(CVE-2015-7501)

一、漏洞说明 JBoss中/invoker/JMXInvokerServlet路径对外开放&#xff0c;JBoss的jmx组件支持反序列化。JBoss在/invoker/JMXInvokerServlet请求中读取了用户传入的对象&#xff0c;然后我们利用Apache Commons Collections中的Gadget执行任意代码。 二、影响版本 JBoss Enter…

虹科分享 | 知识产权盗窃:它是什么以及如何预防

知识产权 (IP) 涵盖各种形式的创造力和创新&#xff0c;例如艺术品、配方、徽标、文献、食谱、工业设计等。个人和企业都可以拥有知识产权&#xff0c;赋予他们对其想法和创作的合法权利。这些权利帮助知识产权所有者从他们的作品中获益、保护作品并防止复制。知识产权对于推动…

【Redis】Redis 的学习教程(九)之 发布 Pub、订阅 Sub

1. Pub/Sub 介绍 Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式是一种消息传递机制&#xff0c;它允许在发送者和接收者之间建立松耦合的通信关系。在这种模式中&#xff0c;发送者&#xff08;发布者&#xff09;将消息发布到一个指定的频道或模式&#xff0c;而接收…

用户体验设计师是什么,一篇文章读懂!

我是设计师l1m0&#xff0c;今天要给大家分享一个有趣的职业&#xff1a;UX设计师。 在我们日常生活中&#xff0c;我们无时无刻都在与产品发生交互行为&#xff0c;例如使用应用APP、访问网站、与实体陈燕萍进行交互&#xff08;例如试穿衣服&#xff09;或者享受某个服务&am…

恒运资本:多股涨停!“吃药”行情卷土重来;政策利好,元宇宙又可以了!

今日早盘&#xff0c;A股小幅震荡反弹&#xff0c;科创50指数继续围绕900点打开争夺。 盘面上&#xff0c;医药&#xff0c;轿车、元世界、煤炭等板块涨幅居前&#xff0c;航空、家居用品、卫星导航、房地产等板块跌幅居前。北上资金净流出4.4亿元。 医药股全线走强 医药股早…

12个小朋友手拉手站成一个圆圈 约瑟夫环 + 字节历险记

目录 12个小朋友手拉手站成一个圆圈&#xff0c;从某一个小朋友开始报数&#xff0c;报到7的那个小朋友退到圈外&#xff0c;然后他的下一位重新报“1”。这样继续下去&#xff0c;直到最后只剩下一个小朋友求解这个小朋友原来站在什么位置上呢? 请问在互联网公司中,OKR是什…

C语言访问Mysql

文章目录 C语言访问Mysql1. 环境设置2. mysql接口介绍(1) 初始化mysql_init()(2) 链接数据库mysql_real_connect(3) 下发mysql命令mysql_query()(4) 获取执行结果mysql_store_result(5) 释放结果集mysql_free_result()(6) 获取结果行数mysql_num_rows(7) 获取结果列数mysql_num…

Java——》synchronized互斥性

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…

Solidity 小白教程:13. 继承

Solidity 小白教程&#xff1a;13. 继承 这一讲&#xff0c;我们介绍solidity中的继承&#xff08;inheritance&#xff09;&#xff0c;包括简单继承&#xff0c;多重继承&#xff0c;以及修饰器&#xff08;modifier&#xff09;和构造函数&#xff08;constructor&#xff…

新手必看!Python爬虫 教程:IP池的使用

前言 嗨喽~大家好呀&#xff0c;这里是小曼呐 ❤ ~! 一、简介 爬虫中为什么需要使用代理 一些网站会有相应的反爬虫措施&#xff0c;例如很多网站会检测某一段时间某个IP的访问次数&#xff0c;如果访问频率太快以至于看起来不像正常访客&#xff0c;它可能就会禁止这个IP的访…

CE单相智能电力仪表ADL200

安科瑞 华楠 ADL200 单相电子式电能表主要用于计量低压网络的单相有功电能&#xff0c;同时可测量电压、电流、功率等电量&#xff0c; 并可选配 RS485 通讯功能&#xff0c;方便用户进行用电监测、集抄和管理。可灵活安装于配电箱内&#xff0c;实现对不同区域和不 同 负 荷 …

分布式系统第三讲:全局唯一ID实现方案

分布式系统第三讲&#xff1a;全局唯一ID实现方案 本文主要介绍常见的分布式ID生成方式&#xff0c;大致分类的话可以分为两类&#xff1a;一种是类DB型的&#xff0c;根据设置不同起始值和步长来实现趋势递增&#xff0c;需要考虑服务的容错性和可用性; 另一种是类snowflake型…

信息化发展34

IT 审计目的 1 、IT 审计的目的是指通过开展IT 审计工作&#xff0c; 了解组织IT 系统与IT 活动的总体状况&#xff0c; 对组织是否实现口目标进行审查和评价&#xff0c; 充分识别与评估相关口风险&#xff0c;提出评价意见及改进建议&#xff0c; 促进组织实现IT 目标。 2 、…

禁用或卸载没那么复杂!如何在Windows 11上禁用或删除McAfee

​当你从Microsoft以外的制造商处购买新的Windows设备时,该设备可能已安装McAfee防病毒软件。虽然在你的电脑上安装防病毒软件总是一个好主意,但你可能更喜欢与McAfee不同的程序。在这种情况下,了解如何卸载McAfee是很重要的。 另一方面,你可能对McAfee很满意,但需要暂时…

忽悠苹果,销量垫底?小屏iPhone已经落寞,iPhone13mini即将停产

苹果公司的小屏iPhone系列可能即将走到尽头。据彭博社报道&#xff0c;苹果最新发布的 iPhone 13 mini 库存已经见底&#xff0c;部分款式在美国官网发货时间显示为2-3周&#xff0c;甚至最久达到了6-8周。这种现象表明&#xff0c;在周二的发布活动结束后&#xff0c;苹果最后…

SpringBoot底层注解

文章目录 前言一、Configuration二、Import导入组件三、Conditional条件装配四、ImportResource导入Spring配置文件五、ConfigurationProperties配置绑定总结 前言 本文主要讲诉Configuration、Import、Conditional、ImportResource、ConfigurationProperties注解。 先将实体…

一心堂正式启动“心链-SRM”项目,携手企企通搭建引领发展的采购供应链协同平台

近日&#xff0c;中国药品连锁零售行业首家上市企业一心堂药业集团股份有限公司&#xff08;以下简称“一心堂”&#xff09;与企企通成功召开“心链-SRM”采购供应链管理项目启动会。双方高层领导及项目团队关键成员出席现场&#xff0c;各子公司管理团队通过视频会议形式参与…

双碳目标下基于“遥感+”集成技术的碳储量、碳排放、碳循环、温室气体等多领域监测与模拟实践

卫星遥感具有客观、连续、稳定、大范围、重复观测的优点&#xff0c;已成为监测全球碳盘查不可或缺的技术手段&#xff0c;卫星遥感也正在成为新一代 、国际认可的全球碳核查方法。目的就是梳理碳中和与碳达峰对卫星遥感的现实需求&#xff0c;系统总结遥感技术在生态系统碳储量…