当前位置: 首页 > article >正文

[网页五子棋][用户模块]数据库设计和配置(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();  }  }  
}

相关文章:

[网页五子棋][用户模块]数据库设计和配置(MyBatis)、约定前后端交互接口、服务器开发

文章目录 数据库数据库设计配置 MyBatis1. Spring 配置2. 创建实体类3. 创建 Mapper 接口4. 使用 MyBatis 约定前后端交互接口登录接口注册接口获取用户信息 服务器开发loginregistergetUserInfo完整代码 数据库 数据库设计 完成注册登录以及用户分数管理 使用数据库来保存上…...

maven编译时跳过test过程

如果代码里有无法在打包环境中测试的部分&#xff0c;则直接运行mvn clean package&#xff0c;因为测试失败&#xff0c;会导致打包失败。目前有两种方式可以跳过测试&#xff1a; 1. mvn clean package -DskipTests&#xff0c;这会跳过执行阶须&#xff0c;但仍会生成测试所…...

threejsPBR材质与纹理贴图

1. PBR材质简介 本节课没有具体的代码&#xff0c;就是给大家科普一下PBR材质&#xff0c;所谓PBR就是&#xff0c;基于物理的渲染(physically-based rendering)。 Three.js提供了两个PBR材质相关的APIMeshStandardMaterial和MeshPhysicalMaterial,MeshPhysicalMaterial是Mes…...

深兰科技董事长陈海波受邀出席2025苏商高质量发展(常州)峰会,共话AI驱动产业升级

5月29日&#xff0c;2025苏商高质量发展峰会在常州隆重开幕。本次峰会聚焦新质生产力培育与产业创新转型&#xff0c;汇聚了众多江苏省内知名企业家、专家学者及政府代表。深兰科技创始人、董事长陈海波作为人工智能领域的领军企业代表&#xff0c;受邀出席盛会并参与重要活动环…...

【计算机网络】子网划分

文章目录 【计算机网络】子网划分&#xff08;知识点详细&#xff09;一、子网划分基础概念1. **为什么需要子网划分&#xff1f;**2. **关键术语** 二、子网划分核心原理1. **借位规则**2. **子网划分步骤** 三、子网划分实战案例案例1&#xff1a;标准C类网划分&#xff08;等…...

Git入门到精通:30分钟掌握核心技巧

目录 一、基础理论片 Git简介 Git安装 Git仓库 Git基本命令用法 仓库别名 二、实操命令篇 远程分支 分支的新建和合并 实操演示 1 本地新建仓库 2 gitee新建仓库 3 建立关系 4 新建分支 5 开发新功能 6 推送新分支 7 合并新分支到主分支 三、可视化工具篇 G…...

Redis7底层数据结构解析

redisObject 在 Redis 的源码中&#xff0c;Redis 会将底层数据结构&#xff08;如 SDS、hash table、skiplist 等&#xff09;统一封装成一个对象&#xff0c;这个对象叫做 redisObject&#xff0c;也简称 robj。 typedef struct redisObject {unsigned type : 4; // 数…...

Android 异步编程中协程的完整实战示例

一、全链路数据加载&#xff1a;网络请求 数据库缓存 在实际开发中&#xff0c;数据加载通常需要先检查本地缓存&#xff0c;若缓存失效则从网络获取&#xff0c;并将结果更新到本地。以下是完整的 MVVM 架构示例&#xff1a; 1. 项目结构 app/ ├── data/ …...

多部手机连接同一wifi的ip一样吗?

在家庭和办公环境中&#xff0c;多台手机同时连接同一个WiFi路由器已成为常态。不少用户会产生疑问&#xff1a;这些设备的IP地址会相同吗&#xff1f;下面就一起来了解一下吧。 一、多部手机连接同一WiFi的IP‌一样吗 多部手机连接同一WiFi时的IP地址是否相同&#xff0c;需要…...

大语言模型值ollama使用(1)

ollama为本地调用大语言模型提供了便捷的方式。下面列举如何在windows系统中快捷调用ollama。 winR打开运行框&#xff0c;输入cmd 1、输入ollama list 显示已下载模型 2、输入ollama pull llama3 下载llama3模型 3、 输入 ollama run llama3 运行模型 4、其他 ollama li…...

