VBlog项目代码理解之后端
文章目录
- VBlog项目代码理解之后端
- 资源
- Bean
- Mapper
- Service
- Config:登录Spring Security配置
- Controller
- Resources:配置文件与前端资源
VBlog项目代码理解之后端
资源
项目地址
前后端交互代码理解
前端代码理解
推荐:整个项目几乎是只用到了SpringBoot、Vue、Mybatis、ElementUI,没有用到Redis、RabbitMQ等内容,很适合刚学完SpringBoot和Vue的同学练手,感谢作者!帮作者打个广告吧~
PS:这是本人第一个学习的项目,难免会有错误的地方,哪里有问题烦请指正,感谢!
因为主要学的后端,之前也练过图书管理系统,所以没什么好详细记录的,就是有些Mybatis
操作还不熟悉。
Bean
很多bean类,但只有User
类实现了UserDetails
(UserDetails
和UserDetailsService
在下面的Spring Security
有介绍),其他的类都通过id等方式和User绑定。
要特别注意的方法就是getAuthorities()
还用@JsonIgnore
注释了一些重载方法,注意中间isEnabled()
没有用这个注释
@Override@JsonIgnorepublic boolean isAccountNonExpired() {return true;}@Override@JsonIgnorepublic boolean isAccountNonLocked() {return true;}@Override@JsonIgnorepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isEnabled() {return enabled;}public void setEnabled(boolean enabled) {this.enabled = enabled;}@Override@JsonIgnorepublic List<GrantedAuthority> getAuthorities() {List<GrantedAuthority> authorities = new ArrayList<>();for (Role role : roles) {authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getName()));}return authorities;}
Mapper
就是一些基础方法的组合
迷惑:
分页:
<!--状态与权限的搜索,为啥还限制了分页?--><select id="getArticleByStateByAdmin" resultType="org.sang.bean.Article">SELECT a.id,a.`title`,a.`editTime`,a.`pageView`,a.`state`,u.`nickname`,c.`cateName`,a.uid FROM article a,useru,category c WHERE a.`cid`=c.`id` AND a.`uid`=u.`id` and a.state=1<if test="keywords!=null">AND title LIKE concat('%',#{keywords},'%')</if>ORDER BY a.editTime DESC limit #{start},#{count};</select><select id="getArticleCountByState" resultType="int">SELECT count(*) FROM article<where><if test="state!=-1">AND state=#{state}</if><if test="uid!=null">AND uid=#{uid}</if><if test="keywords!=null">AND title LIKE concat('%',#{keywords},'%')</if></where></select>
奇怪的LEFT、JOIN、ON
<!--啊!LEFT JOIN ON是啥--><select id="getArticleById" parameterType="Long" resultMap="BaseResultMap">SELECT a.*,t.`tagName`,t.`id` AS tid,u.`nickname`,c.`cateName` FROM article a LEFT JOIN article_tags ats ON a.`id`=ats.`aid` LEFT JOIN tags t ON ats.`tid`=t.`id` LEFT JOIN user u ON a.`uid`=u.`id` LEFT JOIN category c ON a.`cid`=c.`id` WHERE a.id=#{aid}</select><resultMap id="BaseResultMap" type="org.sang.bean.Article"><id column="id" property="id"/><result column="title" property="title"/><result column="cid" property="cid"/><result column="uid" property="uid"/><result column="publishDate" property="publishDate"/><result column="editTime" property="editTime"/><result column="state" property="state"/><result column="pageView" property="pageView"/><result column="mdContent" property="mdContent"/><result column="htmlContent" property="htmlContent"/><result column="summary" property="summary"/><result column="nickname" property="nickname"/><result column="cateName" property="cateName"/><collection property="tags" ofType="org.sang.bean.Tags" column="tagName"><id property="id" column="tid"/><result property="tagName" column="tagName"/></collection></resultMap>
学习操作:
动态sql:
<!--根据状态看某种全部文章或者模糊搜索--><!--用动态SQL实现两种功能,厉害--><select id="getArticleByState" resultType="org.sang.bean.Article">SELECT a.id,a.`title`,a.`editTime`,a.`pageView`,a.`state`,u.`nickname`,c.`cateName`,a.uid FROM article a,useru,category c WHERE a.`cid`=c.`id` AND a.`uid`=u.`id`<if test="state!=-2">and a.uid=#{uid}</if><if test="state!=-1 and state!=-2">and a.state=#{state}</if><if test="state==-2">and a.state=1</if><if test="keywords!=null">AND title LIKE concat('%',#{keywords},'%')</if>ORDER BY a.editTime DESC limit #{start},#{count};</select>
foreach:
<!--批量更新,应是对应着批量删除操作,把文章放入回收站--><!--学学foreach--><update id="updateArticleState">UPDATE article SET state=#{state} WHERE id IN<foreach collection="aids" item="aid" separator="," open="(" close=")">#{aid}</foreach></update>
有自增主键,用null填上:
<insert id="addRoles">INSERT INTO roles_user VALUES<foreach collection="roles" item="role" separator=",">(null,#{role},#{uid})</foreach></insert>
Service
UserService:
还是只有UserService
实现了UserDetailsService
方法。
重写的loadUserByUsername
方法。
@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {User user = userMapper.loadUserByUsername(s);if (user == null) {//避免返回null,这里返回一个不含有任何值的User对象,在后期的密码比对过程中一样会验证失败return new User();}// 查询用户的角色信息,并返回存入user中// 如果user为null这里就会报错List<Role> roles = rolesMapper.getRolesByUid(user.getId());user.setRoles(roles);return user;}
public int reg(User user) {User loadUserByUsername = userMapper.loadUserByUsername(user.getUsername());// 看看用这个名字能不能读出数据,能就代表名字重复了if (loadUserB yUsername != null) {// 重复return 1;}//插入用户,插入之前先对密码进行加密user.setPassword(passwordEncoder.encode(user.getPassword()));user.setEnabled(true);//用户可用long result = userMapper.reg(user);//配置用户的角色,默认都是普通用户String[] roles = new String[]{"2"};int i = rolesMapper.addRoles(roles, user.getId());boolean b = i == roles.length && result == 1;if (b) {// 成功return 0;} else {// 失败return 2;}}
其他的部分平平无奇
CategoryService:
批量删除的操作比较有意思,传进去的就是一个String数组
public boolean deleteCategoryByIds(String ids) {String[] split = ids.split(",");int result = categoryMapper.deleteCategoryByIds(split);return result == split.length;}
int deleteCategoryByIds(@Param("ids") String[] ids);
<delete id="deleteCategoryByIds">DELETE FROM category WHERE id IN<foreach collection="ids" separator="," open="(" close=")" item="id">#{id}</foreach></delete>
DataStatisticsComponent:
使用了一个定时执行注解:
好像是倒着来,每天0 : 01会执行一次
这个注解要在XXXApplication
文件中开启注解支持@EnableScheduling//开启定时任务支持
//每天执行一次,统计PV@Scheduled(cron = "1 0 0 * * ?")public void pvStatisticsPerDay() {articleService.pvStatisticsPerDay();}
ArticleService:
比较复杂的就是文章和对应标签的
public int addNewArticle(Article article) {//处理文章摘要, 如果没写的话就截取前50个字符if (article.getSummary() == null || "".equals(article.getSummary())) {//直接截取String stripHtml = stripHtml(article.getHtmlContent());article.setSummary(stripHtml.substring(0, stripHtml.length() > 50 ? 50 : stripHtml.length()));}// id=-1就是刚添加的,有id就是更新if (article.getId() == -1) {//添加操作Timestamp timestamp = new Timestamp(System.currentTimeMillis());if (article.getState() == 1) {//设置发表日期article.setPublishDate(timestamp);}article.setEditTime(timestamp);// 设置当前用户,同时添加到数据库article.setUid(Util.getCurrentUser().getId());int i = articleMapper.addNewArticle(article);// 打标签,也是加到数据库中// 因为文章和tag是两个类,通过id绑定,所以不能一步走String[] dynamicTags = article.getDynamicTags();if (dynamicTags != null && dynamicTags.length > 0) {int tags = addTagsToArticle(dynamicTags, article.getId());if (tags == -1) {return tags;}}return i;} else {Timestamp timestamp = new Timestamp(System.currentTimeMillis());if (article.getState() == 1) {//设置发表日期article.setPublishDate(timestamp);}//更新article.setEditTime(new Timestamp(System.currentTimeMillis()));int i = articleMapper.updateArticle(article);//修改标签String[] dynamicTags = article.getDynamicTags();if (dynamicTags != null && dynamicTags.length > 0) {int tags = addTagsToArticle(dynamicTags, article.getId());if (tags == -1) {return tags;}}return i;}}private int addTagsToArticle(String[] dynamicTags, Long aid) {//1.删除该文章目前所有的标签tagsMapper.deleteTagsByAid(aid);//2.将上传上来的标签全部存入数据库tagsMapper.saveTags(dynamicTags);//3.查询这些标签的idList<Long> tIds = tagsMapper.getTagsIdByTagName(dynamicTags);//4.重新给文章设置标签int i = tagsMapper.saveTags2ArticleTags(tIds, aid);return i == dynamicTags.length ? i : -1;}
Config:登录Spring Security配置
看Spring Security的笔记就行。
笔记地址
Controller
注意权限,如果有多个权限,那不同的权限处理放到不同的文件夹较好。而且在对应的控制类上加上权限的前缀,如/admin
,/user
,这样也方便后面的config
中的权限管理。
当使用SpringBoot和Vue做前后端分离的项目的时候,controller
是不做视图跳转的,并不能控制到视图,跳转都被Vue
的router
做了,所以一般都在controller上加了@RestController
注解。
Resources:配置文件与前端资源
将Vue
的内容做npm run build
,就会生成一个dist
文件啊加,将其中的文件夹static
和文件index.html
拷贝到后端项目的resources/static/
,再在application.properties
中设置端口号server.port=xxxx
,运行SpringBoot就行了,输入http://localhost:xxxx/index.html
即可。
VBlog项目代码理解之后端相关推荐
- Git拉代码到本地并运行Vue/springboot项目代码(以内网gitlab为例)
因本人是开发小白,所以将开发过程中所需要的关键地方都记载在此处以备复盘,同时也希望给大家可以提供一些帮助. 目录 一.安装Git 二.登录GitLab账号 三.拉取代码 1.直接通过http拉取代码 ...
- SpringBoot+MyBatisPlus+Vue 前后端分离项目快速搭建【后端篇】【快速生成后端代码、封装结果集、增删改查、模糊查找】【毕设基础框架】
前后端分离项目快速搭建[后端篇] 数据库准备 后端搭建 1.快速创建个SpringBoot项目 2.引入依赖 3.编写代码快速生成代码 4.运行代码生成器生成代码 5.编写application.pr ...
- B站项目-云E办的项目代码(含前端和后端)
云办公的项目代码(含前端和后端) 博主为了学习 Vue 和 SpringBoot 参考网上的项目基于ElementUI组件库搭建了一款适用于在线办公的网站框架,如果有需要资料的同学可以加QQ群交流 Q ...
- git拉取tag代码_10年经验17张图带你进入gitflow企业项目代码版本管理的最佳实践...
前言 对于项目版本管理,你是否存在这样的痛点:项目分支多而杂不好管理,git log界面commit信息错乱复杂无规范,版本回退不知道选择什么版本合适--. 项目版本管理的最佳实践系列,笔者将以两篇文 ...
- 实战react技术栈+express前后端博客项目(3)-- 后端路由、代理以及静态资源托管等配置说明...
项目地址:github.com/Nealyang/Re- 本想等项目做完再连载一波系列博客,随着开发的进行,也是的确遇到了不少坑,请教了不少人.遂想,何不一边记录踩坑,一边分享收获呢.分享当然是好的, ...
- 前后端分离简单项目--蚂蚁博客--后端部分
原文网址:前后端分离简单项目--蚂蚁博客--后端部分_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍我从0开发的前后端分离的简单项目--蚂蚁博客.本博文介绍后端部分. 本项目是 ...
- keycloak项目代码
1.前言 有两个项目,需要用keycloak管理做一键登录(登录一个项目,另一个无需登录可直接访问) 项目1:管理系统(主业务) 项目2:文件上传下载(辅助业务) 授权码模式:(5条消息) keycl ...
- BUAA-2023软件工程团队项目——代码管理
项目 这个作业属于哪个课程 2023北航敏捷软件工程 这个作业的要求在哪里 团队项目-代码管理准备 我们在这个课程的目标是 学习并实践软件工程开发的方法论.在把握整体流程和内容要素的基础上实践细节,培 ...
- 使用pycharm将自己项目代码上传github(保姆教程)
1.梳理一下Git.github和gitee这三个之间的关系: 1.1.Github 首先从我们最熟悉的github来说,他其实是一个代码托管平台,我们可以在他的里面新建很多的仓库,有强迫症的我理解就 ...
- 优秀的 Java 项目代码都是如何分层的?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 来源:http://rrd.me/ej56f 1.背景 2.如何进 ...
最新文章
- java读取字节效率最高_Java-IO 字节流的使用和效率比较
- binary search完整笔记
- c#sort升序还是降序_被玩坏的数组排序之sort函数
- python open函数参数newline_Python open() 函数
- csv to mysql_CSV to array
- 字节跳动宣布取消大小周;淘宝、支付宝等阿里系App取消开屏广告;Python 3.10 beta 4 发布|极客头条...
- 查看perl的模块版本
- java的Timer定时器
- Ibatis结合MySQL数据库的使用方法
- 删除非系统盘的msdia80.dll文件以及出现的dllregisterserver调用失败错误代码0x80004005问题
- GSCoolink GSV6201 TypeC/DP to HDMI2.1
- 解决图像目标检测两框重叠问题
- UI层自动化测试框架(五):业务层和用例层
- JMeter中级篇-9-网站性能测试用例2设计
- 行业要闻丨巨额研发投入助力量子技术发展
- 服务器系统如何账务处理,云服务器的账务处理
- 骁龙765g和麒麟9905g差别大不大 骁龙765g和麒麟990哪一个更好一点
- 红米k50至尊版和k50区别哪个好
- 大数据是什么?大数据的趋势?
- php:输入值/表单提交参数过滤,防止sql注入或非法攻击的方法
热门文章
- html---表单实例代码
- 32把数组排成最小的数({3,32,321}输出最小数字为321323)
- 如何阅读源码学习总结
- Word给自动生成的目录页码添加括号
- 学生个人网页设计作品 学生个人网页模板 简单个人主页成品 个人网页制作 HTML学生个人网站作业设计 汉语言文学设计题材网页
- 汽车制造行业OEM Tier1 Tier2指代什么?
- 北京邮电大学计算机科学与技术专业研究生,北京邮电大学计算机科学与技术专业...
- 设计过程(概要设计和详细设计)
- 给出a-z,0-9,输出所有的3个字符的组合
- 使用MapReduce实现专利文件的分析