springboot專案整合-註冊功能模組開發

2022-11-03 06:01:53

工程簡介

準備工作:專案所用到的html介面以及sql檔案連結如下:連結: https://pan.baidu.com/s/18loHJiKRC6FI6XkoANMSJg?pwd=nkz2 提取碼: nkz2 複製這段內容後開啟百度網路硬碟手機App,操作更方便哦

第一步:註冊功能的實現

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 需要考慮上述的兩個注意點

package com.cy.store.mapper;

import com.cy.store.pojo.User;

/**
 * 使用者模組的持久化層介面
 */
public interface UserMapper {
    /**
     * 插入使用者的資料->用來實現註冊功能
     * @param user
     * @return 受到影響的行數(增刪改查 )
     */
    Integer insert(User user);

    /**
     * 根據使用者名稱查詢使用者的資料
     * @param username
     * @return  如果找到了則返回相對應的使用者資訊,找不到返回null
     */
    User findByUsername(String username);

}

1.1.3 編寫對映

1.定義xml對映檔案,與對應的介面進行關聯.所有餓對映檔案需要放置在resource目錄下,一般為了方便管理,一般在這個目錄下建立一個mapper資料夾,然後在找這個資料夾存放相應的mapper 檔案
2.建立介面的對應的對映檔案,規則:和介面的名稱保持一致即可,建立一個UserMapper.xml

1.1.4 單元測試

1.每個獨立的層編寫完畢需要編寫單元測試方法,來測試當前的功能, 在test包下建立一個mapper包
包:test-com.cy.store.mapper.UserMapperTest

package com.cy.store.mapper;

import com.cy.store.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * @PROJECT_NAME: store
 * @DESCRIPTION:
 * @USER: 28416
 * @DATE: 2022/11/2 16:43
 */
@Slf4j
@SpringBootTest
public class UserMapperTest {
    /**
     *  在mapper方法上加上這個註解: @Repository
     */
    @Autowired
    private  UserMapper userMapper;

    /**
     * @Dat 2022年11月2日17:25:41
     * 測試成功
     */
    @Test
    public void insert(){
        User user = new User();
        user.setUsername("tom");
        user.setPassword("123456");
        Integer insert = userMapper.insert(user);
        log.info("插入返回的值:{}",insert);

    }

    /**
     * @Date 2022年11月2日17:27:25
     * @return  查詢的結果為:User(uid=1, username=tom, password=123456, salt=null, phone=null, email=null, gender=null, avatar=null, isDelete=null)
     * 測試成功
     */
    @Test
    public void testFindByUsername(){
        User tom = userMapper.findByUsername("tom");
        log.info("查詢的結果為:{}",tom);
    }
}

1.2註冊功能-業務層

1.2.1 規劃異常

1.runtimeException異常,作為這個異常的子類,然後在定義具體的異常型別來繼承這個異常,業務層異常的基礎類別
serviceException異常,這個異常繼承RuntimeException異常,以此建立異常的機制。

2.使用者在進行註冊時候可能會產生使用者名稱被佔用的錯誤,丟擲一個異常 UsernameDuplicatedException

3.正在執行資料插入操作的時候,伺服器、資料庫宕機。處於正在執行插入的過程中,所產生的異常InsertException

1.2.2 設計介面和抽象方法

1.在service包下建立一個IUserService
2.設計一個實現類的包
3.實現類中重寫 註冊方法實現完全的使用者註冊邏輯

  @Override
    public void reg(User user) {
        //呼叫findByUsernam 方法  判斷使用者名稱是否被註冊過
        String username = user.getUsername();

        User byUsername = userMapper.findByUsername(username);
        if (byUsername != null){
            throw new UsernameDuplicatedException("使用者名稱被佔用");
        }
        
        Integer insert = userMapper.insert(user);
        if (insert != 1){
            throw  new InsertException("在使用者註冊中產生了位置的異常");
        }
    }

1.2.3 在單元測試中建立UserServiceTest類 進行相應的註冊邏輯進行測試

package com.cy.store.service;

import com.cy.store.pojo.User;
import com.cy.store.service.ex.ServiceException;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * @PROJECT_NAME: store
 * @DESCRIPTION:
 * @USER: 28416
 * @DATE: 2022/11/2 18:15
 */

@SpringBootTest
public class UserServiceTest {

    @Autowired
    private  IUserService userService;

    /**
     * @Date 2022年11月2日19:25:39
     * @return UsernameDuplicatedException
     * @return 測試使用者註冊的功能  成功返回1 or  返回自定義的exception
     * /
     * */

    @Test
    public void reg(){
        try {
            User user = new User();
            user.setUsername("Lux");
            user.setPassword("123456");
            userService.reg(user);
            System.out.println("ok");
        } catch (ServiceException e) {
            //獲取異常的類名
            System.out.println(e.getClass().getSimpleName());
            //列印錯誤資訊
            System.out.println(e.getMessage());
        }
    }
}


