Spring boot 搭建个人博客系统(五)——标签和标签云

本文介绍使用SpringBoot、MyBatis和MySQL搭建个人博客系统中的标签功能实现,包括标签的插入、查询及标签云展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring boot 搭建个人博客系统(五)——标签和标签云

一直想用Spring boot 搭建一个属于自己的博客系统,刚好前段时间学习了叶神的牛客项目课受益匪浅,乘热打铁也主要是学习,好让自己熟悉这类项目开发的基本流程。系统采用Spring boot+MyBatis+MySQL的框架进行项目开发。

项目源码:Jblog 
个人主页:tuzhenyu’s page 
原文地址:Spring boot 搭建个人博客系统(五)——标签和标签云

0. 思路

  标签作为文章中的分类标记,会显示出该文章是关于哪一方面的文章,当我们点击该标签的时候,会出现该博客中所有属于该标签的文章。一篇文章可以对应很多标签,同时一个标签也可以对应很多篇文章,博客系统的标签功能是一种典型的多对多的情况。 
  解决多对多的标签问题,一般有两种方案。一种是将标签直接以逗号隔开组成一个字符串存储在article表的字段里,这种方案在文章插入和显示时比较简单,可以直接从标签字段里插入或读取,但是在归档同一标签的文章时复杂度较高,需要遍历全部文章记录将标签字段进行分割,看看该记录是否含有此标签,也可以直接使用like语法查询。另一种是将标签存在tag表中,同时创建article_tag关系表用来存储文章和标签的对应关系。在文章插入的同时插入文章标签关系记录,在文章显示的时候通过查询关系表获取article_id或者tag_id来实现标签功能。 
  

1. 数据模型

文章的标签功能需要操作数据库中的tag表和article_tag表,使用MyBatis作为系统的ORM框架用来简化数据操作。

  • 添加数据库表实体类
public class Tag {
    private int id;
    private String name;
    private int count;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

}
public class ArticleTag {
    private int id;
    private int articleId;
    private int tagId;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getArticleId() {
        return articleId;
    }

    public void setArticleId(int articleId) {
        this.articleId = articleId;
    }

    public int getTagId() {
        return tagId;
    }

    public void setTagId(int tagId) {
        this.tagId = tagId;
    }
}
  • 添加数据库操作DAO类
@Mapper
public interface ArticleDao {
    String TABLE_NAEM = " article ";
    String INSERT_FIELDS = " title, describes, content, created_Date, comment_Count, category ";
    String SELECT_FIELDS = " id, " + INSERT_FIELDS;

    @Insert({"insert into",TABLE_NAEM,"(",INSERT_FIELDS,") values (#{title},#{describes},#{content}" +
            ",#{createdDate},#{commentCount},#{category})"})
    int insertArticle(Article article);

    @Select({"select",SELECT_FIELDS,"from",TABLE_NAEM,"where id=#{id}"})
    Article selectById(int id);

    @Select({"select",SELECT_FIELDS,"from",TABLE_NAEM,"order by id desc limit #{offset},#{limit}"})
    List<Article> selectLatestArticles(@Param("offset") int offset, @Param("limit") int limit);

    @Select({"select",SELECT_FIELDS,"from",TABLE_NAEM,"where category=#{category} order by id desc limit #{offset},#{limit}"})
    List<Article> selecttArticlesByCategory(@Param("category") String category,@Param("offset") int offset, @Param("limit") int limit);

    @Select({"select count(id) from",TABLE_NAEM,"where category=#{category}"})
    int getArticleCountByCategory(@Param("category") String category);

    @Select({"select count(id) from",TABLE_NAEM})
    int getArticleCount();

    @Update({"update",TABLE_NAEM,"set comment_count = #{commentCount} where id = #{questionId}"})
    void updateCommentCount(@Param("questionId") int questionId,@Param("commentCount") int commentCount);

