五子棋双人对战项目(2)——登录模块
目录
一、数据库模块
1、创建数据库
2、使用MyBatis连接并操作数据库
编写后端数据库代码
二、约定前后端交互接口
三、后端代码编写
文件路径如下:
UserAPI:
UserMapper:
四、前端代码
登录页面 login.html:
注册页面 register.html:
一、数据库模块
1、创建数据库
数据库中存放的是用户信息,其中用户信息包含用户ID、用户名、用户密码、用户天梯分数、用户对战场数,用户胜场数。
根据上述信息,写SQL语句:
create database if not exists java_gobang;use java_gobang;drop table if exists use;create table user (user_id int primary key auto_increment,user_name varchar(50) unique, --用户名,不能重复password varchar(50),score int, --用户天梯积分total_count int, --总场数win_count 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, "admin", "123", 1000, 0, 0);
运行这些代码,查询是否创建成功。
2、使用MyBatis连接并操作数据库
加入依赖
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency>
配置yml文件,连接本地数据库:
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/java_gobang?characterEncoding=utf8&useSSL=falseusername: rootpassword: 1234driver-class-name: com.mysql.cj.jdbc.Drivermybatis:# 配置 mybatis xml 的⽂件路径,在 resources/mybatis 创建所有表的 xml ⽂件mapper-locations: classpath:mapper/*Mapper.xmlconfiguration: # 配置打印 MyBatis日志log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true #配置驼峰自动转换
编写后端数据库代码
登录接口:根据用户名,查询数据库中的用户信息,校验密码是否正确
注册模块:根据用户名 和 密码,往数据库中插入新的用户信息。
先创建一个用户类:
@Data
public class UserInfo {private Integer userId;private String userName;private String password;private Integer score;//用户天梯积分private Integer totalCount;//总场数private Integer winCount;//胜场数
}
使用MyBatis操作数据库:
@Mapper
public interface UserMapper {//根据用户名,查询用户的详情信息,用于登录功能@Select("select * from user where user_name = #{userName}")UserInfo selectByName(String userName);//往数据库里插入信息,用于注册功能@Insert("insert into user values (null, #{userName}, #{password}, 1000, 0, 0);")Integer insert(UserInfo userInfo);
}
二、约定前后端交互接口
登录:
注册:
从服务器获取到当前登录的用户信息:
(程序运行过程中,用户登录了之后,让客户端随时通过这个接口,来访问服务器,获取到自身的信息)
三、后端代码编写
文件路径如下:
UserAPI:
@RestController
public class UserAPI {@Autowiredprivate UserMapper userMapper;@PostMapping("/login")@ResponseBodypublic Object login(String username, String password, HttpServletRequest req) {//如果用户名或密码为空,就直接返回空的User对象if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {return new User();}User user = userMapper.selectByName(username);//在数据库里查询不到这个用户名,或者有这个用户,但密码错误if(user == null || !user.getPassword().equals(password)) {return new User();}//建立会话,true的含义,如果当前有session,就直接使用当前的session,如果没有,就创建一个HttpSession httpSession = req.getSession(true);//把当前user保存到这个会话中httpSession.setAttribute("user", user);return user;}@PostMapping("/register")public Object register(String username, String password) {//注册时,用户可能没输入用户名或密码if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {return new User();}try {User user = new User();user.setUsername(username);user.setPassword(password);userMapper.register(user);return user;} catch (org.springframework.dao.DuplicateKeyException e) {//可能会有重复的用户名return new User();}}@GetMapping("/userInfo")@ResponseBodypublic Object getUserInfo(HttpServletRequest req) {try {//拿到当前的session,false的含义:如果当前已经有session了,就使用该session,如果没有,也不会创建新的sessionHttpSession httpSession = req.getSession(false);//从当前的session拿到用户信息User user = (User) httpSession.getAttribute("user");//把当前信息返回给客户端return user;} catch (NullPointerException e) {//可能当前用户没有登录,所以session可能会为空、return new User();}}
}
UserMapper:
@Mapper
public interface UserMapper {//根据用户名,查询用户的详情信息,用于登录功能@Select("select * from user where user_name = #{username}")User selectByName(String username);//往数据库里插入信息,用于注册功能@Insert("insert into user values (null, #{username}, #{password}, 1000, 0, 0);")void register(User userInfo);
}
四、前端代码
登录页面 login.html:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>登录</title><link rel="stylesheet" href="css/common.css"><link rel="stylesheet" href="css/login.css">
</head><body><div class="nav">五子棋对战</div><div class="login-container"><!-- 登录界面的对话框 --><div class="login-dialog"><!-- 提示信息 --><h3>登录</h3><!-- 这个表示一行 --><div class="row"><span>用户名</span><input type="text" id="username"></div><!-- 这个表示另一行 --><div class="row"><span>密码</span><input type="password" id="password"></div><!-- 提交按钮 --><div class="row"><button id="submit">登录</button></div></div></div><script src="./js/jquery.min.js"></script><script>let usernameInput = document.querySelector("#username");let passwordInput = document.querySelector("#password");let submitButton = document.querySelector("#submit");//点击提交按钮的事件submitButton.onclick = function () {$.ajax({type: "post",url: "/login",data: {username: usernameInput.value,password: passwordInput.value},success: function (body) {//请求执行成功的回调函数//判断当前是否登录成功//如果返回的对象是User,那么就是登录成功//如果返回的对象是空的User,那么就是登录失败if(body && body.userId > 0) {//登录成功//重定向跳转到 “游戏大厅页面”location.assign('/game_hall.html');} else {//登录失败alert("登录失败");}},error: function (body) {//请求执行失败的回调函数alert("登录失败");}});}</script>
</body></html>
注册页面 register.html:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>注册</title><link rel="stylesheet" href="css/common.css"><link rel="stylesheet" href="css/login.css">
</head><body><div class="nav">五子棋对战</div><div class="login-container"><!-- 注册界面的对话框 --><div class="login-dialog"><!-- 提示信息 --><h3>注册</h3><!-- 这个表示一行 --><div class="row"><span>用户名</span><input type="text" id="username"></div><!-- 这个表示另一行 --><div class="row"><span>密码</span><input type="password" id="password"></div><!-- 提交按钮 --><div class="row"><button id="submit">注册</button></div></div></div><script src="./js/jquery.min.js"></script><script>let usernameInput = document.querySelector("#username");let passwordInput = document.querySelector("#password");let submitButton = document.querySelector("#submit");//点击提交按钮的事件submitButton.onclick = function () {$.ajax({type: "post",url: "/register",data: {username: usernameInput.value,password: passwordInput.value},success: function (body) {//请求执行成功的回调函数//判断当前是否登录成功//如果返回的对象是User,那么就是登录成功//如果返回的对象是空的User,那么就是登录失败if(body && body.username) {//登录成功alert("注册成功");//重定向跳转到 “游戏大厅页面”location.assign('/login.html');} else {//登录失败alert("注册失败");}},error: function (body) {//请求执行失败的回调函数alert("注册失败");}});}</script>
</body></html>
相关文章:

五子棋双人对战项目(2)——登录模块
目录 一、数据库模块 1、创建数据库 2、使用MyBatis连接并操作数据库 编写后端数据库代码 二、约定前后端交互接口 三、后端代码编写 文件路径如下: UserAPI: UserMapper: 四、前端代码 登录页面 login.html: 注册页面…...
几种操作系统和几种cpu
常见的操作系统:windows,linux,macOS,统信,deepin,raspberry,andriod,iOS,鸿蒙,等等。 常见的cpu:intel,amd,龙芯&#x…...

[Cocoa]_[初级]_[使用NSNotificationCenter作为目标观察者实现时需要注意的事项]
场景 在开发Cocoa程序时,由于界面是用Objective-C写的。无法使用C的目标观察者[1]类。如果是使用第二种方案2[2],那么也需要增加一个代理类。那么有没有更省事的办法? 说明 开发界面的时候,经常是需要在子界面里传递数据给主界面࿰…...

彩虹易支付最新版源码及安装教程(修复BUG+新增加订单投诉功能)
该源码当前版本为较新的版本,新增了订单投诉功能和一套精美的二次元模板。 此版本为全开源版本,所有文件均未加密。系统默认安装完成后无法直接打开,需要进一步配置。 本站特别针对BUG文件进行了修复,且在PHP7.4环境下表现良好。…...
ping香港服务器超时的原因通常有哪些?
Ping命令用于测试计算机与目标服务器之间的网络连接。当您在尝试使用ping命令检测服务器时遇到超时的情况,通常可能是由以下原因造成的: 1. 网络连接问题: - 本地网络故障:如网线损坏、路由器故障或配置不当。 - ISP(互联网服务提…...

书生大模型实战(从入门到进阶)L3-彩蛋岛-InternLM 1.8B 模型 Android 端侧部署实践
目录 1 环境准备 1.1 安装rust 1.2 安装Android Studio 1.3 设置环境变量 2 转换模型 2.1 安装mlc-llm 2.2 (可选)转换参数 2.3 (可选)生成配置 2.4 (可选)上传到huggingface 2.5 (可选) 测试转换的模型 3 打包运行 3.1 修改配置文件 3.2 运行打包命令 3.3 创建签…...
setState是同步更新还是异步更新
setState是同步更新还是异步更新 先说结论setState为什么设计为异步react18之前为什么不确定是同步还是异步呢react18之后setState有哪些改动 先说结论 React18之前:使用了ReactDOM.render,setState在React调度流程中是异步更新,在原生事件和…...
TCP 流量控制 - 滑动窗口和拥塞控制算法解析
滑动窗口主要管理数据流动的速率,对单个连接较好,拥塞控制则防止网络出现过载,对提高整体的网络通畅较好。下面详细解析两者的原理和作用。 1. TCP 滑动窗口算法 TCP 使用滑动窗口机制来控制数据的发送和接收,以实现流量控制&…...

MongoDB聚合操作及索引底层原理
目录 链接:https://note.youdao.com/ynoteshare/index.html?id=50fdb657a9b06950fa255a82555b44a6&type=note&_time=1727951783296 本节课的内容: 聚合操作: 聚合管道操作: 编辑 $match 进行文档筛选 编辑 将筛选和投影结合使用: 编辑 多条件匹配: …...

C++ | Leetcode C++题解之第454题四数相加II
题目: 题解: class Solution { public:int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {unordered_map<int, int> countAB;for (int u: A) {for (int v: B) {count…...

【从零开始实现stm32无刷电机FOC】【实践】【7.2/7 完整代码编写】
目录 stm32cubemx配置芯片选择工程配置stm32基础配置SPI的配置定时器的配置ADC的配置中断优先级的配置生成工程 工程代码编写FOC代码结构搭建电机编码器角度读取PWM产生FOC开环代码编写确定电机正负旋转方向电机旋转速度计算多圈逻辑角度电流采样极对数转子角度确定 闭环控制控…...

谷歌收录查询工具,谷歌收录查询工具的使用指南
谷歌收录查询工具是网站管理员和SEO专业人士用于检查网站是否被谷歌搜索引擎收录及其收录情况的重要辅助手段。以下是一些常用的谷歌收录查询工具及其详细使用指南: 一、Google Search Console(谷歌搜索控制台) 简介: Google Sea…...
vue3 拖拽插件(drag)
前端vue项目中,经常会有弹框拖拽的需求,下面介绍常用方法: 1.如果你使用的是elementPlus插件的el-dialog组件,只需要增加draggable属性即可,代码如下: <el-dialogv-model"showDiloag"width"500&quo…...

数据结构--线性表(顺序结构)
1.线性表的定义和基本操作 1.1线性表以及基本逻辑 1.1.1线性表 (1)n(>0)个数据元素的有限序列,记作(a1,a2,...an),其中ai是线性表中的数据元素,n是表的长度。 (2)…...
面试准备111
Java基础 反射 集合 多线程 Synchronized/volatile 线程池 cas atomic 网络 tcp 三次握手/四次挥手 流量控制 拥塞控制 数据结构 算法 Spring 循环依赖 Mybatis 如何防止sql注入 Mysql 索引 索引分类 索引设计原则 事务 四种隔离级别 MVCC 日志 Binlog…...
Spring 的 IOC 和 AOP 是什么,有哪些优点?解密 Spring两大核心概念:IOC与AOP的魅力所在
在现代Java开发中,Spring框架几乎是不可或缺的存在。它不仅简化了开发过程,还提高了软件的灵活性和可维护性。今天,我们要深入探讨Spring中的两个核心概念:IOC(控制反转)和AOP(面向切面编程&…...
第二百六十四节 JPA教程 - JPA查询日期参数示例
JPA教程 - JPA查询日期参数示例 我们可以在查询中使用日期类型值。 以下代码使用EntityManager创建具有两个参数的查询。 然后它传递两个日期类型值。 em.createQuery("SELECT e " "FROM Professor e " "WHERE e.startDate BETWEEN :start AND :en…...

Spring MVC的运行流程详解
Spring MVC作为一个广泛使用的框架,提供了灵活且强大的MVC架构支持。尤其在业务系统中,Spring MVC能够有效地处理大量并发请求,提供良好的用户体验。本文将详细讲解Spring MVC的运行流程,以电商交易系统为案例,帮助读者…...

判断有向图是否为单连通图的算法
判断有向图是否为单连通图的算法 算法描述伪代码C语言实现解释在图论中,单连通图(singly connected graph)是指对于图中的任意两个顶点 m 和 v,如果存在从 m 到 v 的路径,则该路径是唯一的。为了判断一个有向图是否为单连通图,我们需要确保从任意顶点出发,到任意其他顶点…...

php与python建站的区别有哪些
php与Python建站的区别: 1、语言层面Python的特性比php好,更加规范。 2、Python的性能比php高。 3、有只需要启动服务的时候执行一次的代码,在php里每个请求都会被执行一次,Python不需要。虽然php可以通过缓存缩短这方面的差距…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...

高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...

从零开始了解数据采集(二十八)——制造业数字孪生
近年来,我国的工业领域正经历一场前所未有的数字化变革,从“双碳目标”到工业互联网平台的推广,国家政策和市场需求共同推动了制造业的升级。在这场变革中,数字孪生技术成为备受关注的关键工具,它不仅让企业“看见”设…...

内窥镜检查中基于提示的息肉分割|文献速递-深度学习医疗AI最新文献
Title 题目 Prompt-based polyp segmentation during endoscopy 内窥镜检查中基于提示的息肉分割 01 文献速递介绍 以下是对这段英文内容的中文翻译: ### 胃肠道癌症的发病率呈上升趋势,且有年轻化倾向(Bray等人,2018&#x…...
虚幻基础:角色旋转
能帮到你的话,就给个赞吧 😘 文章目录 移动组件使用控制器所需旋转:组件 使用 控制器旋转将旋转朝向运动:组件 使用 移动方向旋转 控制器旋转和移动旋转 缺点移动旋转:必须移动才能旋转,不移动不旋转控制器…...