⭐ 作者简介:码上言
⭐ 代表教程:Spring Boot + vue-element 开发个人博客项目实战教程
项目部署视频
https://www.bilibili.com/video/BV1sg4y1A7Kv/?vd_source=dc7bf298d3c608d281c16239b3f5167b
文章目录
前言
经历了那么多天的基础项目的搭建,终于把基本的项目配置、项目日志、项目管理以及数据库建立起来了。可能会遇到很多的问题,遇到问题首先想的是怎么去解决,而不是想着太难了就算了。我是希望能给大家带来一点帮助。最近可能会更新的比较慢,因为还有好多平时自己的事情要去做,我也在构思如何是这个项目更加的简洁,能跑起来,才会有成就感,才会是你自己有学习的动力。好啦,不多说啦,以后有人生感慨可以和我私聊。下面开始狂撸用户中心的功能。
用户中心主要是我们对账号的管理,用户登录账号等,我现在考虑的是暂时不做权限角色管理,现在只实现一个角色的用户登录,因为是自己的博客系统,目前只能由自己开发,后期有时间的话,会放在第二版的项目更新的时候再做,第一版先搭建基础的用户管理。
一、引入Lombok
1、为什么要用Lombok
Lombok官方文档:https://projectlombok.org/features/all
在本项目中我们要用到Lombok中的注解,可以帮助我们节省大量重复的代码编写工作,正所谓:任何技术的出现都是为了解决某一类问题。我们在学基础的时候应该都会学到getter/setter/toString 等代码的编写,其实仔细想想当时我们是直接生成的,会使一个类中出现大量的无含量的代码,然而Lombok就会帮我们把这些代码省略掉,只需要加一个注解即可,这个也是现在开发项目中经常要使用的。
2、引入相应的maven包
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.22</version> </dependency>
我们在项目的pom.xml
中,再添加这个maven包。然后点击刷新,等待加载完成即可。
3、添加IDE工具对Lombok的支持
接下来,我们要在IDEA
去安装这个Lombok
插件,方便我们开发,使得我们的开发工具去支持这个功能。
点击左上角的File
,然后选择Settings
然后打开,找到Plugins
,在这里面可以搜索到Lombok
,如果没有搜索到可能是网络的原因,或者看一下你IDEA
的版本,2020
最后一个版本后的基本上都可以使用,在第三章我提供的IDEA
工具肯定可以搜索到。安装完之后,可能需要重新启动下IDEA
即可。
4、Lombok注解的使用
我们最先用到的则是@Data
注解,里面有@Getter/@Setter
方法。具体的我们去代码中实现,实战讲解。
具体的某些注解可以看我写的注解那一篇的文章:Lombok核心注解总结:https://blog.csdn.net/m0_37779600/article/details/120188115
二、用户功能实现增删改查
首先实现用户列表的功能,这个就是从数据库捞出数据,在后台管理页面上展示即可,这里的查找就会遇到分页的功能,虽然是我们自己管理,没几个账号,就不使用分页了,我们会在文章管理功能在使用分页查询。
用户中心添加的总类目录参考:
1、添加实体类
在类的上方添加了一个@Data
注解,这个注解就是我们刚才引入的Lombok
,可以帮我们省略点@Getter/@Setter
方法。这就是我们创建的用户实体对象。
在我们创建的entity
包中创建一个User.java
类,然后将以下代码添加在类中。
package com.blog.personalblog.entity; import lombok.Data; import java.time.LocalDateTime; import java.util.Date; /** * @author: SuperMan * 欢迎关注公众号:码上言 * @create: 2021-11-02 */ @Data public class User { /** * 主键id */ private Integer id; /** * 用户名 */ private String userName; /** * 密码 */ private String passWord; /** * 邮箱 */ private String email; /** * 上次登录时间 */ private Date lastLoginTime; /** * 手机号 */ private Integer phone; /** * 昵称 */ private String nickname; /** * 创建时间 */ private LocalDateTime createTime; /** * 更新时间 */ private LocalDateTime updateTime; }
2、添加业务接口
在我们创建的service
包中,创建一个UserService.java
类,该类是一个接口类,是将我们的业务功能暴露出去,可以供接口层调用
此类实现了用户的增删改查功能接口,其中增加、修改和删除只需要在接口层返回一个成功或者失败的信息即可,不需要返回数据。
package com.blog.personalblog.service; import com.blog.personalblog.entity.User; import java.util.List; /** * @author: SuperMan * 欢迎关注我的公众号:码上言 * @create: 2021-11-03 */ public interface UserService { /** * 查询所有用户列表 * @return */ List<User> findAll(); /** * 添加用户 * @param user */ void createUser(User user); /** * 修改用户信息 * @param user */ void updateUser(User user); /** * 删除用户 * @param id */ void deleteUser(int id); }
3、添加业务接口实现类
实现类则实现了业务接口的功能,继承这个接口,具体的业务的逻辑都会在这个类中写,很重要,同时和数据库接口相连,进行调用数据库的接口,实现数据处理。在我们创建的Impl包中新建一个UserServiceImpl.java
类,同时继承UserService
接口,用关键字implements
去继承接口,具体的extends
和implements
的区别可以去百度了解。
创建完是这样样子的,接下来教大家一个快的创建接口实现的方法。
package com.blog.personalblog.service.Impl; import com.blog.personalblog.service.UserService; import org.springframework.stereotype.Service; /** * 业务实现层 * * @author: SuperMan * 欢迎关注我的公众号:码上言 * @create: 2021-11-03 * */ @Service public class UserServiceImpl implements UserService { }
鼠标浮在报错的这个类上,会出现以下报错信息,然后点击Implement methods
。
此时就会弹出这个弹出框,里面正是我们刚才在UserService.java
中创建的方法,然后点击OK即可。
以下就生成了四个实现方法。
package com.blog.personalblog.service.Impl; import com.blog.personalblog.entity.User; import com.blog.personalblog.service.UserService; import org.springframework.stereotype.Service; import java.util.List; /** * 业务实现层 * * @author: SuperMan * 欢迎关注我的公众号:码上言 * @create: 2021-11-03 * */ @Service public class UserServiceImpl implements UserService { @Override public List<User> findAll() { return null; } @Override public void createUser(User user) { } @Override public void updateUser(User user) { } @Override public void deleteUser(int id) { } }
接下来我们去处理数据库接口的方法,我们需要四个对用户数据库操作的接口,接下来我们去处理Mapper
包,这个Mapper
包相当于dao
层。
4、数据库查询接口实现
在我们创建的Mapper
包中,创建一个UserMapper.java
接口。这里我们在传递参数的时候用了一个@Param注解,这个注解一般在传递多个条件的时候才使用,当然我们这里的业务没有那么复杂,一个条件的时候也可以使用,所以我们在这里使用下,扩宽知识了。
@Param注解的作用是给参数命名,参数命名后就能根据名字得到参数值,正确的将参数传入sql语句中(一般通过#{}的方式,${}会有sql注入的问题)。
package com.blog.personalblog.mapper; import com.blog.personalblog.entity.User; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; import java.util.List; /** * @author: SuperMan * 欢迎关注我的公众号:码上言 * @create: 2021-11-03 */ @Repository public interface UserMapper { /** * 查询全部用户信息 * * @return */ List<User> findAll(); /** * 添加用户 * @param user */ void insert(@Param("user") User user); /** * 更新用户 * @param user */ void update(@Param("user")User user); /** * 删除用户 * @param id * @return */ int delete(@Param("id")int id); }
此时,大家可能会看到在UserMapper类上多了一个@Repository注解,这个注解是干嘛的呢,@repository需要在Spring中配置扫描包地址,然后生成dao层的bean,之后被注入到ServiceImpl中,如果不加在实现类中引用了mapper类的来调用dao层的处理,使用@Autowired注解时被标红线,找不到bean。
加了这个之后,还需要在启动类上注解并加入Mapper包的地址,这样我们就可以正常的使用mapper接口了。
也可以使用@mapper,则不需要在springboot启动类上配置扫描地址,则是通过mapper.xml里面的namespace属性对应相关的mapper类,spring将动态的生成Bean后注入到ServiceImpl中。
5、编写数据库xml
我们在resources
文件下的mapper
文件夹中新建一个UserMapper.xml
文件,这里放的就是我们对数据库的操作,一些SQL语句。
此时,我们因为在UserMapper
类中用到的是@Repository
注入,所以我们要在启动类上加一个扫包的注解,去扫mapper
包的接口类。启动类完整代码:
package com.blog.personalblog; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.blog.personalblog.mapper") public class PersonalBlogApplication { public static void main(String[] args) { SpringApplication.run(PersonalBlogApplication.class, args); } }
下面开始编写xml
文件了。
具体的为啥要这样写我就不一一说了,官方文档有详细介绍。
Mybatis文档: https://mybatis.org/mybatis-3/sqlmap-xml.html#select然后开始写sql
语句,需要注意的是,sql
语句上的id
要和mapper
中的方法名一致。
UserMapper.xml
完整代码:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.blog.personalblog.mapper.UserMapper"> <resultMap id="BaseResultMap" type="com.blog.personalblog.entity.User"> <result column="id" jdbcType="INTEGER" property="id"/> <result column="username" jdbcType="VARCHAR" property="userName"/> <result column="password" jdbcType="VARCHAR" property="passWord"/> <result column="email" jdbcType="VARCHAR" property="email"/> <result column="last_login_time" jdbcType="TIMESTAMP" property="lastLoginTime"/> <result column="phone" jdbcType="VARCHAR" property="phone"/> <result column="nickname" jdbcType="VARCHAR" property="nickname"/> <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/> <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/> </resultMap> <select id="findAll" resultMap="BaseResultMap"> select * from person_user; </select> <insert id="insert" parameterType="com.blog.personalblog.entity.User" useGeneratedKeys="true" keyProperty="id"> INSERT INTO person_user (username, password, email, last_login_time, phone, nickname, create_time, update_time) VALUES(#{userName}, #{passWord}, #{email}, #{lastLoginTime}, #{phone}, #{nickname}, #{createTime}, #{updateTime}) </insert> <update id="update" parameterType="com.blog.personalblog.entity.User"> update person_user <set> username = #{userName}, password = #{passWord}, email = #{email}, last_login_time = #{lastLoginTime}, phone = #{phone}, nickname = #{nickname} </set> WHERE id = #{id} </update> <delete id="delete" parameterType="java.lang.Integer"> delete from person_user where id = #{id, jdbcType=INTEGER} </delete> </mapper>
数据库的接口已基本上完成,接下来还有实现类的方法的功能还没写,接下来返回到UserServiceImpl.java
类中,我们首先要引入Mapper
接口类。
@Autowired
注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。
@Autowired UserMapper userMapper;
接下来,我们就是用userMapper
去调用UserMapper
中功能的接口。
package com.blog.personalblog.service.Impl; import com.blog.personalblog.entity.User; import com.blog.personalblog.mapper.UserMapper; import com.blog.personalblog.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * 业务实现层 * * @author: SuperMan * 欢迎关注我的公众号:码上言 * @create: 2021-11-03 * */ @Service public class UserServiceImpl implements UserService { @Autowired UserMapper userMapper; @Override public List<User> findAll() { List<User> userList = userMapper.findAll(); return userList; } @Override public void createUser(User user) { userMapper.insert(user); } @Override public void updateUser(User user) { userMapper.update(user); } @Override public void deleteUser(int id) { userMapper.delete(id); } }
此时,到现在基本的业务功能全部完成了,但是我们查出来的数据如何暴露在外边呢,前面也说到了,我们这个是前后端分离的项目,也就是说我们后端的服务和前端后台管理的页面分开部署,所以就要通过接口来进行调用,每一个接口代表着某些功能的实现,所以下面我们开始编写Controller
层的代码。
6、编写接口层
在编写Controller
类之前,我们还要做一件事情,就是我们要封装一个返回类,用做我们返回数据的类型,统一设置返回格式方便前端调用。我在这里定义了一个返回类,以后所有的接口都会用这个返回类进行数据的返回和返回的错误信息供前端参考。
在我们建的util包中新建一个JsonResult.java
类,里面放入我们设置好统一的返回格式,返回的三个参数一个是返回数据、一个是错误码、另一个是错误信息。
JsonResult.java
完整代码:
package com.blog.personalblog.util; import java.io.Serializable; /** * @author: SuperMan * 欢迎关注我的公众号:码上言 * @create: 2021-11-06 */ public class JsonResult<T> implements Serializable { private static final long serialVersionUID = 1L; /** * 成功 */ public static final int SUCCESS = 200; /** * 失败 */ public static final int error = 500; private int code; private String msg; private T data; public static <T> JsonResult<T> success() { return jsonResult(null, SUCCESS, "操作成功"); } public static <T> JsonResult<T> success(T data) { return jsonResult(data, SUCCESS, "操作成功"); } public static <T> JsonResult<T> error() { return jsonResult(null, error, "操作失败"); } public static <T> JsonResult<T> error(String msg) { return jsonResult(null, error, msg); } public static <T> JsonResult<T> error(T data) { return jsonResult(data, error, "操作失败"); } private static <T> JsonResult<T> jsonResult(T data, int code, String msg) { JsonResult<T> result = new JsonResult<>(); result.setCode(code); result.setData(data); result.setMsg(msg); return result; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public T getData() { return data; } public void setData(T data) { this.data = data; } }
然后在controller
包中新建一个UserController.java
类,然后引入我们的Userservice
类,实现业务接口的调用。
UserController.java
完整代码:
package com.blog.personalblog.controller; import com.blog.personalblog.util.JsonResult; import com.blog.personalblog.entity.User; import com.blog.personalblog.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.util.List; /** * @author: SuperMan * 欢迎关注我的公众号:码上言 * @create: 2021-11-03 */ @RestController @RequestMapping("/user") public class UserController { @Autowired UserService userService; /** * 用户列表 * @return */ @PostMapping("/list") public JsonResult<Object> list() { List<User> userList = userService.findAll(); return JsonResult.success(userList); } /** * 添加用户 * @return */ @PostMapping("/create") public JsonResult<Object> userCreate(@RequestBody @Valid User user) { userService.createUser(user); return JsonResult.success(); } /** * * 修改用户 * @return */ @PostMapping("/update") public JsonResult<Object> userUpdate(@RequestBody @Valid User user) { userService.updateUser(user); return JsonResult.success(); } /** * 删除 * @return */ @PostMapping("/delete/{id}") public JsonResult<Object> userDelete(@PathVariable(value = "id") int id) { userService.deleteUser(id); return JsonResult.success(); } }
以上的代码我们用到了很多的注解,我再之前的注解文章中写写了好多,这里我就介绍这两个注解。
● @RequestBody:主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的)
● @Valid:用于验证注解是否符合要求,直接加在变量user之前,在变量中添加验证信息的要求,当不符合要求时就会在方法中返回message 的错误提示信息。
在我们用@Valid注解时,需要添加依赖,如下所示,将依赖添加到pom.xml中。
<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version> </dependency>
好啦,到此用户中心基础的功能已经实现,但是还有好多工作没有做,写是写完了,现在能不能通过接口进行数据操作呢,用户密码加密存储等操作,后面我们在慢慢的完善接口,这篇幅有点长,留到下篇我们再测试接口。好啦,最近比较忙,更新的比较慢,大家多多理解。
上一篇:Spring Boot + vue-element 开发个人博客项目实战教程(七、创建数据库表)