当前位置:   article > 正文

Spring Boot + vue-element 开发个人博客项目开发(六、用户中心功能实现)_用户中心项目

用户中心项目

前面用了六节内容把项目的项目配置,项目日志、项目管理以及数据库建立起来了。

用户中心主要是我们对账号的管理,用户登录账号等,现在暂时不做权限角色的管理,只是先做一个角色的用户登录。

一、引入Lombok

1. 为什么要引入lombok

在本项目中我们要使用Lombok注解,可以帮我们省略大量重复代码编写工作,正所谓:任何技术的出现都是为了解决某一类问题,我们在学习基础的时候应该都学过getter/setter/to String在数据封装就会用到这些,这些代码都是可以通过快捷键一键生成的,会使一个类中出现大量无含量的代码,然而使用Lombok可以让我们将这些代码省略掉,只需要加一个注解即可,这就是现在开发中常用到的

2. 引入相应的Maven包

  1. <dependency>
  2. <groupId>org.projectlombok</groupId>
  3. <artifactId>lombok</artifactId>
  4. <version>1.18.22</version>
  5. </dependency>

pom.xml中添加这个依赖,

3. 添加IDEA对Lombok的支持

依赖添加完成之后,我们要在IDEA中安装Lombok这个插件,方便我们的开发,使得我们开发工具去支持这个功能

点击项目的File -> Settings

打开,点击Plugins ,在搜索框中搜索Lombok,点击Install进行安装,安装后点击Apply,再点击OK

Lombok组件安装完成之后,可能需要 重启一下IDEA

4. Lombok注解的使用

我们最早用到的是@Date注解,里面有@Getter/@Setter,具体的等会使用的时候进行具体讲解。

二、用户的功能实现增删改查

首先实现用户列表的功能,这个就是从数据库中捞出数据,在后台页面上展示即可,这里的查找就会用到分页的功能,虽然是我们自己的管理,没几个账号,就不适用分页了,我们会在文章管理功能页面使用分页。

用户中心添加的总目录参考:

1. 添加实体类

在项目personblog/entity下新建一个实体类,命名为Userji

 即在创建的entity包中创建一个User.java的实体类,

将数据进行封装,引入@Date注解

在类的上方添加一个@Date注解,这个注解就是我们刚刚引入的Lombok,可以帮我们省略@Getter/@Setter方法

  1. package com.blog.personblog.entity;
  2. import lombok.Data;
  3. import java.time.LocalDateTime;
  4. import java.util.Date;
  5. /**
  6. * 添加@Date注解
  7. */
  8. @Data
  9. public class User {
  10. /**
  11. * 主键id
  12. */
  13. private Integer id;
  14. /**
  15. * 用户名
  16. */
  17. private Integer userName;
  18. /**
  19. * 密码
  20. */
  21. private String passWord;
  22. /**
  23. * 邮箱
  24. */
  25. private String email;
  26. /**
  27. * 上次登录时间
  28. */
  29. private Date lastLoginTime;
  30. /**
  31. * 手机号
  32. */
  33. private Integer phone;
  34. /**
  35. * 昵称
  36. */
  37. private String nickname;
  38. /**
  39. * 创建时间
  40. */
  41. private LocalDateTime createTime;
  42. /**
  43. * 更新时间
  44. */
  45. private LocalDateTime updateTime;
  46. }

2. 添加业务接口

在我们创建的service包中,创建一个UserService.java类型,该类是一个接口类,将我们的业务功能暴露出去,可以供接口层调用

在包service处右键New ->  Java Class

选择Interface,填入接口名UserService

此类实现了用户增删改查功能接口, 其中增加、修改和删除只需要在接口层返回一个成功或者失败的信息即可,不需要返回信息

  1. package com.blog.personblog.service;
  2. import com.blog.personblog.entity.User;
  3. import java.util.List;
  4. public interface UserService {
  5. /**
  6. * 查询所有用户列表
  7. * @return
  8. */
  9. List<User> findAll();
  10. /**
  11. * 添加用户
  12. * @param user
  13. */
  14. void createUser(User user);
  15. /**
  16. * 修改用户
  17. * @param user
  18. */
  19. void updateUser(User user);
  20. /**
  21. * 修改用户
  22. * @param id
  23. */
  24. int deleteUser(int id);
  25. }

