• 【springboot项目详解】springboot项目整合-注册功能模块开发


    第一步:注册功能的实现

    1.1持久层的设计

    1.1.1规范需要执行的SQL语句

    1.用户的注册工作,相当于在做数据的插入操作

    insert  into t_user (username,password) values (?,?)
    

    2.在用户的注册是首先需要查询当前的用户名是否存在,如果存在则不能进行注册,相当于一个查询语句

    select * from t_user where username = ?
    

    1.1.2设计接口和抽象方法

    定义mapper接口,在项目的目录结构下首先创建一个mapper包,在这个包下根据不同的功能模块来创建mapper接口
    1.创建一个userMapper 需要考虑上述的两个注意点

    1. package com.cy.store.mapper;
    2. import com.cy.store.pojo.User;
    3. /**
    4. * 用户模块的持久化层接口
    5. */
    6. public interface UserMapper {
    7. /**
    8. * 插入用户的数据->用来实现注册功能
    9. * @param user
    10. * @return 受到影响的行数(增删改查 )
    11. */
    12. Integer insert(User user);
    13. /**
    14. * 根据用户名查询用户的数据
    15. * @param username
    16. * @return 如果找到了则返回相对应的用户信息,找不到返回null
    17. */
    18. User findByUsername(String username);
    19. }

    1.1.3 编写映射

    1.定义xml映射文件,与对应的接口进行关联.所有饿映射文件需要放置在resource目录下,一般为了方便管理,一般在这个目录下创建一个mapper文件夹,然后在找这个文件夹存放相应的mapper 文件
    2.创建接口的对应的映射文件,规则:和接口的名称保持一致即可,创建一个UserMapper.xml

    1.1.4 单元测试

    1.每个独立的层编写完毕需要编写单元测试方法,来测试当前的功能, 在test包下创建一个mapper包
    包:test-com.cy.store.mapper.UserMapperTest

    1. package com.cy.store.mapper;
    2. import com.cy.store.pojo.User;
    3. import lombok.extern.slf4j.Slf4j;
    4. import org.junit.jupiter.api.Test;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.boot.test.context.SpringBootTest;
    7. /**
    8. * @PROJECT_NAME: store
    9. * @DESCRIPTION:
    10. * @USER: 28416
    11. * @DATE: 2022/11/2 16:43
    12. */
    13. @Slf4j
    14. @SpringBootTest
    15. public class UserMapperTest {
    16. /**
    17. * 在mapper方法上加上这个注解: @Repository
    18. */
    19. @Autowired
    20. private UserMapper userMapper;
    21. /**
    22. * @Dat 2022年11月2日17:25:41
    23. * 测试成功
    24. */
    25. @Test
    26. public void insert(){
    27. User user = new User();
    28. user.setUsername("tom");
    29. user.setPassword("123456");
    30. Integer insert = userMapper.insert(user);
    31. log.info("插入返回的值:{}",insert);
    32. }
    33. /**
    34. * @Date 2022年11月2日17:27:25
    35. * @return 查询的结果为:User(uid=1, username=tom, password=123456, salt=null, phone=null, email=null, gender=null, avatar=null, isDelete=null)
    36. * 测试成功
    37. */
    38. @Test
    39. public void testFindByUsername(){
    40. User tom = userMapper.findByUsername("tom");
    41. log.info("查询的结果为:{}",tom);
    42. }
    43. }

    1.2注册功能-业务层

    1.2.1 规划异常

    1.runtimeException异常,作为这个异常的子类,然后在定义具体的异常类型来继承这个异常,业务层异常的基类
    serviceException异常,这个异常继承RuntimeException异常,以此建立异常的机制。

    2.用户在进行注册时候可能会产生用户名被占用的错误,抛出一个异常 UsernameDuplicatedException

    3.正在执行数据插入操作的时候,服务器、数据库宕机。处于正在执行插入的过程中,所产生的异常InsertException

    1.2.2 设计接口和抽象方法

    1.在service包下创建一个IUserService
    2.设计一个实现类的包
    3.实现类中重写 注册方法实现完全的用户注册逻辑

    1. @Override
    2. public void reg(User user) {
    3. //调用findByUsernam 方法 判断用户名是否被注册过
    4. String username = user.getUsername();
    5. User byUsername = userMapper.findByUsername(username);
    6. if (byUsername != null){
    7. throw new UsernameDuplicatedException("用户名被占用");
    8. }
    9. Integer insert = userMapper.insert(user);
    10. if (insert != 1){
    11. throw new InsertException("在用户注册中产生了位置的异常");
    12. }
    13. }

    1.2.3 在单元测试中创建UserServiceTest类 进行相应的注册逻辑进行测试

    1. package com.cy.store.service;
    2. import com.cy.store.pojo.User;
    3. import com.cy.store.service.ex.ServiceException;
    4. import org.junit.jupiter.api.Test;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.boot.test.context.SpringBootTest;
    7. /**
    8. * @PROJECT_NAME: store
    9. * @DESCRIPTION:
    10. * @USER:
    11. * @DATE: 2022/11/2 18:15
    12. */
    13. @SpringBootTest
    14. public class UserServiceTest {
    15. @Autowired
    16. private IUserService userService;
    17. /**
    18. * @Date 2022年11月2日19:25:39
    19. * @return UsernameDuplicatedException
    20. * @return 测试用户注册的功能 成功返回1 or 返回自定义的exception
    21. * /
    22. * */
    23. @Test
    24. public void reg(){
    25. try {
    26. User user = new User();
    27. user.setUsername("Lux");
    28. user.setPassword("123456");
    29. userService.reg(user);
    30. System.out.println("ok");
    31. } catch (ServiceException e) {
    32. //获取异常的类名
    33. System.out.println(e.getClass().getSimpleName());
    34. //打印错误信息
    35. System.out.println(e.getMessage());
    36. }
    37. }
    38. }

    1.3控制层

    1.3.1 创建响应

    1.状态码、状态描述信息、数据,这部分功能封装在一个类中,将这类方法作为方法返回值,返回给前端浏览器 com.cy.store.StoreApplication

    1.3.2. 设计请求

    依据当前的业务功能模块进行请求的设计

    1. 请求的路径: /user/reg
    2. 请求参数: User user
    3. 请求类型: Post
    4. 响应结果:JsonResult<void>

    1.3.3 处理请求

    1.创建一个控制层的对应的类 UserController com.cy.store.controller.UserController

    1. try {
    2. userService.reg(user);
    3. voidJsonResult.setState(200);
    4. voidJsonResult.setMessage("用户注册成功");
    5. } catch (UsernameDuplicatedException e) {
    6. voidJsonResult.setState(4000);
    7. voidJsonResult.setMessage("用户名被占用");
    8. }
    9. catch (InsertException e) {
    10. voidJsonResult.setState(5000);
    11. voidJsonResult.setMessage("注册时发生未知的异常");
    12. }

    业务逻辑过于复杂 进行简化

    1.3.4 控制层优化设计

    在控制层抽离一个父类,在这个父类中统一的处理关于异常的相关操作,编写一个BaseController类,在这个类中,统一的处理异常

    1. package com.cy.store.controller;
    2. import com.cy.store.service.ex.InsertException;
    3. import com.cy.store.service.ex.ServiceException;
    4. import com.cy.store.service.ex.UsernameDuplicatedException;
    5. import com.cy.store.util.JsonResult;
    6. import org.springframework.web.bind.annotation.ExceptionHandler;
    7. /**
    8. * @PROJECT_NAME: store
    9. * @DESCRIPTION:
    10. * @USER:
    11. * @DATE: 2022/11/2 20:34
    12. *
    13. * 用来表示控制层类的基类
    14. *
    15. */
    16. public class BaseController {
    17. public static final int OK = 200; //表示操作成功的状态码
    18. //请求处理方法,这个方法的返回值就是需要传递给前端的数据
    19. //当项目中产生异常时,会被拦截到此方法 这个方法此时充当的就是请求处理方法 方法的返回值直接给到前端
    20. @ExceptionHandler(ServiceException.class) // 主要用于统一处理抛出的异常
    21. public JsonResult<Void> handleException(Throwable e){
    22. JsonResult<Void> result = new JsonResult<>(e);
    23. if (e instanceof UsernameDuplicatedException){
    24. result.setState(4000);
    25. result.setMessage("用户名已经被占用");
    26. }else if (e instanceof InsertException){
    27. result.setState(5000);
    28. result.setMessage("注册时发生未知的异常");
    29. }
    30. return result;
    31. }
    32. }

    修改后的controller - userController 的代码如下;

    1. @RestController
    2. @RequestMapping("users")
    3. public class UserController extends BaseController{
    4. @Autowired
    5. private IUserService userService;
    6. /**
    7. * 原先的代码
    8. *
    9. * @RequestMapping("reg")
    10. public JsonResult<Void> reg(User user){
    11. //创建结果响应对象
    12. JsonResult<Void> voidJsonResult = new JsonResult<>();
    13. try {
    14. userService.reg(user);
    15. voidJsonResult.setState(200);
    16. voidJsonResult.setMessage("用户注册成功");
    17. } catch (UsernameDuplicatedException e) {
    18. voidJsonResult.setState(4000);
    19. voidJsonResult.setMessage("用户名被占用");
    20. }
    21. catch (InsertException e) {
    22. voidJsonResult.setState(5000);
    23. voidJsonResult.setMessage("注册时发生未知的异常");
    24. }
    25. return voidJsonResult;
    26. }**/
    27. /**
    28. * 优化以后的代码
    29. * @param user
    30. * @return
    31. */
    32. @RequestMapping("reg")
    33. public JsonResult<Void> reg(User user) {
    34. userService.reg(user);
    35. return new JsonResult<>(OK);
    36. }
    37. }

    妙不可言!!!!!!!!!!

    1.4前端页面的设计

    1.在register页面中编写发送请求的方法,后端接收方法为reg,当检测中点击事件后触发请求--》 点击事件

     选择对应的按键(%(“选择器”)),再去添加点击的事件,$.ajax()函数发送异步请求额
    

    2.JQuery封装了一个函数,称为$.ajax()函数,通过对象调用ajax函数,可以异步的加载一个请求,依靠的是JAVAScript提供的一个xhr(xmlHttpResponse),封装了这个对象

    3.ajax()使用方法: 需要传递一个方法体作为一个方法的参数使用:一对大括号被称为方法体.ajax接收多个参数,参数之间要求使用","进行分割,每一组参数之间使用":"进行分割
    。参数的组成部分一个是参数的名称(不能随意更改),参数的值要求是用字符串来标识。参数的声明顺序没有要求 。语法结构如下:

    1. $.ajax({
    2. url: "",
    3. type: "",
    4. dataType: "",
    5. success: function() {
    6. },
    7. error:function() {
    8. }
    9. });

    4.ajax函数参数的含义

    url : 标识请求的地址(url地址)。不能包括列表部分的内容 例如: url:"localhost:8080/users/reg"

    type: 请求类型(GET 和 POST 请求类型) 例如: type:"POST"

    data: 向指定的请求url地址提交的数据: 例如: data:"username="tom"&password="123456""

    dataType:提交的数据的类型 例如:"json"

    success:当服务器正常响应客户端时,将会自动调用success方法,并且将服务器返回的数据以参数的形式传递给这个方法的参数上

    error:当服务器异常响应客户端时,将会自动调用error方法,并且将服务器返回的数据以参数的形式传递给这个方法的参数上

    5.js代码可以独立声明在一个js的文件里或者声明在一个script标签中

    注册功能实现完成

  • 相关阅读:
    慢SQL排查定位
    【Opencv工程开发所用类】VideoTracker 视频摄像头
    面试:“谈谈ArrayList和LinkdeList之间的区别?”,究竟有多少人回答错了?该怎么回答?
    HTML中的<!DOCTYPE html>和JavaScript中的strict mode
    国庆周《LInux学习第四课》
    【架构】五大常见架构模式,集中式架构、分布式架构、面向服务的系统架构、微服务架构等区别详解
    对比鸿蒙,Google 的 Fuchsia 当前进度如何?
    基于Effect的组件设计 | 京东云技术团队
    深度学习(PyTorch)——torchvision中的数据集使用方法
    python中那些常见的@装饰器
  • 原文地址:https://blog.csdn.net/wufaqidong1/article/details/127660549