    @Delete({"delete from",TABLE_NAEM,"where id=#{id}"})
    void deleteById(int id);
}
@Mapper
public interface ArticleTagDao {
    String TABLE_NAEM = " article_tag ";
    String INSERT_FIELDS = " article_id, tag_id ";
    String SELECT_FIELDS = " id, " + INSERT_FIELDS;

    String TAG_FIELDS = " id, name, count ";
    String ARTICLE_FIELDS = " id, title, describes, content, created_Date, comment_Count , category ";

    @Insert({"insert into",TABLE_NAEM,"(",INSERT_FIELDS,") values (#{articleId},#{tagId})"})
    int insertArticleTag(ArticleTag articleTag);

    @Select({"select",TAG_FIELDS,"from tag where id in (select tag_id from article_tag where article_id=#{articleId})"})
    List<Tag> selectByArticleId(int articleId);

    @Select({"select",ARTICLE_FIELDS,"from article where id in (select article_id from article_tag where tag_id=#{tagId}) limit #{offset},#{limit}"})
    List<Article> selectByTagId(@Param("tagId") int tagId,@Param("offset") int offset, @Param("limit") int limit);

    @Select({"select count(id) from article where id in (select article_id from article_tag where tag_id=#{tagId})"})
    int selectArticleCountByTagId(@Param("tagId") int tagId);

    @Delete({"delete from",TABLE_NAEM,"where id=#{id}"})
    void deleteById(int id);
}

2. 标签功能

博客系统采用文章标签关系表的方式实现博客的标签功能,功能的实现主要包括标签的插入,特定文章所有标签的查询和特定标签所有文章的查询。

(1) 标签的插入:在文章发布的时候,将输入的标签信息插入数据库。如果数据库中已存在欲插入的标签则直接返回标签id,同时在文章标签关系表中插入一条关系记录;如果数据库中未存在欲插入的标签则插入该标签并返回标签id,同时在文章标签关系表中插入一条关系记录;

@RequestMapping("/articleAdd")
    public String addArticle(@RequestParam("title")String title,@RequestParam("category")String category,
                             @RequestParam("tag")String tag,@RequestParam("describe")String describe,
                             @RequestParam("content")String content){
    Article article = new Article();
    article.setTitle(title);
    article.setDescribes(describe);
    article.setCreatedDate(new Date());
    article.setCommentCount(0);
    article.setContent(JblogUtil.tranfer(content));
    article.setCategory(category);
    int articleId = articleService.addArticle(article);

    String[] tags = tag.split(",");
    for (String t : tags){
        Tag tag1 = tagService.selectByName(t);
        if (tag1==null){
            Tag tag2 = new Tag();
            tag2.setName(t);
            tag2.setCount(1);
            int tagId = tagService.addTag(tag2);

            ArticleTag articleTag = new ArticleTag();
            articleTag.setTagId(tagId);
            articleTag.setArticleId(articleId);
            tagService.addArticleTag(articleTag);
        }else {
            tagService.updateCount(tag1.getId(),tag1.getCount()+1);

            ArticleTag articleTag = new ArticleTag();
            articleTag.setTagId(tag1.getId());
            articleTag.setArticleId(articleId);
            tagService.addArticleTag(articleTag);
        }
    }

    return "redirect:/";
}

(2) 特定文章所有标签的查询:文章显示时查询此文章所有标签,先通过本文章标签关系表article_tag查询出所有与该文章关联的标签id,再在标签tag表中根据标签id查询出所有关联标签。

 @RequestMapping("/article/{articleId}")
    public String singleArticle(Model model, @PathVariable("articleId")int articleId){
 Article article = articleService.getArticleById(articleId);
 List<Tag> tags = tagService.getTagByArticleId(article.getId());
 model.addAttribute("article",article);
 model.addAttribute("tags",tags);
 return "article";
}

通过子查询获取特定文章的所有标签


    @Select({"select",TAG_FIELDS,"from tag where id in (select tag_id from article_tag where article_id=#{articleId})"})
    List<Tag> selectByArticleId(int articleId);