大模型应用开发之Langchain

一、框架简述 Langchain 是一个用于构建和管理 LLM 应用的开发框架。它为开发者提供了工具和接口&#xff0c;以便于更轻松地将大语言模型集成到应用程序中&#xff0c;并处理语言模型生成的响应、管理对话状态、执行链式调用、处理多步任务等。 二、Langchain主要模块 1、M…...

thc-ssl-dos:SSL 压力测试的轻量级工具!全参数详细教程!Kali Linux教程!

简介 THC-SSL-DOS 是一款用于验证 SSL 性能的工具。 建立安全的 SSL 连接需要服务器比客户端高 15 倍的处理能力。 THC-SSL-DOS 利用这种不对称特性&#xff0c;通过使服务器过载并使其断网。 此问题影响当今所有 SSL 实现。供应商自 2003 年以来就已意识到这个问题&#x…...

什么是内网ip证书

内网IP证书是一种基于公钥基础设施&#xff08;PKI&#xff09;技术的数字证书&#xff0c;专门用于保护企业内部网络中通过IP地址访问服务的通信安全。以下是对内网IP证书的详细解析&#xff1a; 一、核心定义与用途 定义&#xff1a;内网IP证书是SSL/TLS证书的一种特殊类型…...

【速通RAG实战:进阶】17、AI视频打点全攻略:从技术实现到媒体工作流提效的实战指南

一、AI视频打点的技术底层与数据处理流程 (一)视频内容结构化的核心技术栈 AI视频打点的本质是将非结构化视频数据转化为带时间戳的结构化信息,其技术流程涵盖音视频处理、语音识别、自然语言处理三大核心模块,形成“数据采集-内容解析-智能标记-协同应用”的完整闭环。 …...

立控信息智能装备柜:科技赋能军队装备管理现代化

在军事装备管理领域&#xff0c;高效、安全、智能化的存储解决方案至关重要。传统的人工管理模式不仅效率低下&#xff0c;还容易因人为疏忽导致装备丢失或管理混乱。​LKONE智能装备柜凭借先进的物联网技术、生物识别安全系统和智能管理功能&#xff0c;为军队提供了一套高效、…...

【freertos-kernel】queue(发送)

文章目录 补充各种yeildTCB的xStateListItem和xEventListItem xQueueGenericSendprvCopyDataToQueueprvNotifyQueueSetContainervTaskInternalSetTimeOutStatevTaskSuspendAllxTaskResumeAllprvLockQueueprvUnlockQueueprvIncrementQueueTxLockvTaskPlaceOnEventListprvAddCurr…...

【华为云物联网】如何实现在 MQTT.fx 上模拟数据间隔上传一次,并按设定系数变动数据

虽然 MQTT.fx 本身不支持定时循环脚本发送消息,但可以通过以下方式 实现在 MQTT.fx 上模拟设备参数每隔 1 分钟上传一次,并按设定系数变动数据: ✅ 推荐方式:使用 Python 脚本+MQTT.fx 联动观察 你将用 Python 自动发送数据,MQTT.fx 订阅对应主题观察是否发送成功。 🧩…...

破解高原运维难题:分布式光伏智能监控系统的应用研究

安科瑞刘鸿鹏 摘要 高原地区光照资源丰富&#xff0c;具有发展分布式光伏发电的巨大潜力。然而&#xff0c;该地区复杂的气候环境、地形地貌和运维条件对光伏电站的运行与维护带来严峻挑战。本文结合Acrel1000DP分布式光伏监控系统的技术特点和典型应用案例&#xff0c;探讨其…...

图标变白,开始菜单栏无法打开程序(以jupyter为例)

不知道是本人删了一些东西导致的还是什么原因&#xff0c;总之现在本人的jupyter只能通过命令行打开&#xff0c;以往我是从开始菜单栏打开。琢磨了一段时间&#xff0c;发现是.ico文件没有了。重新在网上下载图片&#xff0c;用网站图片转 ico 图标 - 锤子在线工具 转换一下格…...

大语言模型(LLM)入门 - (1) 相关概念

文章来自&#xff1a;大语言模型(LLM)小白入门自学项目-TiaoYu-1 GitHub - tiaoyu1122/TiaoYu-1: For People! For Freedom!For People! For Freedom! Contribute to tiaoyu1122/TiaoYu-1 development by creating an account on GitHub.https://github.com/tiaoyu1122/TiaoYu…...