3. 添加业务接口实现类

实现类则实现了业务接口这个功能,继承这个接口,具体的业务逻辑都会在这个类中写,很重要,同时和数据库接口相连,进行调用数据库的接口,实现数据处理。

在创建的lmplNew -> Java Class,命名为UserServiceImpl.java,同时继承UserService接口,用关键字implements去实现继承接口,

生成 UserServiceImpl.java文件,

使用关键字 implements 实现接口,添加具体的实现类

然后按快捷键 Alt+Enter,勾选implements methods实现方法

 弹出一个弹出框,里面就是在UserService.java中创建的方法,然后点击OK,

就生成了四个具体的重写方法

  1. package com.blog.personblog.service.Impl;
  2. import com.blog.personblog.entity.User;
  3. import com.blog.personblog.service.UserService;
  4. import org.springframework.stereotype.Service;
  5. import java.util.List;
  6. /**
  7. * 四个重写方法
  8. *
  9. */
  10. @Service
  11. public class UserServiceImpl implements UserService {
  12. @Override
  13. public List<User> findAll() {
  14. return null;
  15. }
  16. @Override
  17. public void createUser(User user) {
  18. }
  19. @Override
  20. public void updateUser(User user) {
  21. }
  22. @Override
  23. public int delete(int id) {
  24. return 0;
  25. }
  26. }

 4. 数据库查询接口实现

在我们创建的Mapper包中,创建一个UserMapper.java接口

这里我们在传递参数时用了一个@param注解,这个注解一般在传递多个参数条件才使用。

  1. /**
  2. * 多条件参数下一般使用@param注解
  3. *
  4. */
  5. int updateByExampleSelective(@Param("record") AccessRecord record, @Param("example") AccessRecordExample example);
  6. /**
  7. * 单条件参数下一般不使用@param注解
  8. *
  9. */
  10. int updateByPrimaryKey(AccessRecord record);

我们这里业务没这么复杂,不涉及到多个参数,但我们也使用一下,作为扩展