(3) 特定标签所有文章的查询:根据标签对文章分类显示时,通过标签查询所有关联文章。先通过本文章标签关系表article_tag查询出所有与该标签关联的文章id,再在文章article表中根据文章id查询出所有关联文章。

 @RequestMapping(value = "/tag/{tagId}",method = RequestMethod.GET)
    public String tag(Model model, @PathVariable("tagId")int tagId, @RequestParam("pageId")int pageId){
        List<Article> articles = articleService.getArticlesByTag(tagId,(pageId-1)*4,4);
        List<ViewObject> vos = new ArrayList<>();
        for (Article article:articles){
            ViewObject vo = new ViewObject();
            List<Tag> tags = tagService.getTagByArticleId(article.getId());
            String clickCount = jedisService.get(RedisKeyUntil.getClickCountKey("/article/"+article.getId()));
            if (clickCount==null)
                clickCount = "0";
            vo.set("clickCount",clickCount);
            vo.set("article",article);
            vo.set("tags",tags);
            vos.add(vo);
    }
    model.addAttribute("vos",vos);
    return "tag";
}

通过子查询获取特定文章的所有标签

 @Select({"select",ARTICLE_FIELDS,"from article where id in (select article_id from article_tag where tag_id=#{tagId}) limit #{offset},#{limit}"})
    List<Article> selectByTagId(@Param("tagId") int tagId,@Param("offset") int offset, @Param("limit") int limit);
  • 1
  • 2

3. 标签云功能

标签云的实现主要是通过一个JS插件jquery-tagclould.js实现的。

<div class="side tags">
 <div class="header"><i class="fa fa-tags" aria-hidden="true"></i><span>Tags</span></div>
  <div id="tagCloud">
    #foreach($tag in $tags)
    <a href="/tag/$!{tag.id}?pageId=1" rel="$!{tag.count}">$!{tag.name}</a>
    #end
  </div>
</div>
$('#tag').tokenfield();
$('#tagCloud a').tagcloud();
$.fn.tagcloud.defaults = {
    size: {start: 10, end: 18, unit: 'pt'},
    color: {start: '#aaa', end: '#555'}
};

4. 总结

  博客系统的标签功能是一种典型的数据库多对多情况,通过建立中间关系表将文章和标签关联起来,进而实现特定文章的标签列表查询和特定标签的文章列表查询。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.youkuaiyun.com/u013967175/article/details/77460549

