[網頁五子棋][用戶模塊]數據庫設計和配置(MyBatis)、約定前后端交互接口、服務器開發

文章目錄

  • 數據庫
    • 數據庫設計
    • 配置 MyBatis
      • 1. Spring 配置
      • 2. 創建實體類
      • 3. 創建 Mapper 接口
      • 4. 使用 MyBatis
  • 約定前后端交互接口
    • 登錄接口
    • 注冊接口
    • 獲取用戶信息
  • 服務器開發
    • login
    • register
    • getUserInfo
    • 完整代碼

數據庫

數據庫設計

完成注冊登錄以及用戶分數管理

  • 使用數據庫來保存上述用戶信息

創建 java_gobang 數據庫, user 表,表示用戶信息和分數信息

create database if not exists java_gobang;  use java_gobang;  drop table if exists user;  
create table user (  userId int primary key auto_increment,  username varchar(50) unique,  password varchar(50),  score int,         -- 天梯積分  totalCount int,    -- 比賽總場數  winCount int       -- 獲勝場數  
);  insert into user values (null, 'zhangsan', '123', 1000, 0, 0);  
insert into user values (null, 'lisi', '123', 1000, 0, 0);  
insert into user values (null, 'wangwu', '123', 1000, 0, 0);

配置 MyBatis

使用 MyBatis 來連接并操作我們的數據庫

1. Spring 配置

修改 Spring 的配置文件,使用數據庫可以被連接上

spring:  application:  name: java_gobang  datasource:  url: jdbc:mysql://127.0.0.1:3306/java_gobang?characterEncoding=utf8&useSSL=false  username: root  password: 20230153018  driver-class-name: com.mysql.cj.jdbc.Driver  mybatis:  mapper-locations: classpath:mapper/**Mapper.xml
  • 如果 driver-class-name 報錯,可能是沒有引入 Maven 依賴的原因

2. 創建實體類

創建一個實體類:用戶

package org.example.model;  public class User {  private int userId;  private String username;  private String password;  private int score;  private int totalCount;  private int winCount;  public int getUserId() {  return userId;  }  public void setUserId(int userId) {  this.userId = userId;  }  public String getUsername() {  return username;  }  public void setUsername(String username) {  this.username = username;  }  public String getPassword() {  return password;  }  public void setPassword(String password) {  this.password = password;  }  public int getScore() {  return score;  }  public void setScore(int score) {  this.score = score;  }  public int getTotalCount() {  return totalCount;  }  public void setTotalCount(int totalCount) {  this.totalCount = totalCount;  }  public int getWinCount() {  return winCount;  }  public void setWinCount(int winCount) {  this.winCount = winCount;  }  
}

3. 創建 Mapper 接口

package org.example.model;  /**  * 接口里面創建一些典型的方法  */  
public interface UserMapper {  // 往數據庫中插入一個用戶,用于注冊功能  void insert(User user);  // 根據用戶名,來查詢用戶的詳細信息,用于登錄功能  User selectByName(String userName);  
}

4. 使用 MyBatis

實現 MyBatis 的相關 xml 配置文件,來自動實現數據庫操作

