【图书管理系统】用户注册系统实现详解

引言

本系统允许用户输入用户名和密码,前端通过AJAX请求将数据发送到后端,后端验证并存储用户信息,同时为每个用户创建一个专属图书表。尽管这是一个基础实现,但它展示了前后端分离开发的核心思想。博客还将讨论潜在的优化点,如密码安全和数据库设计。

1. 约定前后端交互接口

前后端分离开发需要明确的接口约定,以确保数据交互顺畅。在本系统中,前端通过HTTP POST请求将用户注册信息发送到后端的/user/register端点,后端返回JSON格式的响应,指示注册结果。

请求格式

前端发送的请求包含以下字段:

json 复制代码
{
    "userName": "exampleUser",
    "password": "examplePassword"
}
  • userName:用户输入的用户名,字符串类型。
  • password:用户输入的密码,字符串类型。

响应格式

后端返回的JSON对象包含以下字段:

json 复制代码
{
    "status": "SUCCESS" | "FAIL",
    "errorMessage": "错误信息(如果有)"
}
  • status :表示注册结果,SUCCESS表示成功,FAIL表示失败。
  • errorMessage:当注册失败时,提供错误原因,如"用户已存在"或"请填写账号密码"。

2. 整体逻辑

用户注册系统的逻辑分为前端和后端两部分。前端负责用户输入验证和数据发送,后端处理数据存储和业务逻辑。后端采用经典的三层架构:Controller、Service和Mapper。

2.1 Controller的逻辑

Controller层是后端的入口,负责接收前端的HTTP请求,调用Service层处理业务逻辑,并返回响应。在本系统中,UserInfoController类的register方法处理/user/register请求:

  1. 参数验证 :检查传入的UserInfo对象是否为空。
  2. 调用Service :将请求委托给userInfoService.registerUserInfo方法。
  3. 响应处理:根据Service层的返回结果,设置响应的状态和错误消息。

2.2 Service层

Service层封装业务逻辑,确保注册过程的完整性和事务性。UserInfoService类的registerUserInfo方法执行以下步骤:

  1. 检查用户是否存在:查询数据库,确认用户名是否已被注册。
  2. 插入新用户:如果用户名可用,将用户信息插入数据库。
  3. 创建图书表:为新用户创建一个专属的图书表,存储其图书信息。
  4. 事务管理 :使用@Transactional注解确保操作的原子性。

2.3 Mapper层

Mapper层通过MyBatis与数据库交互,执行SQL操作。UserInfoMapper接口定义了三个关键方法:

  • queryUserInfoByUserNameNormal:根据用户名查询用户信息,用于检查用户是否存在。
  • insertUserInfo:插入新用户记录。
  • createBooktable:为用户创建图书表,表名以用户ID命名。

MyBatis的XML映射文件定义了createBooktable的SQL语句,使用动态表名创建图书表。

3. 后端代码实现

以下是后端代码的详细实现,分为Controller和Service层。

3.1 Controller层

UserInfoController类处理用户注册请求:

java 复制代码
@Slf4j
@RestController
@RequestMapping("/user")
public class UserInfoController {
    @RequestMapping("/register")
    public Result register(UserInfo userInfo){
        Result result = new Result();
        if(userInfo == null){
            result.setStatus(ResultStatus.FAIL);
            result.setErrorMessage("请填写账号密码");
            return result;
        }
        result = userInfoService.registerUserInfo(userInfo);
        if(result == null){
            result.setStatus(ResultStatus.FAIL);
            result.setErrorMessage("注册失败");
            log.info("注册时,Service返回的result为空");
            return result;
        }
        result.setStatus(ResultStatus.SUCCESS);
        return result;
    }
}
  • 注解说明
    • @RestController:标记为REST控制器,返回JSON响应。
    • @RequestMapping("/user"):设置基础路径,所有请求以/user开头。
    • @RequestMapping("/register"):映射/user/register路径。
  • 逻辑流程
    1. 检查userInfo是否为空,若为空,返回错误。
    2. 调用Service层的registerUserInfo方法。
    3. 处理Service返回结果,若为空,记录日志并返回错误;否则返回成功。

3.2 Service层

UserInfoService类实现注册的业务逻辑:

java 复制代码
@Slf4j
@Service
public class UserInfoService {
    @Transactional
    public Result registerUserInfo(UserInfo userInfo){
        Result result = new Result();
        UserInfo getUserInfo = userInfoMapper.queryUserInfoByUserNameNormal(userInfo.getUserName());
        if(getUserInfo != null){
            result.setErrorMessage("用户已存在,请重新注册");
            result.setStatus(ResultStatus.FAIL);
            return result;
        }
        Integer count = userInfoMapper.insertUserInfo(userInfo);
        if(count == 1){
            result.setStatus(ResultStatus.SUCCESS);
            UserInfo u = userInfoMapper.queryUserInfoByUserNameNormal(userInfo.getUserName());
            userInfoMapper.createBooktable(u.getId());
            return result;
        }else{
            result.setStatus(ResultStatus.FAIL);
            result.setErrorMessage("用户注册失败");
            log.info("新用户插入后返回的值不是1");
            return result;
        }
    }
}
  • 注解说明
    • @Service:标记为Spring的服务组件。
    • @Transactional:确保方法内的数据库操作具有事务性。
  • 逻辑流程
    1. 调用queryUserInfoByUserNameNormal检查用户名是否已存在。
    2. 若不存在,调用insertUserInfo插入用户。
    3. 检查插入结果,若成功(count == 1),查询新用户ID并调用createBooktable创建图书表。
    4. 若失败,记录日志并返回错误。

