前言
🌟🌟本期讲解关于websocket的相关知识介绍~~~
🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客
🔥 你的点赞就是小编不断更新的最大动力
🎆那么废话不多说直接开整吧~~
目录
📚️1.数据库设计
🚀1.1数据库
小编使用的是navicat,具体的数据库如下所示,由于发表文章设计三个数据库:
文章数据库,板块数据库,作者数据库(这里指的就是用户数据库)
文章数据库:
包含了文章id,文章属于那个板块,所以板块id,谁发表的就是用户id,以及文章题目,内容,以及点赞数,回复数,浏览量等等,可以看看表的英文解释;
用户数据库:
这里就包含了用户id(与文章里的对应),以及username,password,包含比较重要的一些用户数据;
板块数据库:
这里就是每个板块的信息,板块名字,板块内发布的文章的数量,先后顺序等等.....
🚀1.2板块数据库SQL语句编写
分析:
我们要发布一篇文章,那么发布文章后,对应发布文章的作者对应的发布数量要增加,以及文章属于那个板块,那么板块包含的数量也要增加,所以这里涉及到三个数据库的操作;
1.2.1用户表更新数据
这里很明显是动态更新,具体的SQL语句如下所示:
<update id="updateByPrimaryKeySelective" parameterType="com.example.forum.model.User">
update t_user
<set>
<if test="username != null">
username = #{username,jdbcType=VARCHAR},
</if>
<if test="password != null">
password = #{password,jdbcType=VARCHAR},
</if>
<if test="nickname != null">
nickname = #{nickname,jdbcType=VARCHAR},
</if>
<if test="phoneNum != null">
phoneNum = #{phoneNum,jdbcType=VARCHAR},
</if>
<if test="email != null">
email = #{email,jdbcType=VARCHAR},
</if>
<if test="gender != null">
gender = #{gender,jdbcType=TINYINT},
</if>
<if test="salt != null">
salt = #{salt,jdbcType=VARCHAR},
</if>
<if test="avatarUrl != null">
avatarUrl = #{avatarUrl,jdbcType=VARCHAR},
</if>
<if test="articleCount != null">
articleCount = #{articleCount,jdbcType=INTEGER},
</if>
<if test="isAdmin != null">
isAdmin = #{isAdmin,jdbcType=TINYINT},
</if>
<if test="remark != null">
remark = #{remark,jdbcType=VARCHAR},
</if>
<if test="state != null">
state = #{state,jdbcType=TINYINT},
</if>
<if test="deleteState != null">
deleteState = #{deleteState,jdbcType=TINYINT},
</if>
<if test="createTime != null">
createTime = #{createTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null">
updateTime = #{updateTime,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
1.2.2板块表更新数据
很明显这里肯定也是动态更新的过程:
<update id="updateByPrimaryKeySelective" parameterType="com.example.forum.model.Board">
update t_board
<set>
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
</if>
<if test="articleCount != null">
articleCount = #{articleCount,jdbcType=INTEGER},
</if>
<if test="sort != null">
sort = #{sort,jdbcType=INTEGER},
</if>
<if test="state != null">
state = #{state,jdbcType=TINYINT},
</if>
<if test="deleteState != null">
deleteState = #{deleteState,jdbcType=TINYINT},
</if>
<if test="createTime != null">
createTime = #{createTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null">
updateTime = #{updateTime,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{id,jdbcType=BIGINT}
</update>
1.2.3文章表发布数据
这里发布,那么就是往数据库中插入数据:
<insert id="insertSelective" parameterType="com.example.forum.model.Article">
insert into t_article
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="boardId != null">
boardId,
</if>
<if test="userId != null">
userId,
</if>
<if test="title != null">
title,
</if>
<if test="visitCount != null">
visitCount,
</if>
<if test="replyCount != null">
replyCount,
</if>
<if test="likeCount != null">
likeCount,
</if>
<if test="state != null">
state,
</if>
<if test="deleteState != null">
deleteState,
</if>
<if test="createTime != null">
createTime,
</if>
<if test="updateTime != null">
updateTime,
</if>
<if test="content != null">
content,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="boardId != null">
#{boardId,jdbcType=BIGINT},
</if>
<if test="userId != null">
#{userId,jdbcType=BIGINT},
</if>
<if test="title != null">
#{title,jdbcType=VARCHAR},
</if>
<if test="visitCount != null">
#{visitCount,jdbcType=INTEGER},
</if>
<if test="replyCount != null">
#{replyCount,jdbcType=INTEGER},
</if>
<if test="likeCount != null">
#{likeCount,jdbcType=INTEGER},
</if>
<if test="state != null">
#{state,jdbcType=TINYINT},
</if>
<if test="deleteState != null">
#{deleteState,jdbcType=TINYINT},
</if>
<if test="createTime != null">
#{createTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null">
#{updateTime,jdbcType=TIMESTAMP},
</if>
<if test="content != null">
#{content,jdbcType=LONGVARCHAR},
</if>
</trim>
</insert>
📚️2.Dao层的设计
这里很简单就是设计接口与数据库进行连接,种类小编将三种接口的设计一起写入到下方:
//板块数据的动态更新
int updateByPrimaryKeySelective(Board record);
//用户数据的动态更新
int updateByPrimaryKeySelective(User record);
//文章的发布(插入)
int insertSelective(Article record);
注意:每个方法的名字要和上述SQL在xml中的id要保持一致,不然会出现无法找到我们所需要的SQL语句来操作数据库;
📚️3.Service层的设计
🚀3.1用户service层
这里先规定service接口,在使用实现类进行实现
/**
* 用户发布帖子后进行帖子数量的增加
* @param id
*/
void addOneArticleCountById(Long id);
对应的实现类的代码如下所示:
@Override
public void addOneArticleCountById(Long id) {
//校验参数
if(id == null || id <= 0){
log.warn(ResultCode.FAILED_BOARD_ARTICLE_COUNT.toString());
throw new ApplicationException(AppResult.fail(ResultCode.FAILED_BOARD_ARTICLE_COUNT));
}
//进行获取对象
User user = userMapper.selectByPrimaryKey(id);
//校验这里的对象是否存在
if(user == null){
log.warn(ResultCode.ERROR_IS_NULL.toString() + ", user id = " + id);
// 抛出异常
throw new ApplicationException(AppResult.fail(ResultCode.ERROR_IS_NULL));
}
//然后通过更新这里的文章数量
User updataUser = new User();
updataUser.setId(user.getId());
updataUser.setArticleCount(user.getArticleCount() + 1);
//更新
int result = userMapper.updateByPrimaryKeySelective(updataUser);
if(result != 1){
log.warn(ResultCode.FAILED.toString());
throw new ApplicationException(AppResult.fail(ResultCode.FAILED));
}
}
大体的步骤就是:对于id进行参数的校验,然后通过id拿到这里的用户的对象;再次进行非空的校验,最后就是设修改的对象,传入用户要修改的信息即可;那么最后一步就是判断这里的修改行数是否是1即可;
🚀3.2板块service层
大致和用户差不多,service实现类如下所示:
@Override
public void addOneArticleCountById(Long id) {
//首先判断id参数的合法性
if(id == null || id <= 0){
log.warn("没有找到对应的板块,id:" + id);
throw new ApplicationException(AppResult.fail(ResultCode.FAILED_BOARD_ARTICLE_COUNT));
}
//根据id查询对应的板块
Board board = boardMapper.selectByPrimaryKey(id);
//校验是否正确
if(board == null){
//此时板块为空
log.warn(ResultCode.ERROR_IS_NULL.toString());
throw new ApplicationException(AppResult.fail(ResultCode.ERROR_IS_NULL));
}
//更新这里的文章的数量
Board updataBoard = new Board();
updataBoard.setId(board.getId());
updataBoard.setArticleCount(board.getArticleCount() + 1);
int result = boardMapper.updateByPrimaryKeySelective(updataBoard);
//判断这里的更新是否出现了的错误
if(result != 1){
log.warn(ResultCode.FAILED.toString());
throw new ApplicationException(AppResult.fail(ResultCode.FAILED));
}
}
和用户板块差不多,那么这里抛出异常主要是为了事务进行准备;
🚀3.3文章service层
在接口中由于这里涉及三个表的设计,所以为了保证安全性,这里使用事务,保证三个数据库更改一起成功或者一起失败:
@Transactional
void create(Article article);
那么至于service层代码来说:
public void create(Article article) {
//进行参数的校验
if(article == null || article.getUserId() == null
|| article.getBoardId() == null
|| !StringUtils.hasLength(article.getContent())
|| !StringUtils.hasLength(article.getTitle())){
log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
}
//设置默认值
article.setVisitCount(0); // 访问数
article.setReplyCount(0); // 回复数
article.setLikeCount(0); // 点赞数
article.setDeleteState((byte) 0);
article.setState((byte) 0);
Date date = new Date();
article.setCreateTime(date);
article.setUpdateTime(date);
//进行创建文章的操作
int result = articleMapper.insertSelective(article);
if(result != 1){
throw new ApplicationException(AppResult.fail(ResultCode.FAILED_CREATE));
}
//更新这里的用户表数据以及板块表数据
//这里要进行校验的操作,利用事务进行轮滚或者是提交
User user = userServiceImp.selectById(article.getUserId());
if(user == null){
throw new ApplicationException(AppResult.fail(ResultCode.FAILED_CREATE));
}
userServiceImp.addOneArticleCountById(user.getId());
Board board = boardServiceImp.selectById(article.getBoardId());
if(board == null){
throw new ApplicationException(AppResult.fail(ResultCode.FAILED_CREATE));
}
boardServiceImp.addOneArticleCountById(board.getId());
}
大致就是在进行数据校验的判断后,设置要传递的对象实现数据修改,并进行是否成功的判断,然后对于两个板块和用户对象来说,这里还需要进行对应的service层方法的调用实现对应数据库的数据更改;(前提也是进行获得的对象的非空的校验);
这里上述三个service层来说一但抛出异常后,那么事务就会回滚,而不会提交 ,保证了数据的准确性以及正确性;
📚️4.Controller层的设计
这里是发表文章,牵连到三个数据库的设计,所以只需要设计发表文章的控制类即可
具体的代码如下所示:
@RequestMapping(value = "/create" ,method = RequestMethod.POST)
public AppResult create(HttpServletRequest request,
@RequestParam("boardId") @NonNull Long boardId,
@RequestParam("title") @NonNull String title,
@RequestParam("content") @NonNull String content){
//判断用户是否禁言,用户对象从session中进行获取
HttpSession session = request.getSession(false);
User user =(User) session.getAttribute(ContentConfig.USER_SESSION);
if(user.getState() == 1){
//说明此时用户处于禁言的状态
return AppResult.fail(ResultCode.FAILED_USER_BANNED);
}
//设置传递参数
Article article = new Article();
article.setUserId(user.getId());
article.setBoardId(boardId);
article.setContent(content);
article.setTitle(title);
articleServiceImp.create(article);
return AppResult.success("发表文章成功");
}
解释:首先设置路由,以及需要的方法,然后设置的三个参数来说,直接是使用lombok中的NunNull进行非空的校验,然后从session中获取用户对象,设置这里传递的对象,最后调用service层的代码即可;
📚️5.测试
最后我们使用pastman进行测试这里的代码,是否能成功修改我们的数据库:
注意:由于要使用这里的session来获取对象,那么我们首先进行登录,然后再进行测试:
那么此时我们检查一下我们navicat中的数据库:
很明显这里输入的2指的就是板块2,这里的文章数量很明显进行了加一的操作;
然后这里的文章板块也进行了对应的发布操作;
对应的用户发布的文章也进行了加一的操作;
📚️6.总结
本期主要讲解了关于发布文章,牵连的三个数据库表的设计操作,从SQL的编写到Dao层,Service层,Controller层的程序设计;以及最后的结果展示;
🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!
💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。
😊😊 期待你的关注~~~