Spring boot 搭建个人博客系统(五)——标签和标签云
2017-08-21 21:10
441 查看
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);
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. 总结
博客系统的标签功能是一种典型的数据库多对多情况,通过建立中间关系表将文章和标签关联起来,进而实现特定文章的标签列表查询和特定标签的文章列表查询。相关文章推荐
- Spring boot 搭建个人博客系统(一)——整体思路
- Spring boot 搭建个人博客系统(六)——文章点击量和阅读排行榜
- 使用Spring Boot搭建个人博客遇到的问题
- 使用Spring Boot搭建个人博客全记录
- SpringBoot + Mybatis + thymeleaf 搭建的个人博客
- springboot+thymeleaf 实现thymeleaf自定义方言系统 自定义标签, cms系统搭建(二)
- 使用SpringBoot+SemanticUI搭建一个博客后台管理系统
- springboot+thymeleaf 实现thymeleaf自定义方言系统 自定义标签, cms系统搭建(一)
- Spring Boot+JPA+Mysql+ThymeLeaf快速构建CURD系统(二)搭建SpringBoot工程
- Spring Boot+JPA+Mysql+ThymeLeaf快速构建CURD系统(二)搭建SpringBoot工程
- 使用Spring boot实现开源博客系统之始
- 快速搭建个人博客系统
- 自己用springboot+mybatis+easyui写的个人管理系统遇到的问题总结
- 个人博客系统(Spring,Spring MVC,MyBatis)
- Spring Boot+JPA+Mysql+ThymeLeaf快速构建CURD系统(二)搭建SpringBoot工程
- Spring Boot+JPA+Mysql+ThymeLeaf快速构建CURD系统(二)搭建SpringBoot工程
- ssm从零搭建个人博客系统(零)
- Spring Boot+JPA+Mysql+ThymeLeaf快速构建CURD系统(二)搭建SpringBoot工程
- 【基于SSH框架的个人博客系统01】Eclipse搭建SSH框架详细流程
- 【基于SSH框架的个人博客系统01】Eclipse搭建SSH框架详细流程