行为型:访问者模式

目录 1、核心思想 2、实现方式 2.1 模式结构 2.2 实现案例 3、优缺点分析 4、适用场景 1、核心思想 目的&#xff1a;数据结构稳定的情况下&#xff0c;解决数据与算法的耦合问题。适用于对象结构稳定但需频繁扩展操作的场景。 实现&#xff1a;在访问数据时根据数据类…...

C++数据结构 : 哈希表的实现

C数据结构 &#xff1a; 哈希表的实现 目录 C数据结构 &#xff1a; 哈希表的实现引言1. 哈希概念1.1 直接定址法1.2 哈希冲突1.3 负载因子 2. 哈希函数2.1 除法散列法/除留余数法2.2 乘法散列法&#xff08;了解&#xff09;2.3 全域散列法&#xff08;了解&#xff09; 3. 处…...

抖音电商客户端一面面经

抖音电商客户端一面面经 时间&#xff1a; 25.05.30 岗位&#xff1a; 抖音电商客户端开发工程师 形式&#xff1a; 技术一面 刚刚结束了字节跳动抖音电商客户端开发工程师岗位的技术一面&#xff0c;整体感觉考察范围非常全面&#xff0c;涵盖了基础、项目、算法、系统设计等…...

JavaScript 在 AcroForm 中的广泛应用

在Adobe表单(特别是SAP Interactive Forms by Adobe)中使用JavaScript的各种技巧和方法,下面这些代码片段可以帮助开发者更高效地处理表单逻辑和交互。 1. 获取数据内容 从上下文结构中获取数据 var LV_DATA = xfa.resolveNode("$record.IM_TEST.FIELDNAME").val…...

Socket编程之TCP套件字

基于的TCP套件字编程流程 1. Socket套接字 Socket是一个编程接口&#xff08;网络编程接口&#xff09;&#xff0c;是一种特殊的文件描述符&#xff08;write/read&#xff09;。Socket并不 仅限于TCP/IP Socket独立于具体协议的编程接口&#xff0c;这个接口位于TCP/IP四层…...

AD9268、AD9643调试过程中遇到的问题

Ad9268芯片 AD9268是一款双通道、16位、80 MSPS/105 MSPS/125 MSPS模数转换器(ADC)。AD9268旨在支持要求高性能、低成本、小尺寸和多功能的通信应用。双通道ADC内核采用多级差分流水线架构&#xff0c;集成输出纠错逻辑。每个ADC都具有宽带宽、差分采样保持模拟输入放大器&…...

Java-File类基本方法使用指南

Java-File类基本方法使用指南 一、File类基础概念1.1 什么是File类1.2 File类的构造函数 二、文件和目录的创建与删除2.1 创建文件 - createNewFile()2.2 创建目录 - mkdir() 和 mkdirs()2.3 删除文件或目录 - delete() 三、文件和目录的查询与判断3.1 存在性判断 - exists()3.…...

Python爬虫实战:研究PyQuery库相关技术

1. 引言 1.1 研究背景与意义 随着互联网的快速发展,网络上的数据量呈爆炸式增长。如何高效地从海量的网页数据中提取有价值的信息,成为当前信息技术领域的一个重要研究方向。网络爬虫作为一种自动获取网页内容的程序,能够按照一定的规则,自动地抓取万维网信息,在搜索引擎…...

第九篇:MySQL 安全加固与访问控制策略实战

数据库的安全不仅仅是防止外部入侵&#xff0c;更包括合理配置账户权限、日志审计、网络加密、配置加固等。本文将系统性梳理 MySQL 的安全机制与实战加固方法&#xff0c;助你构建安全可靠的数据库运行环境。 一、数据库安全风险面 数据库常面临的威胁&#xff1a; 弱口令或默…...

神经网络-Day40

目录 单通道图片的规范写法图像任务中的张量形状NLP任务中的张量形状1. **Flatten操作**2. **view/reshape操作** 总结彩色图片的规范写法 图像数据的格式以及模型定义的过程&#xff0c;和之前结构化数据的略有不同&#xff0c;主要差异体现在2处 模型定义的时候需要展平图像由…...