3.3 Mapper层实现

UserInfoMapper接口定义了数据库操作:

java 复制代码
@Mapper
public interface UserInfoMapper {
    @Select("select id,user_name,password,delete_flag,create_time,updata_time from normal_user_info where user_name= #{userName}")
    UserInfo queryUserInfoByUserNameNormal(String userName);

    @Insert("insert into normal_user_info (user_name,password) values(#{userName},#{password})")
    Integer insertUserInfo(UserInfo userInfo);

    Integer createBooktable(Integer userId);
}

对应的MyBatis XML映射文件定义了createBooktable的SQL:

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.booksmanagementsystem.mapper.UserInfoMapper">
    <update id="createBooktable">
        create table #{id}_book_info(
            `id` INT(11) NOT NULL AUTO_INCREMENT,
            `book_name` VARCHAR(127) NOT NULL,
            `author` VARCHAR(127) NOT NULL,
            `count` INT(11) NOT NULL,
            `price` DECIMAL(7,2) NOT NULL,
            `publish` VARCHAR(256) NOT NULL,
            `status` TINYINT(4) DEFAULT 1 COMMENT '0-无效, 1-正常, 2-不允许借阅',
            `create_time` DATETIME DEFAULT now(),
            `update_time` DATETIME DEFAULT now() ON UPDATE now(),
            PRIMARY KEY (`id`)
        ) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
    </update>
</mapper>
  • 关键点
    • queryUserInfoByUserNameNormal使用@Select注解执行查询。
    • insertUserInfo使用@Insert注解插入数据。
    • createBooktable在XML中定义,动态创建表,表名以用户ID为前缀。

4. 前端代码

前端代码包括HTML表单和JavaScript逻辑,使用Bootstrap美化界面,jQuery处理AJAX请求。

HTML代码

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>用户注册</title>
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <link rel="stylesheet" href="css/register.css">
</head>
<body>
<div class="container-login">
    <div class="container-pic"></div>
    <div class="login-dialog">
        <h3>新用户注册</h3>
        <form id="registerForm">
            <div class="row">
                <span>账户</span>
                <input type="text" name="username" id="username" class="form-control" required>
            </div>
            <div class="row">
                <span>密码</span>
                <input type="password" name="password" id="password" class="form-control" required>
            </div>
            <div class="row">
                <span>确认密码</span>
                <input type="password" name="confirmPassword" id="confirmPassword" class="form-control" required>
            </div>
            <div class="row" style="margin-top: 20px;">
                <div class="col-md-6">
                    <button type="button" class="btn btn-success btn-lg btn-block" onclick="submitRegister()">立即注册</button>
                </div>
                <div class="col-md-6">
                    <button type="button" class="btn btn-secondary btn-lg btn-block" onclick="history.back()">返回登录</button>
                </div>
            </div>
        </form>
    </div>
</div>
  • 结构说明
    • 使用Bootstrap的form-control类美化输入框。
    • 包含用户名、密码和确认密码三个输入字段。
    • 提供"立即注册"和"返回登录"两个按钮。

JavaScript代码

JavaScript 复制代码
function submitRegister() {
    // 基础验证
    if ($("#password").val() !== $("#confirmPassword").val()) {
        alert("两次密码输入不一致!");
        return;
    }

    $.ajax({
        url: "/user/register",
        type: "post",
        data: {
            "userName": $("#username").val(),
            "password": $("#password").val()
        },
        success: function(result) {
            if(result.status == "SUCCESS") {
                alert("注册成功!");
                location.href = "login_test.html";
            } else {
                alert("注册失败,请重试");
            }
        }
    });
}

功能说明:

  • 密码验证:先检查密码和确认密码是否一致,不一致则弹出提示并停止。
  • AJAX请求:密码一致时,通过POST请求发送到/user/register,携带用户名和密码。
  • 响应处理:成功时,若状态为"SUCCESS",弹出成功提示并跳转到登录页;失败时,弹出失败提示。

5 .总结

本博客详细解析了用户注册系统的实现,从前端表单设计到后端业务逻辑,涵盖了HTML、JavaScript、Spring Boot和MyBatis的集成。系统允许用户注册并为每个用户创建专属图书表,体现了前后端分离开发的优势。

相关推荐
skiy6 分钟前
SpringBoot项目中读取resource目录下的文件(六种方法)
spring boot·python·pycharm
不甘先生11 分钟前
Go context 实战指南:从入门到生产级并发控制(架构师避坑手册)
开发语言·后端·golang
xmjd msup18 分钟前
mysql的分区表
数据库·mysql
Lyyaoo.19 分钟前
【JAVA Spring面经】Spring 事务失效情况
java·数据库·spring
MeAT ITEM24 分钟前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
salipopl27 分钟前
Spring Boot 整合 Druid 并开启监控
java·spring boot·后端
dovens28 分钟前
PostgreSQL 中进行数据导入和导出
大数据·数据库·postgresql
IOT.FIVE.NO.128 分钟前
claude code desktop cowork报错解决和记录Workspace..The isolated Linux environment ...
linux·服务器·数据库
Rick199337 分钟前
mysql 慢查询怎么快速定位
android·数据库·mysql
GISer_Jing38 分钟前
AI原生前端工程化进阶实践:从流式交互架构到端云协同全链路落地
前端·人工智能·后端·学习