核心功能 文章/图片/视频发布、喜欢、统计阅读次数。 文章标签tag功能、支持按tag分类 文章支持ueditor/markdown编辑器切换(后台配置) 评论功能,支持回复,支持表情。 第三方(微博、QQ)登录。 lucene实现的站内搜索。 响应式布局 支持用户订阅 先看效果图 SpringBoot开发非常美观的java博客系统(包含后台管理功能) SpringBoot开发非常美观的java博客系统(包含后台管理功能) SpringBoot开发非常美观的java博客系统(包含后台管理功能) http://localhost:8080/admin/group/list SpringBoot开发非常美观的java博客系统(包含后台管理功能) SpringBoot开发非常美观的java博客系统(包含后台管理功能)SpringBoot开发非常美观的java博客系统(包含后台管理功能) 技术选型: JDK8 数据库MySQL 主框架 (Spring-bootSpring-data-jpa) 安全权限 Shiro 搜索工具 Lucene 缓存 Ehcache 视图模板 Freemarker 其它 Jsoup、fastjson jQuery、Seajs Bootstrap 前端框架 UEditor/Markdown编辑器 font-Awesome 字体/图标 准备工作(sql文件在项目里面) 安装 Jdk8 安装 Maven 准备 IDE (如果你不看源码,可以忽略下面的步骤,直接通过Maven编译war包:mvn clean package -DskipTests) IDE 需要配置的东西 编码方式设为UTF-8 配置Maven 设置Jdk8 关于这些配置,网上有一大把的资料,所以此处不再重复。 获取代码导入到IDE 下载代码 导入到IDE的时候请选择以Maven的方式导入 项目配置参考 系统配置手册 配置完毕 启动项目,在控制台看到Mblog加载完毕的信息后,表示启动成功 打开浏览器输入:http//localhost/mblog/ (此处仅是示例,具体具体端口因人而异),访问成功即部署完毕 后台管理的地址是 /admin, 如果你是管理员账号点导航栏的头像会看到"后台管理" 启动成功后,你应该去后台的系统配置里配置你的网站信息等。 常见问题总结 进入系统后, 菜单加载不出来, 那应该是你没有导 db_init.sql 点标签显示乱码, 请设置Tomcat的 URIEncoding 为 UTF-8 项目截图 SpringBoot开发非常美观的java博客系统(包含后台管理功能) 转自:https://gitee.com/mtons/mblog SpringBoot开发非常美观的java博客系统(包含后台管理功能) 注意: 一、java main方式运行mblog-web下的BootApplication.java时抛出异常的解决方案 Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean. SpringBoot开发非常美观的java博客系统(包含后台管理功能) 注释掉后下面图片的这段后,记得maven要重新reimport SpringBoot开发非常美观的java博客系统(包含后台管理功能) SpringBoot开发非常美观的java博客系统(包含后台管理功能) 否则maven依赖不生效还是会抛出以上的异常 二、第三方登录点击后无响应,那是因为第三方开放平台回调的url失效导致,需要你去对应的第三方开放平台注册app后获取对应的oauth帐号 SpringBoot开发非常美观的java博客系统(包含后台管理功能) 三、idea以maven项目导入该项目后,发现没有maven的依赖包时,需要对每个maven module进行clearinstall,并且注意maven的依赖顺序 SpringBoot开发非常美观的java博客系统(包含后台管理功能) SpringBoot开发非常美观的java博客系统(包含后台管理功能) 四、访问地址是http://localhost:8080 登录时,帐号,密码只要自己找个密码,然后md5下在更新到db中即可登录成功。 比如:zuidaima 111111,md5后密码是 3931MUEQD1939MQMLM4AISPVNE,md5的java类 SpringBoot开发非常美观的java博客系统(包含后台管理功能) SpringBoot开发非常美观的java博客系统(包含后台管理功能)
基于springboot_ssm的个人博客源代码: 个人博客系统主要用于发表个人博客,记录个人生活日常,学习心得,技术分享等,供他人浏览,查阅,评论等。本系统结构如下: (1)博主端: 登录模块:登入后台管理系统:首先进入登录页面,需要输入账号密码。它会使用Shiro进行安全管理,对前台输入的密 码进行加密运算,然后与数据库中的进行比较。成功后才能登入后台系统。 博客管理模块: 博客管理功能分为写博客博客信息管理。写博客是博主用来发表编写博客的,需要博客标题,然后选择博 客类型,最后将博客内容填入百度的富文本编辑器中,点击发布博客按钮即可发布博客博客类别管理模块:博主类别管理系统可以添加,修改删除博客类型名称排序序号。将会显示到首页的按日志类别区域。 游客可 以从这里查找相关的感兴趣的博客内容 评论信息管理模块:评论管理功能分为评论审核评论信息管理两部分。评论审核是当有游客或自己发表了评论之后,博主需 要在后台管理系统中审核评论。若想将此评论显示在页面上则点击审核通过,否则点击审核不通过。 个人信息管理模块:修改博主的个人信息,可以修改昵称,个性签名,可以添加个人头像,修改个人简介; 系统管理功能模块:友情链接管理,修改密码,刷新系统缓存安全退出,友情链接管理可以添加,修改,删除友情链接网址 (2)游客端: 查询博客: 查询具体哪一篇博客 查看博客内容: 查看博客内容 查看博主个人信息:查看博主个人简介 发表评论: 可以评论具体某篇博客 友情链接: 查看友情链接
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值