1.3控制層

1.3.1 建立響應

1.狀態碼、狀態描述資訊、資料,這部分功能封裝在一個類中,將這類方法作為方法返回值,返回給前端瀏覽器 com.cy.store.StoreApplication

1.3.2. 設計請求

依據當前的業務功能模組進行請求的設計

請求的路徑: /user/reg
請求引數: User user
請求型別: Post
響應結果:JsonResult<void>
1.3.3 處理請求

1.建立一個控制層的對應的類 UserController com.cy.store.controller.UserController

try {
            userService.reg(user);
            voidJsonResult.setState(200);
            voidJsonResult.setMessage("使用者註冊成功");
        } catch (UsernameDuplicatedException e) {
            voidJsonResult.setState(4000);
            voidJsonResult.setMessage("使用者名稱被佔用");
        }
        catch (InsertException e) {
            voidJsonResult.setState(5000);
            voidJsonResult.setMessage("註冊時發生未知的異常");
        }

業務邏輯過於複雜 進行簡化

1.3.4 控制層優化設計

在控制層抽離一個父類別,在這個父類別中統一的處理關於異常的相關操作,編寫一個BaseController類,在這個類中,統一的處理異常


package com.cy.store.controller;

import com.cy.store.service.ex.InsertException;
import com.cy.store.service.ex.ServiceException;
import com.cy.store.service.ex.UsernameDuplicatedException;
import com.cy.store.util.JsonResult;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
 * @PROJECT_NAME: store
 * @DESCRIPTION:
 * @USER: 28416
 * @DATE: 2022/11/2 20:34
 *
 * 用來表示控制層類的基礎類別
 *
 */
public class BaseController {


    public  static  final  int OK = 200;  //表示操作成功的狀態碼

    //請求處理方法,這個方法的返回值就是需要傳遞給前端的資料

    //當專案中產生異常時,會被攔截到此方法  這個方法此時充當的就是請求處理方法 方法的返回值直接給到前端
    @ExceptionHandler(ServiceException.class) // 主要用於統一處理丟擲的異常
    public JsonResult<Void> handleException(Throwable e){
        JsonResult<Void>   result = new JsonResult<>(e);
        if (e instanceof UsernameDuplicatedException){
            result.setState(4000);
            result.setMessage("使用者名稱已經被佔用");
        }else if (e instanceof InsertException){
            result.setState(5000);
            result.setMessage("註冊時發生未知的異常");
        }

        return  result;
    }
}

修改後的controller - userController 的程式碼如下;

@RestController
@RequestMapping("users")
public class UserController   extends  BaseController{

    @Autowired
    private IUserService userService;

    /**
     * 原先的程式碼
     *
     * @RequestMapping("reg")

    public JsonResult<Void> reg(User user){
        //建立結果響應物件
        JsonResult<Void> voidJsonResult = new JsonResult<>();
        try {
            userService.reg(user);
            voidJsonResult.setState(200);
            voidJsonResult.setMessage("使用者註冊成功");
        } catch (UsernameDuplicatedException e) {
            voidJsonResult.setState(4000);
            voidJsonResult.setMessage("使用者名稱被佔用");
        }
        catch (InsertException e) {
            voidJsonResult.setState(5000);
            voidJsonResult.setMessage("註冊時發生未知的異常");
        }

        return  voidJsonResult;
    }**/
    /**
     * 優化以後的程式碼
     * @param user
     * @return
     */
    @RequestMapping("reg")
    public JsonResult<Void> reg(User user) {
        userService.reg(user);

        return new JsonResult<>(OK);
    }
}

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

1.4前端頁面的設計

1.在register頁面中編寫傳送請求的方法,後端接收方法為reg,當檢測中點選事件後觸發請求--》 點選事件

 選擇對應的按鍵(%(「選擇器」)),再去新增點選的事件,$.ajax()函數傳送非同步請求額

2.JQuery封裝了一個函數,稱為$.ajax()函數,通過物件呼叫ajax函數,可以非同步的載入一個請求,依靠的是JAVAScript提供的一個xhr(xmlHttpResponse),封裝了這個物件

3.ajax()使用方法: 需要傳遞一個方法體作為一個方法的引數使用:一對大括號被稱為方法體.ajax接收多個引數,引數之間要求使用","進行分割,每一組引數之間使用":"進行分割
。引數的組成部分一個是引數的名稱(不能隨意更改),引數的值要求是用字串來標識。引數的宣告順序沒有要求 。語法結構如下:


$.ajax({
    url: "",
    type: "",
    dataType: "",
    success: function() {
      
    },
    error:function() {
      
    }
});

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標籤中

註冊功能實現完成