[网页五子棋][用户模块]数据库设计和配置(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
insert into user values(null, #{username}, #{password}, 1000, 0, 0); select * from user where username = #{username};
约定前后端交互接口
登录接口
请求:
- 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),当插入一个已存在的用户名时会抛出此异常
- 这个异常来自 Spring 的 DataAccessException 系列,专门处理数据库层的错误
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(); } } }
- } catch (org.springframework.dao.DuplicateKeyException e) {
- 根据用户传进来的 username,去数据库里面查一下,看查到的结果能不能和传入进来的 password 匹配
- GET /userInfo HTTP/1.1
- 程序运行过程中,用户登录了之后,让客户端随时通过这个接口,来访问服务器,获取到自身的信息
- 这里约定好了之后,后续的后端/前端代码,都要严格地遵守这个约定来写代码
- 比如,这里的每个属性都是空着的,像 userId => 0
- 如果 driver-class-name 报错,可能是没有引入 Maven 依赖的原因
- 使用数据库来保存上述用户信息
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。