實現 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="org.example.java_gobang.model.UserMapper">  <insert id="insert">  insert into user values(null, #{username}, #{password}, 1000, 0, 0);  </insert>  <select id="selectByName" resultType="org.example.java_gobang.model.User">  select * from user where username = #{username};  </select>  
</mapper>

約定前后端交互接口

登錄接口

請求:

  • POST /login HTTP/1.1
  • Content-Type: application/x-222-form-urlencoded
  • username=zhangsan&password=123

響應:

  • HTTP/1.1 200 OK
  • Content-Type: application/json
    {
    userId: 1,
    username: ‘zhangsan’,
    score: 1000,
    totalCount: 0,
    winCount: 0
    }
  • 如果登錄失敗,就返回一個無效的 user 對象
    • 比如,這里的每個屬性都是空著的,像 userId => 0

注冊接口

請求:

  • POST /register HTTP/1.1
  • Content-Type: application/x-www-form-urlencoded
  • username=zhangsan&password=123

響應:

  • HTTP/1.1 200 OK
  • Content-Type: application/json
    {
    userId: 1,
    username: ‘zhangsan’,
    score: 1000,
    totalCount: 0,
    winCount: 0
    }

前后端交互的接口,在約定的時候,是有很多種交互方式的

  • 這里約定好了之后,后續的后端/前端代碼,都要嚴格地遵守這個約定來寫代碼

獲取用戶信息

從服務器獲取到當前登錄用戶的信息

  • 程序運行過程中,用戶登錄了之后,讓客戶端隨時通過這個接口,來訪問服務器,獲取到自身的信息

請求:

  • GET /userInfo HTTP/1.1

響應:

  • HTTP/1.1 200 OK
  • COntent-Type: application/json
    {
    userId: 1,
    username: ‘zhangsan’,
    score: 1000,
    totalCount: 0,
    winCount: 0
    }

服務器開發

創建 api.UserAPI 類,主要實現三個方法:

  • login:用來實現登錄邏輯
  • register:用來實現注冊邏輯
  • getUserInfo:用來實現登錄成功后顯示用戶分數的信息

login

在登錄的時候,我們要做的關鍵操作就是:

  • 根據用戶傳進來的 username,去數據庫里面查一下,看查到的結果能不能和傳入進來的 password 匹配
    • 匹配:登陸成功
    • 不匹配:登錄失敗
@PostMapping("/login")  
@ResponseBody  
public Object login(String username, String password, HttpServletRequest req) {  // 關鍵操作,就是根據 username 去數據庫中進行查找,  // 如果能找到匹配的用戶,并且密碼也一直,就認為登錄成功  User user = userMapper.selectByName(username); System.out.println("[login] username=" + username);  if (user == null || !user.getPassword().equals(password)) {  // 登錄失敗  System.out.println("登錄失敗!");  return new User();  }  HttpSession httpSession = req.getSession(true);  httpSession.setAttribute("user", user);  return user;  
}
  • HttpServletRequest:可以通過這個對象獲取或創建 Session,以及訪問其他 HTTP 屬性
  • getSession(true)
    • 如果當前請求中沒有帶上已有的 Session ID,或者 Session 已過期,就會創建一個新的 HttpSession 對象
    • 如果存在有效的 Session,會返回當前 Session
  • getSession(false)
    • 如果當前請求沒有有效的 Session,會返回 null,不會創建新的 Session
  • httpSession.setAttribute("user", user)
    • Session 保存一項屬性,鍵是 “user”,值是當前登錄的用戶對象
    • 保存后,在接下來的任何請求中,只要該用戶帶著同一個 Session ID(通常通過 cookie 自動攜帶),就能取出這個對象

register

@PostMapping("/register")  
@ResponseBody  
public Object register(String username, String password) {  try {  User user = new User();  user.setUsername(username);  user.setPassword(password);  userMapper.insert(user);  return user;  }catch (org.springframework.dao.DuplicateKeyException e) {  User user = new User();  return user;  }  
}
  • } catch (org.springframework.dao.DuplicateKeyException e) {
    • 如果數據庫表中設置了 username 為唯一索引(UNIQUE),當插入一個已存在的用戶名時會拋出此異常
    • 這個異常來自 SpringDataAccessException 系列,專門處理數據庫層的錯誤

getUserInfo

@GetMapping("/userInfo")  
@ResponseBody  
public Object getUserInfo(HttpServletRequest req) {  try {  HttpSession httpSession = req.getSession(false);  User user = (User) httpSession.getAttribute("user");  return user;  }catch (NullPointerException e) {  return new User();  }  
}

完整代碼

package org.example.java_gobang.api;  import jakarta.annotation.Resource;  
import jakarta.servlet.http.HttpServletRequest;  
import jakarta.servlet.http.HttpSession;  
import org.example.java_gobang.model.User;  
import org.example.java_gobang.model.UserMapper;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.PostMapping;  
import org.springframework.web.bind.annotation.ResponseBody;  
import org.springframework.web.bind.annotation.RestController;  @RestController  
public class UserAPI{  @Resource  private UserMapper userMapper;  @PostMapping("/login")  @ResponseBody  public Object login(String username, String password, HttpServletRequest req) {  // 關鍵操作,就是根據 username 去數據庫中進行查找,  // 如果能找到匹配的用戶,并且密碼也一直,就認為登錄成功  User user = userMapper.selectByName(username);  System.out.println("[login] username=" + username);  if (user == null || !user.getPassword().equals(password)) {  // 登錄失敗  System.out.println("登錄失敗!");  return new User();  }  HttpSession httpSession = req.getSession(true);  httpSession.setAttribute("user", user);  return user;  }  @PostMapping("/register")  @ResponseBody  public Object register(String username, String password) {  try {  User user = new User();  user.setUsername(username);  user.setPassword(password);  userMapper.insert(user);  return user;  }catch (org.springframework.dao.DuplicateKeyException e) {  User user = new User();  return user;  }  }  @GetMapping("/userInfo")  @ResponseBody  public Object getUserInfo(HttpServletRequest req) {  try {  HttpSession httpSession = req.getSession(false);  User user = (User) httpSession.getAttribute("user");  return user;  }catch (NullPointerException e) {  return new User();  }  }  
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/84691.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/84691.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/84691.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Qt/C++學習系列之列表使用記錄

Qt/C學習系列之列表使用記錄 前言列表的初始化界面初始化設置名稱獲取簡單設置 單元格存儲總結 前言 列表的使用主要基于QTableWidget控件&#xff0c;同步使用QTableWidgetItem進行單元格的設置&#xff0c;最后可以使用QAxObject進行單元格的數據讀出將數據進行存儲。接下來…

防火墻通常可以分為哪些類型?

防火墻是目前保護網絡安全的重要設備&#xff0c;能夠通過監控、過濾和控制進出網絡的數據流量&#xff0c;來保護內部網絡不會受到未經授權的IP地址進行訪問和惡意的網絡威脅&#xff0c;設置防火墻能夠幫助企業確保網絡的安全性&#xff0c;同時防火墻也會根據不同的功能來劃…

基于GeoTools的道路相交多個點容差冗余計算實戰

目錄 前言 一、關于道路相交 1、相交四個點 2、點更多的情況 二、基于距離的相交點去重 1、冗余距離計算 2、調用過程 3、去重后的結果 三、總結 前言 在地理信息系統&#xff08;GIS&#xff09;領域&#xff0c;道路網絡數據的處理與分析一直是關鍵課題。隨著城市化進…

android:foregroundServiceType詳解

在 Android 中&#xff0c;foregroundServiceType 是用于聲明前臺服務類型的屬性&#xff0c;主要從 Android 10&#xff08;API 29&#xff09;開始引入&#xff0c;并在 Android 11&#xff08;API 30&#xff09;及更高版本 中進一步細化。以下是所有可用的 foregroundServi…

React+Taro 微信小程序做一個頁面,背景圖需貼手機屏幕最上邊覆蓋展示

話不多說 直接上圖 第一步 import { getSystemInfoSync } from tarojs/taro;第二步 render() {const cardBanner getImageUrlByGlobal(member-merge-bg.png);const { safeArea, statusBarHeight } getSystemInfoSync();const NAV_BAR_HEIGHT 44;const navBarHeight NAV…

從零開始的云計算生活——番外,實戰腳本。

目錄 題目一&#xff1a;系統信息收集腳本 題目二&#xff1a;用戶管理配置腳本 題目三&#xff1a;磁盤空間管理腳本 題目四&#xff1a;網絡配置檢查腳本 題目五&#xff1a;系統日志分析腳本 題目一&#xff1a;系統信息收集腳本 編寫一個腳本名為 collect_system_info…

MySQL基礎知識(DDL、DML)

什么是數據庫&#xff1f; 數據庫&#xff1a;英文為 DataBase&#xff0c;簡稱DB&#xff0c;它是存儲和管理數據的倉庫。 注釋&#xff1a; 單行注釋&#xff1a;-- 注釋內容 或 # 注釋內容(MySQL特有)多行注釋&#xff1a; /* 注釋內容 */ 分類 SQL語句根據其功能被分為…

用volatile修飾數組代表什么意思,Java

文章目錄 volatile 修飾數組引用的含義volatile 對數組元素無效總結 如何讓數組元素也具有 volatile 特性&#xff1f; 當用 volatile 關鍵字修飾一個數組時&#xff0c;它只保證數組引用的可見性和部分原子性&#xff0c;而不保證數組元素的可見性和原子性。 換句話說&#x…

Ubuntu 24.04 LTS 長期支持版發布:對服務器用戶意味著什么?新特性、升級建議與性能影響初探

更多云服務器知識&#xff0c;盡在hostol.com 在服務器運維的廣闊世界里&#xff0c;每一次主流操作系統長期支持&#xff08;LTS&#xff09;版本的發布&#xff0c;都無異于一次重要的“時代交替”。它不僅帶來了一系列令人矚目的技術革新&#xff0c;更重要的是&#xff0c…

題目 3241: 藍橋杯2024年第十五屆省賽真題-挖礦

題目 3241: 藍橋杯2024年第十五屆省賽真題-挖礦 時間限制: 3s 內存限制: 512MB 提交: 1267 解決: 224 題目描述 小藍正在數軸上挖礦&#xff0c;數軸上一共有 n 個礦洞&#xff0c;第 i 個礦洞的坐標為 ai 。小藍從 0 出發&#xff0c;每次可以向左或向右移動 1 的距離&#xf…

vue3+ts+vite創建的后臺管理系統筆記

Vue3+ Vite + Element-Plus + TypeScript 從0到1搭建企業級后臺管理系統(前后端開源):參考有來科技學習搭建項目 創建項目bug匯總,知識點src 路徑別名配置和tsconfig.json文件報錯【這個不配置好,會引起其他頁面引用時報錯:見--整合 Pinia】:整合 Pinia 【參考-- src 路徑…

指針01 day13

十三&#xff1a;指針變量 一&#xff1a;數據類型 ? 指針類型---------對應處理的數據是指針 (地址)這種數據 ? 整型類型---------對應處理的數據是整數這種類型 二&#xff1a;定義指針類型的變量 ? 語法&#xff1a; 基類型&#xff08;1&#xff09; *&#xff08;…

基于深度學習的智能文本生成:從模型到應用

前言 隨著人工智能技術的飛速發展&#xff0c;自然語言處理&#xff08;NLP&#xff09;領域取得了顯著的進展。其中&#xff0c;智能文本生成技術尤其引人注目。從聊天機器人到內容創作&#xff0c;智能文本生成不僅能夠提高效率&#xff0c;還能創造出令人驚嘆的內容。本文將…

Oracle業務用戶的存儲過程個數及行數統計

Oracle業務用戶的存儲過程個數及行數統計 統計所有業務用戶存儲過程的個數獨立定義的存儲過程定義在包里的存儲過程統計所有業務用戶存儲過程的總行數獨立定義的存儲過程定義在包里的存儲過程通過DBA_SOURCE統計類型個數和代碼行數?? 對存儲過程進行統計主要用到以下三個系統…

多線程安全:核心解決方案全解析

在多線程環境下保證共享變量的線程安全,需解決原子性、可見性、有序性三大問題。以下是核心解決方案及適用場景: 一、同步鎖機制(互斥訪問) synchronized 關鍵字 原理:通過 JVM 監視器鎖(Monitor)確保同一時間僅一個線程訪問臨界區。示例:public class Counter {privat…

2025-06-01-Hive 技術及應用介紹

Hive 技術及應用介紹 參考資料 Hive 技術原理Hive 架構及應用介紹Hive - 小海哥哥 de - 博客園https://cwiki.apache.org/confluence/display/Hive/Home(官方文檔) Apache Hive 是基于 Hadoop 構建的數據倉庫工具&#xff0c;它為海量結構化數據提供類 SQL 的查詢能力&#xf…

Python爬蟲(52)Scrapy-Redis分布式爬蟲架構實戰:IP代理池深度集成與跨地域數據采集

目錄 一、引言&#xff1a;當爬蟲遭遇"地域封鎖"二、背景解析&#xff1a;分布式爬蟲的兩大技術挑戰1. 傳統Scrapy架構的局限性2. 地域限制的三種典型表現 三、架構設計&#xff1a;Scrapy-Redis 代理池的協同機制1. 分布式架構拓撲圖2. 核心組件協同流程 四、技術實…

HashMap真面目

背景 今天數據采集項目碰到一個性能問題&#xff0c;3000多個采集點&#xff0c;每一個采集點每秒送一個數據&#xff0c;接收到數據之后首先需要內存中做緩存&#xff0c;之后有一系列的業務分析處理&#xff0c;所以&#xff0c;對系統性能要求比較高。 最近幾天發現服務器…

STM32CubeMX-H7-19-ESP8266通信(中)--單片機控制ESP8266實現TCP地址通信

前言 上篇文章我們已經能夠使用串口助手實現esp8266的幾種通信&#xff0c;接下來我們使用單片機控制實現。這篇文章會附帶教程&#xff0c;增加.c和,.h&#xff0c;把串口和定時器放到對應的編號&#xff0c;然后調用初始化就可以使用了。 先講解&#xff0c;然后末尾再放源碼…

歐盟RED網絡安全標準EN 18031-2的要求

歐盟RED網絡安全標準EN 18031-2的要求 歐盟RED網絡安全標準EN 18031-2的要求 ? 適用產品范圍&#xff1a; 能夠處理個人隱私數據的可聯網無線電設備。 不具備聯網能力的三類無線電設備&#xff1a;玩具、兒童護理類設備、可穿戴類設備。 主要測試與評估內容&#xff1a; EN…