@Param的主要作用就是给参数命名,参数命名后就能根据参数得到参数值,正确得将参数传入sql语句中,(一般通过#{} 得方式,${}会有sql注入问题)

mapper包右键 -> New -> Java Class 

选择Interface命名为UserMapper.java

  1. package com.blog.personblog.mapper;
  2. import com.blog.personblog.entity.User;
  3. import org.apache.ibatis.annotations.Param;
  4. import org.springframework.stereotype.Repository;
  5. import java.util.List;
  6. @Repository
  7. public interface UserMapper {
  8. /**
  9. * 查询全部用户信息
  10. *
  11. * @return
  12. */
  13. List<User> findAll();
  14. /**
  15. * 添加用户
  16. * @param user
  17. */
  18. void create(@Param("user") User user);
  19. /**
  20. * 修改用户
  21. * @param user
  22. */
  23. void update(@Param("user") User user);
  24. /**
  25. * 删除用户
  26. * @param id
  27. */
  28. int delete(@Param("id") int id);
  29. }

 可以看到,在UserMapper类上多了一个@Repository注解,

作用@Repository是需要在Spring中配置扫描包地址,然后生成dao层的bean,之后被注入ServiceImpl中,如果不加在实现类中引用了mapper层的类来调用dao层的处理,使用@Autowired注解被标红线,找不到bean

加了这个之后,还需要在启动类上注解并加上Mapper包的地址,这样我们就可以正常使用mapper接口了,

也可以使用@Mapper注解,用了就不需要在启动类上配置扫描地址,则是通过mapper.xml中的namespace对应相关的mapper类,Spring将动态的生成Bean后注入ServiceImpl

 5. 编写数据库的xml

在上面,我们在Mapper层中用的是@Repository注解,所以我们要在启动类上加一个扫描包的注解,去扫描Mapper包的接口类。

启动类:

  1. package com.blog.personblog;
  2. import org.mybatis.spring.annotation.MapperScan;
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5. @SpringBootApplication
  6. /**
  7. * 添加扫描包
  8. */
  9. @MapperScan("com.blog.personblog.mapper")
  10. public class PersonBlogApplication {
  11. public static void main(String[] args) {
  12. SpringApplication.run(PersonBlogApplication.class, args);
  13. }
  14. }

我们在resource下的mapper文件夹中新建一个UserMapper.xml文件,这里放的就是一些对数据库的操作,一些SQL语句,

下面开始编写xml文件

之所以这样写可以看看官方文档的解释:https://mybatis.org/mybatis-3/sqlmap-xml.html#select 

  • <ResultMap>标签中放的是数据表里的字段和实体类中属性名的映射
  • property放的是属性名

然后开始写sql语句,注意sql中的id要和mapper中的方法名一致 

如果在写sql语句的过程中,表名和相关属性都爆红,点击右侧的Database是空白的,说明数据库没有导入,

 点击+号,点击Data Source ,点击MySQL

填写建立数据库就设立好的用户名和密码,填入表名称,点击Apply,点击OK

这时再点击Database就会有相应的表格出现了,也就不会爆红了

  • @Param的主要作用就是给参数命名,参数命名后就能根据参数得到参数值,正确得将参数传入sql语句中,(一般通过#{} 得方式,${}会有sql注入问题)
  • 在这里就用到了 #{}
  • mybatis 非常的智能,如果配置了resultMap,返回值统一使用 resultMap=“BaseResultMap”,mybatis会根据查询到的条目数量自动进行判断,如果是一条就返回对象,如果是多条就返回List对象列表
  • useGeneratedKeys =true 这个表示插入数据之后返回一个自增的主键id给你对应实体类中的主键属性。通过这个设置可以解决在主键自增的情况下通过实体的getter方法获取主键(当然还需要keyproperty指明数据库中返回的主键id给实体类中的哪个属性)。
  • keyproperty=主键,这样就可以解决在主键自增的情况下获取主键。
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.blog.personblog.mapper.UserMapper">
  6. <resultMap id="BaseResultMap" type="com.blog.personblog.entity.User">
  7. <result column="id" jdbcType="INTEGER" property="id"/>
  8. <result column="username" jdbcType="VARCHAR" property="userName"/>
  9. <result column="password" jdbcType="VARCHAR" property="passWord"/>
  10. <result column="email" jdbcType="VARCHAR" property="email"/>
  11. <result column="last_login_time" jdbcType="TIMESTAMP" property="lastLoginTime"/>
  12. <result column="phone" jdbcType="VARCHAR" property="phone"/>
  13. <result column="nickname" jdbcType="VARCHAR" property="nickname"/>
  14. <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
  15. <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
  16. </resultMap>
  17. <!--select标签代表查 -->
  18. <select id="findAll" resultMap="BaseResultMap">
  19. select * from person_user;
  20. </select>
  21. <!--insert 标签代表增 -->
  22. <insert id="insert" parameterType="com.blog.personblog.entity.User" useGeneratedKeys="true" keyProperty="id">
  23. INSERT INTO person_user (username, password, email, last_login_time, phone, nickname, create_time, update_time)
  24. VALUES (#{userName}, #{passWord}, #{email}, #{lastLoginTime}, #{phone}, #{nickname}, #{createTime}, #{updateTime})
  25. </insert>
  26. <!--update 标签代表改 -->
  27. <update id="update" parameterType="com.blog.personblog.entity.User">
  28. update person_user
  29. <set>
  30. username=#{userName},
  31. password=#{passWord},
  32. email=#{email},
  33. last_login_time=#{lastLoginTime},
  34. phone=#{phone},
  35. nickname=#{nickname},
  36. </set>
  37. WHERE id = #{id}
  38. </update>
  39. <!--delete 标签代表删 -->
  40. <delete id="delete" parameterType="java.lang.Integer">
  41. delete from person_user where id = #{id,jdbcType=INTEGER}
  42. </delete>
  43. </mapper>

 数据库的接口基本上已经完成了,

还有接口实现类Impl没写,接下来回到UserServiceImpl.java中,我们首先要引入Mapper接口类

使用@Autowired注解,它可以对类成员变量,方法,及构造函数进行标注,完成自动装配工作

  1. @Autowired
  2. UserMapper userMapper;

利用@Autowired引入Mapper然后用userMapper去调用UserMapper中的功能的接口

  1. package com.blog.personblog.service.Impl;
  2. import com.blog.personblog.entity.User;
  3. import com.blog.personblog.mapper.UserMapper;
  4. import com.blog.personblog.service.UserService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Service;
  7. import java.util.List;
  8. /**
  9. * @Service注解用于类上,标记当前类是一个service类,加上该注解会将当前类自动注入到spring容器中
  10. *
  11. */
  12. @Service
  13. public class UserServiceImpl implements UserService {
  14. /**
  15. * 业务实现层
  16. *
  17. */
  18. @Autowired
  19. UserMapper userMapper;
  20. @Override
  21. public List<User> findAll() {
  22. /**
  23. *userMapper.findAll();
  24. * 调用UseMapper中的findALL方法
  25. */
  26. List<User> userList = userMapper.findAll();
  27. return userList;
  28. }
  29. @Override
  30. public void createUser(User user) {
  31. /**
  32. *userMapper.insert;
  33. * 调用UseMapper中的insert方法
  34. */
  35. userMapper.insert(user);
  36. }
  37. @Override
  38. public void updateUser(User user) {
  39. /**
  40. *userMapper.update;
  41. * 调用UseMapper中的insert方法
  42. */
  43. userMapper.update(user);
  44. }
  45. @Override
  46. public void deleteUser(int id) {
  47. /**
  48. *userMapper.delete;
  49. * 调用UseMapper中的delete方法
  50. */
  51. userMapper.delete(id);
  52. }
  53. }

到此,我们基本的业务逻辑功能都完成了,但是我们查出来的数据如何暴露在外面呢,前面说了,这是个前后端分离的项目,也就是我们后端的服务和前端后台管理页面分开部署,所以要通过接口来进行统一的调用,每一个接口代表一个功能的实现,

这些进行调用的接口写在Controller层中,

6. 编写Controller接口层

在编写Controller类之前,我们还需要做一件事,就是需要封装一个返回类,封装我们的返回类型,统一设置返回格式方便前端调用,在这里定义了一个返回类 ,以后所有的接口都会用这个返回类进行数据的返回和返回错误信息供前端参考

在我们建的util包中新建一个JsonResult.java类,

里面放我们设置好的统一的返回格式,返回的三个参数分别是:返回数据、错误码、错误信息

JsonResult.java完整代码

  1. package com.blog.personblog.util;
  2. import java.io.Serializable;
  3. public class JsonResult<T> implements Serializable {
  4. private static final long serialVersionUID = 1L;
  5. /**
  6. * 成功
  7. */
  8. public static final int SUCCESS = 200;
  9. /**
  10. * 失败
  11. */
  12. public static final int error = 500;
  13. /**
  14. * 返回数据
  15. */
  16. private int code;
  17. /**
  18. * 错误码
  19. */
  20. private String msg;
  21. /**
  22. * 错误信息
  23. */
  24. private T data;
  25. public static <T> JsonResult<T> success() {
  26. return jsonResult(null, SUCCESS, "操作成功");
  27. }
  28. public static <T> JsonResult<T> success(T data) {
  29. return jsonResult(data, SUCCESS, "操作成功");
  30. }
  31. public static <T> JsonResult<T> error() {
  32. return jsonResult(null, error, "操作失败");
  33. }
  34. public static <T> JsonResult<T> error(String msg) {
  35. return jsonResult(null, error, msg);
  36. }
  37. public static <T> JsonResult<T> error(T data) {
  38. return jsonResult(data, error, "操作失败");
  39. }
  40. private static <T> JsonResult<T> jsonResult(T data, int code, String msg) {
  41. JsonResult<T> result = new JsonResult<>();
  42. result.setCode(code);
  43. result.setData(data);
  44. result.setMsg(msg);
  45. return result;
  46. }
  47. /**
  48. * 通过 Alt + Insert 快捷键一键生成,Get/Set方法
  49. */
  50. public int getCode() {
  51. return code;
  52. }
  53. public void setCode(int code) {
  54. this.code = code;
  55. }
  56. public String getMsg() {
  57. return msg;
  58. }
  59. public void setMsg(String msg) {
  60. this.msg = msg;
  61. }
  62. public T getData() {
  63. return data;
  64. }
  65. public void setData(T data) {
  66. this.data = data;
  67. }
  68. }

然后在controller包中新建一个UserController类,通过注解@Autowired引入我们的UserService类,实现业务接口调用

先说一下其中可能会出现的小问题:

引入@Vaild注解爆红

 打开pom.xml添加依赖,添加完成点击刷新,添加成功后,再在爆红的位置,按快捷键Alt +Enter引入即可,

使用到了@PathVariable注解,具体的使用规则参考这位博主的文章:

(1条消息) @PathVariable注解的用法和作用(Demo详解)_辰兮要努力的博客-CSDN博客_pathvariable

UserController.java类完整代码

  1. package com.blog.personblog.controller;
  2. import com.blog.personblog.entity.User;
  3. import com.blog.personblog.service.UserService;
  4. import com.blog.personblog.util.JsonResult;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.web.bind.annotation.*;
  7. import javax.validation.Valid;
  8. import java.util.List;
  9. @RestController
  10. @RequestMapping("/user")
  11. public class UserController {
  12. @Autowired
  13. UserService userService;
  14. /**
  15. * 用户列表
  16. * @return
  17. */
  18. @PostMapping("/list")
  19. public JsonResult<Object> list() {
  20. /**
  21. * findALL有返回值,需要对应的变量来接收
  22. */
  23. List<User> userList = userService.findAll();
  24. return JsonResult.success(userList);
  25. }
  26. /**
  27. * 添加用户
  28. * @return
  29. */
  30. @PostMapping("/create")
  31. public JsonResult<Object> userCreate(@RequestBody @Valid User user ) {
  32. /**
  33. * createUser没有返回值,直接变量名.方法调用即可
  34. */
  35. userService.createUser(user);
  36. return JsonResult.success();
  37. }
  38. /**
  39. * 修改用户
  40. * @return
  41. */
  42. @PostMapping("/update")
  43. public JsonResult<Object> userUpdate(@RequestBody @Valid User user) {
  44. /**
  45. * updateUser没有返回值,直接变量名.方法调用即可
  46. */
  47. userService.updateUser(user);
  48. return JsonResult.success();
  49. }
  50. /**
  51. * 删除用户
  52. * @return
  53. */
  54. @PostMapping("/delete/{id}")
  55. public JsonResult<Object> userDelete(@PathVariable(value = "id") int id) {
  56. userService.deleteUser(id);
  57. return JsonResult.success();
  58. }
  59. }

以上的代码都使用了很多注解,

  • @RequestBody :主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据),
  • @Valid:用于验证注解是否符合要求,直接加在变量user之前,在变量中直接添加验证信息的要求,当不符合要求就会在方法中返回message中的错误提示信息。
  • 使用@Valid注解时候,需要在pom.xml中添加依赖
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-validation</artifactId>
  4. </dependency>

到这里,用户中心的基础功能已经基本实现,

记得提交代码到Gitee, 

总结了一下大概流程

  • 先构建实体类

  • 在构建Service层(接口),让业务功能暴露出去,可以供接口层调用

  • 构建ServiceImpl实现类,实现业务接口,重写实现类中的方法

  • 创建Mapper层接口,数据库查询接口实现

  • 在启动类中添加扫描包

  • 编写数据库的xml文件,Mapper.xml

  • 回到Impl实现类,在ServiceImpl中利用@Autowired注解引入mapper,进行调用mapper中的方法,及mapper中的功能的接口

注:Mapper接口类的方法名和ServiceImpl实现类中的方法名尽量不要一样,

  • 封装一个返回类,用于封装我们的返回类型,统一设置返回格式方便前端调用

  • 新建Controller类,引入Service层,实现业务接口调用

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/113323
推荐阅读
相关标签
  

闽ICP备14008679号