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

文章目录

数据库

数据库设计

完成注册登录以及用户分数管理

  • 使用数据库来保存上述用户信息

创建 java_gobang 数据库, user 表,表示用户信息和分数信息

sql 复制代码
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 的配置文件,使用数据库可以被连接上

xml 复制代码
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. 创建实体类

创建一个实体类:用户

java 复制代码
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 接口

java 复制代码
package org.example.model;  
  
/**  
 * 接口里面创建一些典型的方法  
 */  
public interface UserMapper {  
    // 往数据库中插入一个用户,用于注册功能  
    void insert(User user);  
  
    // 根据用户名,来查询用户的详细信息,用于登录功能  
    User selectByName(String userName);  
}

4. 使用 MyBatis

实现 MyBatis 的相关 xml 配置文件,来自动实现数据库操作

实现 UserMapper.xml

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 匹配
    • 匹配:登陆成功
    • 不匹配:登录失败
java 复制代码
@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

java 复制代码
@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

java 复制代码
@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();  
    }  
}

完整代码

java 复制代码
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();  
        }  
    }  
}
相关推荐
.似水14 分钟前
MySQL 索引和select优化
数据库·mysql
bbsh20991 小时前
WebFuture:ASP.NET启动失败报500.30错误
数据库·webfuture
MyFreeIT1 小时前
Unable to start embedded Tomcat
java·tomcat·mybatis
胆大的1 小时前
SQL 盲注(Blind SQL Injection)
数据库·sql·安全性测试
不会聊天真君6472 小时前
MyBatis(Web后端开发第二期)
mybatis
数据库幼崽2 小时前
MySQL 排查全局锁
数据库·mysql
啃火龙果的兔子3 小时前
华为云二级、多级域名配置
数据库·华为云
isNotNullX3 小时前
kettle好用吗?相较于国产ETL工具有哪些优劣之处?
大数据·数据库·数据仓库·信息可视化·etl
姜豆豆耶4 小时前
Oracle client 静默安装
数据库·oracle·dba
秋意零4 小时前
【排坑指南】MySQL初始化后,Nacos与微服务无法连接??
运维·数据库·mysql·微服务·nacos·报错