Spring Boot项目学习05之用户注册模块

1.前端页面

对于一个后端开发者来说,自己去开发前端页面的各种特效和交互效果,是一件挺复杂的事情。所以对于一个较为完整的项目开发上,作为后端开发来说,使用成型的模版就是一个很好的选择。这里就使用Fly Template来构建前端页面。Fly Template是基于 layui 搭建而成,提供了全屏和固宽两类排版,并且具备响应式适配能力,可很好地作为简约型问答社区的页面支撑。

layui下载地址(非官方),官方网站已经下线了:layui下载地址(非官方)

fly template下载地址:fly template下载地址

fly项目结构如此下:
在这里插入图片描述

|–html 可以直接预览的模板文件
|–res 静态资源
…|–css
…|–images
…|–layui
…|–modes 模板业务模块
|–views 动态模板参考

2.创建用户表

创建数据库与用户表,用户表主要包含一些常见的字段,例如登陆信息、头像、简介等。

CREATE
DATABASE /*!32312 IF NOT EXISTS*/`my_bbs_db` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `my_bbs_db`;

DROP TABLE IF EXISTS `tb_bbs_user`;

CREATE TABLE `tb_bbs_user` (
   `user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户主键id',
   `login_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '登陆名称(默认为邮箱号码)',
   `password_md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'MD5加密后的密码',
   `nick_name` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '昵称',
   `head_img_url` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '头像',
   `gender` varchar(4) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '性别',
   `location` varchar(4) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '居住地',
   `introduce` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '个人简介',
   `user_status` tinyint NOT NULL DEFAULT '0' COMMENT '用户状态 0=正常 1=禁言',
   `last_login_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最新登录时间',
   `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间',
   PRIMARY KEY (`user_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;

3.初始化项目

创建Spring Boot项目,此项目是web项目,所以开始添加web依赖即可,之后需要什么依赖就添加什么依赖。然后将fly template的文件资源添加到项目中,这样我们就可以不用自己去设计前端页面,只需要做简要修改即可。

首先主要将前端模版的css文件夹和layui文件夹的内容添加到Spring Boot项目的static文件夹下。这样就可以基本使用该前端模板的功能了。接着创建一个简单的index.html,创建一个控制器进行跳转,检查项目是否能正常运行。

3.1 初始项目结构

在这里插入图片描述

3.2 创建demo示例

index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>index</title>
    <link rel="stylesheet" th:href="@{layui/layui.js}">
    <link rel="stylesheet" th:href="@{css/global.css}">
</head>
<body>
    <div class="nav-user">
        <a class="unlogin" href="user/login.html"><i class="iconfont icon-touxiang"></i></a>
        <span><a href="user/login.html">登入</a><a href="user/reg.html">注册</a></span>
        <p class="out-login">
            <a href="" onclick="layer.msg('正在通过QQ登入', {icon:16, shade: 0.1, time:0})" class="iconfont icon-qq" title="QQ登入"></a>
            <a href="" onclick="layer.msg('正在通过微博登入', {icon:16, shade: 0.1, time:0})" class="iconfont icon-weibo" title="微博登入"></a>
        </p>
    </div>
</body>
</html>

IndexController.java

@Controller
public class IndexController {

    @RequestMapping("hello")
    public String index(){
        return "index";

    }
}

最后启动项目,检查我们的layui是否可一在项目中使用。由下图可以看到我们可以引用layui的样式功能。保证初始化项目正常运行,接下来接可以完成具体功能设计了。
在这里插入图片描述

4.注册页面制作

4.1 注册页面跳转Controller实现

在 controller/rest 包下新建 BBSUserController.java,添加页面跳转功能。

@Controller
public class BBSUserController {

    /**
     * 注册页面跳转
     * @return
     */
    @GetMapping({"/register", "/register.html"})
    public String registerPage() {
        return "user/reg";
    }
}

该方法用于处理 /register 请求,是注册页面的跳转处理方法,请求方法为 GET,在发起请求后会分别跳转到 templates 模板目录中 user 目录下的 reg.html 中。

4.2 页面制作

注册页面的整体布局参考了 fly 论坛的注册页面,在 templates 目录中新建 user 目录和 reg.html 模板页面。

在此之前需要将一些图片文件、公共js文件和一些公共页面先创建完成在说,比如页面的头部等;添加到Spring Boot项目中。

header.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="head-fragment(title)">
    <meta charset="utf-8">
    <title th:text="${title}">首页</title>
    <link rel="shortcut icon" th:href="@{/images/my-bbs-icon.png}">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="description" content="My-BBS,bbs,论坛,SpringBoot论坛,论坛系统,Java论坛,SpringBoot,spring-boot,java">
    <meta name="description" content="My BBS 是由 SpringBoot + Mybatis + Thymeleaf 等技术实现的 Java BBS论坛系统">
    <link rel="stylesheet" th:href="@{/layui/css/layui.css}">
    <link rel="stylesheet" th:href="@{/css/global.css}">
</head>

<div th:fragment="header-fragment" class="fly-header layui-bg-black">
    <div class="layui-container">
        <a class="fly-logo" href="/">
            <img th:src="@{/images/my-bbs-logo.png}" alt="My-BBS">
        </a>
        <ul class="layui-nav fly-nav layui-hide-xs">
            <li class="layui-nav-item layui-this">
                <a href="添加自己的文档地址"><i class="iconfont icon-wenda"></i>开发文档</a>
            </li>
            <li class="layui-nav-item">
                <a href="添加自己的源码下载地址"><i class="iconfont icon-daima"></i>源码</a>
            </li>
            <li class="layui-nav-item layui-this">
                <a href="添加自己的博客地址"><i class="iconfont icon-jiaoliu"></i>交流</a>
            </li>
        </ul>

        <ul class="layui-nav fly-nav-user">

            <!-- 未登入的状态 -->
            <th:block th:if="${session.myBBSUser==null}">
                <li class="layui-nav-item">
                    <a class="iconfont icon-touxiang layui-hide-xs" href="user/login.html"></a>
                </li>
                <li class="layui-nav-item">
                    <a th:href="@{/login}">登入</a>
                </li>
                <li class="layui-nav-item">
                    <a th:href="@{/register}">注册</a>
                </li>
            </th:block>


            <!-- 登入后的状态 -->
            <th:block th:unless="${session.myBBSUser==null}">
                <li class="layui-nav-item">
                    <a class="fly-nav-avatar" href="javascript:;">
                        <cite class="layui-hide-xs" th:text="${session.myBBSUser.nickName}">picacho</cite>
                        <th:block th:if="${session.myBBSUser.gender==''}">
                            <i class="iconfont icon-nan"></i>
                        </th:block>
                        <th:block th:if="${session.myBBSUser.gender==''}">
                            <i class="iconfont icon-nv"></i>
                        </th:block>
                        <th:block th:if="${session.myBBSUser.gender=='未知'}">
                            <i class="iconfont icon-biaoqing"></i>
                        </th:block>
                        <img th:src="@{${session.myBBSUser.headImgUrl}}">
                        <span class="layui-nav-more"></span>
                    </a>
                    <dl class="layui-nav-child">
                        <dd><a th:href="@{/userSet}"><i class="layui-icon">&#xe620;</i>基本设置</a></dd>
                        <dd><a th:href="@{/myCenter}"><i class="layui-icon" style="margin-left: 2px; font-size: 22px;">&#xe68e;</i>我的主页</a>
                        </dd>
                        <hr style="margin: 5px 0;">
                        <dd><a th:href="@{/logout}" style="text-align: center;">退出</a></dd>
                    </dl>
                </li>
            </th:block>
        </ul>
    </div>
</div>

试着分析下页面结构是大致实现即可,毕竟作为后端开发来说写页面太难了(要自己写是真的不会啊)。
reg.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<!-- 引用公共部分-->
<head th:replace="header::head-fragment('注册')">
</head>
<body>

<div th:replace="header::header-fragment"></div>

<div class="layui-container fly-marginTop">
    <div class="fly-panel fly-panel-user" pad20>
        <div class="layui-tab layui-tab-brief" lay-filter="user">
            <ul class="layui-tab-title">
                <li><a th:href="@{/login}">登入</a></li>
                <li class="layui-this">注册</li>
            </ul>
            <div class="layui-form layui-tab-content" id="LAY_ucm" style="padding: 20px 0;">
                <div class="layui-tab-item layui-show">
                    <div class="layui-form layui-form-pane">
                        <!-- 表单,用于提交用户注册信息-->
                        <form method="post" id="registerForm" onsubmit="return false;" action="##">
                            <!-- 填写邮箱-->
                            <div class="layui-form-item">
                                <label for="loginName" class="layui-form-label">邮箱</label>
                                <div class="layui-input-inline">
                                    <input type="text" id="loginName" name="loginName" required lay-verify="email"
                                           autocomplete="off" class="layui-input">
                                </div>
                                <div class="layui-form-mid layui-word-aux">将会成为您唯一的登入名</div>
                            </div>
                            <!-- 填写昵称-->
                            <div class="layui-form-item">
                                <label for="nickName" class="layui-form-label">昵称</label>
                                <div class="layui-input-inline">
                                    <input type="text" id="nickName" name="nickName" required lay-verify="required"
                                           autocomplete="off" class="layui-input">
                                </div>
                            </div>
                            <!-- 填写密码-->
                            <div class="layui-form-item">
                                <label for="password" class="layui-form-label">密码</label>
                                <div class="layui-input-inline">
                                    <input type="password" id="password" name="password" required lay-verify="required"
                                           autocomplete="off" class="layui-input">
                                </div>
                                <div class="layui-form-mid layui-word-aux">6到20个字符</div>
                            </div>
                            <!-- 填写确认密码-->
                            <div class="layui-form-item">
                                <label for="repass" class="layui-form-label">确认密码</label>
                                <div class="layui-input-inline">
                                    <input type="password" id="repass" name="repass" required lay-verify="required"
                                           autocomplete="off" class="layui-input">
                                </div>
                            </div>
                            <!-- 填写验证码-->
                            <div class="layui-form-item">
                                <label for="verifyCode" class="layui-form-label">验证码</label>
                                <div class="layui-input-inline">
                                    <input type="text" id="verifyCode" name="verifyCode" required lay-verify="required"
                                           placeholder="请输入验证码" autocomplete="off" class="layui-input">
                                </div>
                                <div class="layui-form-mid">
                  <span><img data-tooltip="看不清楚?换一张"
                             th:src="@{/common/captcha}"
                             onclick="this.src='/common/captcha?d='+new Date()*1"
                             alt="单击图片刷新!"></span>
                                </div>
                            </div>
                            <!-- 立即注册按钮,绑定到一个全局函数上;没有使用表单自带的action属性提交表单-->
                            <div class="layui-form-item">
                                <button class="layui-btn" lay-filter="*" lay-submit onclick="register()">立即注册</button>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>

</div>

<div class="fly-footer">
    <p>My-BBS社区 2021 &copy; <a href="填写自己的额博客地址" target="_blank">picacho</a></p>
</div>

<script th:src="@{/js/public.js}"></script>
<script th:src="@{/layui/layui.js}"></script>
<script type="text/javascript">
    layui.use(['layer', 'jquery'], function () {
        var layer = layui.layer;
        var $ = layui.$;
        window.register = function () {
            var $ = layui.$;
            var loginName = $("#loginName").val();
            if (!validEmail(loginName)) {
                layer.alert('请输入正确的登录名!', {title: '提醒', skin: 'layui-layer-molv', icon: 2});
                return false;
            }
            var nickName = $("#nickName").val();
            if (!validUserName(nickName)) {
                layer.alert('请输入正确的昵称!', {title: '提醒', skin: 'layui-layer-molv', icon: 2});
                return false;
            }
            var password = $("#password").val();
            if (!validPassword(password)) {
                layer.alert('请输入正确的密码格式!', {title: '提醒', skin: 'layui-layer-molv', icon: 2});
                return false;
            }
            var repass = $("#repass").val();
            if (!validPassword(repass)) {
                layer.alert('请输入正确的密码格式!', {title: '提醒', skin: 'layui-layer-molv', icon: 2});
                return false;
            }
            if (repass != password) {
                layer.alert('确认密码与密码字段不相同!', {title: '提醒', skin: 'layui-layer-molv', icon: 2});
                return false;
            }
            var verifyCode = $("#verifyCode").val();
            if (!validLength(verifyCode, 5)) {
                layer.alert('请输入正确的验证码!', {title: '提醒', skin: 'layui-layer-molv', icon: 2});
                return false;
            }
            // 将表单数据序列化,用于网络传输数据
            var params = $("#registerForm").serialize();
            var url = '/register';
            $.ajax({
                type: 'POST',// 方法类型
                url: url,
                data: params,
                success: function (result) {
                    if (result.resultCode == 200) {
                        layer.alert('注册成功!', {title: '信息', skin: 'layui-layer-molv', icon: 1});
                    } else {
                        layer.msg(result.message);
                    }
                    ;
                },
                error: function () {
                    layer.alert('操作失败!', {title: '提醒', skin: 'layui-layer-molv', icon: 2});
                }
            });
        }
    });
</script>
</body>
</html>

启动项目访问请求路径,可以看到如下画面,表示注册跳转页面功能完成了。
在这里插入图片描述
接着需要完成验证码功能,这个功能在这篇博客讲到过基于Servlet的验证码登陆demo,这里使用第三方工具实现即可。在controller/common文件夹下创建CaptchaController控制器处理验证码相关的功能。

前端页面访问路径如下:
在这里插入图片描述

CaptchaController.java

@Controller
public class CaptchaController {

    @GetMapping("/common/captcha")
    public void defaultKaptcha(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        httpServletResponse.setHeader("Cache-Control", "no-store");
        httpServletResponse.setHeader("Pragma", "no-cache");
        httpServletResponse.setDateHeader("Expires", 0);
        httpServletResponse.setContentType("image/gif");

        // 三个参数分别为宽、高、位数
        GifCaptcha captcha = new GifCaptcha(75, 30,4);

        // 设置类型 数字和字母混合
        captcha.setCharType(Captcha.TYPE_DEFAULT);

        //设置字体
        captcha.setCharType(Captcha.FONT_9);

        // 验证码存入session
        // 这里设置全局变量Constants.VERIFY_CODE_KEY,也可以自己设置
        httpServletRequest.getSession().setAttribute(Constants.VERIFY_CODE_KEY, captcha.text().toLowerCase());

        // 输出图片流
        captcha.out(httpServletResponse.getOutputStream());
    }
}

在这里插入图片描述

5.完成注册功能

在实现注册功能时,选择后端接口 + 前端 Ajax 调用方式来实现的。BBSUserController 类已经创建,之后在 service 包下新建业务层代码 BBSUserService.java 及实现类,之后参照接口分别功能实现即可。

5.1 完成统一结果返回

在common包下创建ServiceResultEnum枚举类型,用于统一定义返回的信息。在util包下创建Result
类统一包装返回结果。在util包下创建ResultGenerator类生成Result对象返回给前端。

public enum ServiceResultEnum {
    ERROR("error"),

    SUCCESS("success"),

    DATA_NOT_EXIST("未查询到记录!"),

    SAME_LOGIN_NAME_EXIST("用户名已存在!"),

    LOGIN_NAME_NULL("请输入登录名!"),

    LOGIN_NAME_NOT_EMAIL("请输入正确的邮箱!"),

    LOGIN_PASSWORD_NULL("请输入密码!"),

    LOGIN_VERIFY_CODE_NULL("请输入验证码!"),

    LOGIN_VERIFY_CODE_ERROR("验证码错误!"),

    LOGIN_ERROR("登录失败!"),

    DB_ERROR("database error");

    private String result;

    ServiceResultEnum(String result) {
        this.result = result;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }
}
public class Result<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    private int resultCode;
    private String message;
    private T data;

    public Result() {
    }

    public Result(int resultCode, String message) {
        this.resultCode = resultCode;
        this.message = message;
    }

    public int getResultCode() {
        return resultCode;
    }

    public void setResultCode(int resultCode) {
        this.resultCode = resultCode;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "Result{" +
                "resultCode=" + resultCode +
                ", message='" + message + '\'' +
                ", data=" + data +
                '}';
    }
}

public class ResultGenerator {
    private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";
    private static final String DEFAULT_FAIL_MESSAGE = "FAIL";
    private static final int RESULT_CODE_SUCCESS = 200;
    private static final int RESULT_CODE_SERVER_ERROR = 500;

    public static Result genSuccessResult() {
        Result result = new Result();
        result.setResultCode(RESULT_CODE_SUCCESS);
        result.setMessage(DEFAULT_SUCCESS_MESSAGE);
        return result;
    }

    public static Result genSuccessResult(String message) {
        Result result = new Result();
        result.setResultCode(RESULT_CODE_SUCCESS);
        result.setMessage(message);
        return result;
    }

    public static Result genSuccessResult(Object data) {
        Result result = new Result();
        result.setResultCode(RESULT_CODE_SUCCESS);
        result.setMessage(DEFAULT_SUCCESS_MESSAGE);
        result.setData(data);
        return result;
    }

    public static Result genFailResult(String message) {
        Result result = new Result();
        result.setResultCode(RESULT_CODE_SERVER_ERROR);
        if (!StringUtils.hasLength(message)) {
            result.setMessage(DEFAULT_FAIL_MESSAGE);
        } else {
            result.setMessage(message);
        }
        return result;
    }

    public static Result genErrorResult(int code, String message) {
        Result result = new Result();
        result.setResultCode(code);
        result.setMessage(message);
        return result;
    }
}


5.2 BBSUserController层代码

接口的映射地址为 /register,请求方法为 POST。

    /**
     * 注册功能
     */
    @PostMapping("/register")
    @ResponseBody
    public Result register(@RequestParam("loginName") String loginName,
                           @RequestParam("verifyCode") String verifyCode,
                           @RequestParam("nickName") String nickName,
                           @RequestParam("password") String password,
                           HttpSession httpSession) {
        if (!StringUtils.hasLength(loginName)) {
            return ResultGenerator.genFailResult(ServiceResultEnum.LOGIN_NAME_NULL.getResult());
        }
        if (!PatternUtil.isEmail(loginName)) {  // 使用正则工具类处理昵称,判断是否符合邮箱格式
            return ResultGenerator.genFailResult(ServiceResultEnum.LOGIN_NAME_NOT_EMAIL.getResult());
        }
        if (!StringUtils.hasLength(password)) {
            return ResultGenerator.genFailResult(ServiceResultEnum.LOGIN_PASSWORD_NULL.getResult());
        }
        if (!StringUtils.hasLength(verifyCode)) {
            return ResultGenerator.genFailResult(ServiceResultEnum.LOGIN_VERIFY_CODE_NULL.getResult());
        }
        String kaptchaCode = httpSession.getAttribute(Constants.VERIFY_CODE_KEY) + "";
        if (!StringUtils.hasLength(kaptchaCode) || !verifyCode.equals(kaptchaCode)) {
            return ResultGenerator.genFailResult(ServiceResultEnum.LOGIN_VERIFY_CODE_ERROR.getResult());
        }
        String registerResult = bbsUserService.register(loginName, password, nickName);
        //注册成功
        if (ServiceResultEnum.SUCCESS.getResult().equals(registerResult)) {
            httpSession.removeAttribute(Constants.VERIFY_CODE_KEY);//删除session中的验证码
            return ResultGenerator.genSuccessResult();
        }
        //注册失败
        return ResultGenerator.genFailResult(registerResult);
    }

首先对参数进行校验,之后调用 bbsUserService 业务层代码在数据库中新增一条论坛用户记录,最后根据业务层的结果来返回对应的 Result 对象。

5.3 BBSUserServiceImpl业务层代码

首先查询数据库中是否有相同登录名的记录,如果存在则不再执行后续逻辑,返回 “用户名已存在” 的错误信息,如果不存在则证明可以新增这条记录。同时由于用户注册时只填写了登录名称和密码,数据库存储所需的两个字段,还有其他字段并没有传入,所以对头像、介绍、居住地等字段都进行了默认值的设置,这些字段可以在个人中心页面进行修改。最后将密码进行 MD5 转换后执行 insert 语句把这条用户信息插入到数据库中,并返回成功的业务信息。

public interface BBSUserService {
    /**
     * 用户注册
     *
     * @param loginName
     * @param password
     * @return
     */
    String register(String loginName, String password, String nickName);

}
@Service
public class BBSUserServiceImpl implements BBSUserService {

    @Autowired
    private BBSUserMapper bbsUserMapper;

    @Override
    public String register(String loginName, String password, String nickName) {
        if (bbsUserMapper.selectByLoginName(loginName) != null) {
            return ServiceResultEnum.SAME_LOGIN_NAME_EXIST.getResult();
        }
        //注册用户
        BBSUser registerUser = new BBSUser();
        registerUser.setLoginName(loginName);
        registerUser.setNickName(nickName);
        //默认头像
        registerUser.setHeadImgUrl("/images/avatar/default.png");
        //默认介绍
        registerUser.setIntroduce("这个人很懒,什么都没留下~");
        //居住地
        registerUser.setLocation("未知");
        registerUser.setGender("未知");
        String passwordMD5 = MD5Util.MD5Encode(password, "UTF-8");
        registerUser.setPasswordMd5(passwordMD5);
        if (bbsUserMapper.insertSelective(registerUser) > 0) {
            return ServiceResultEnum.SUCCESS.getResult();
        }
        return ServiceResultEnum.DB_ERROR.getResult();
    }
}

5.4 BBSUserMapper数据持久层

主要的 SQL 方法为 selectByLoginName() 和 insertSelective()。selectByLoginName() 方法是根据用户名查询用户记录信息,然后与要注册的用户名比较,如果存在则不插入,否则就插入。

package top.picacho.bbs.entity;

import java.util.Date;

/**
 * 论坛用户-实体类
 */
public class BBSUser {
    private Long userId;

    private String loginName;

    private String passwordMd5;

    private String nickName;

    private String headImgUrl;

    private String gender;

    private String location;

    private String introduce;

    private Byte userStatus;

    private Date lastLoginTime;

    private Date createTime;

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName == null ? null : loginName.trim();
    }

    public String getPasswordMd5() {
        return passwordMd5;
    }

    public void setPasswordMd5(String passwordMd5) {
        this.passwordMd5 = passwordMd5 == null ? null : passwordMd5.trim();
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName == null ? null : nickName.trim();
    }

    public String getHeadImgUrl() {
        return headImgUrl;
    }

    public void setHeadImgUrl(String headImgUrl) {
        this.headImgUrl = headImgUrl == null ? null : headImgUrl.trim();
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender == null ? null : gender.trim();
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location == null ? null : location.trim();
    }

    public String getIntroduce() {
        return introduce;
    }

    public void setIntroduce(String introduce) {
        this.introduce = introduce == null ? null : introduce.trim();
    }

    public Byte getUserStatus() {
        return userStatus;
    }

    public void setUserStatus(Byte userStatus) {
        this.userStatus = userStatus;
    }

    public Date getLastLoginTime() {
        return lastLoginTime;
    }

    public void setLastLoginTime(Date lastLoginTime) {
        this.lastLoginTime = lastLoginTime;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", userId=").append(userId);
        sb.append(", loginName=").append(loginName);
        sb.append(", passwordMd5=").append(passwordMd5);
        sb.append(", nickName=").append(nickName);
        sb.append(", headImgUrl=").append(headImgUrl);
        sb.append(", gender=").append(gender);
        sb.append(", location=").append(location);
        sb.append(", introduce=").append(introduce);
        sb.append(", userStatus=").append(userStatus);
        sb.append(", lastLoginTime=").append(lastLoginTime);
        sb.append(", createTime=").append(createTime);
        sb.append("]");
        return sb.toString();
    }
}
public interface BBSUserMapper {
    int insertSelective(BBSUser record);

    BBSUser selectByLoginName(String loginName);
}
<?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="top.picacho.bbs.dao.BBSUserMapper">
    <resultMap id="BaseResultMap" type="top.picacho.bbs.entity.BBSUser">
        <id column="user_id" jdbcType="BIGINT" property="userId" />
        <result column="login_name" jdbcType="VARCHAR" property="loginName" />
        <result column="password_md5" jdbcType="VARCHAR" property="passwordMd5" />
        <result column="nick_name" jdbcType="VARCHAR" property="nickName" />
        <result column="head_img_url" jdbcType="VARCHAR" property="headImgUrl" />
        <result column="gender" jdbcType="VARCHAR" property="gender" />
        <result column="location" jdbcType="VARCHAR" property="location" />
        <result column="introduce" jdbcType="VARCHAR" property="introduce" />
        <result column="user_status" jdbcType="TINYINT" property="userStatus" />
        <result column="last_login_time" jdbcType="TIMESTAMP" property="lastLoginTime" />
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    </resultMap>
    <sql id="Base_Column_List">
        user_id, login_name, password_md5, nick_name, head_img_url, gender, location, introduce, 
    user_status, last_login_time, create_time
    </sql>
    <!-- 通过登录名查询用户-->
    <select id="selectByLoginName" resultType="top.picacho.bbs.entity.BBSUser">
        select
        <include refid="Base_Column_List" />
        from tb_bbs_user
        where login_name = #{loginName,jdbcType=VARCHAR} limit 1
    </select>

   
    <insert id="insertSelective" parameterType="top.picacho.bbs.entity.BBSUser">
        insert into tb_bbs_user
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="userId != null">
                user_id,
            </if>
            <if test="loginName != null">
                login_name,
            </if>
            <if test="passwordMd5 != null">
                password_md5,
            </if>
            <if test="nickName != null">
                nick_name,
            </if>
            <if test="headImgUrl != null">
                head_img_url,
            </if>
            <if test="gender != null">
                gender,
            </if>
            <if test="location != null">
                location,
            </if>
            <if test="introduce != null">
                introduce,
            </if>
            <if test="userStatus != null">
                user_status,
            </if>
            <if test="lastLoginTime != null">
                last_login_time,
            </if>
            <if test="createTime != null">
                create_time,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="userId != null">
                #{userId,jdbcType=BIGINT},
            </if>
            <if test="loginName != null">
                #{loginName,jdbcType=VARCHAR},
            </if>
            <if test="passwordMd5 != null">
                #{passwordMd5,jdbcType=VARCHAR},
            </if>
            <if test="nickName != null">
                #{nickName,jdbcType=VARCHAR},
            </if>
            <if test="headImgUrl != null">
                #{headImgUrl,jdbcType=VARCHAR},
            </if>
            <if test="gender != null">
                #{gender,jdbcType=VARCHAR},
            </if>
            <if test="location != null">
                #{location,jdbcType=VARCHAR},
            </if>
            <if test="introduce != null">
                #{introduce,jdbcType=VARCHAR},
            </if>
            <if test="userStatus != null">
                #{userStatus,jdbcType=TINYINT},
            </if>
            <if test="lastLoginTime != null">
                #{lastLoginTime,jdbcType=TIMESTAMP},
            </if>
            <if test="createTime != null">
                #{createTime,jdbcType=TIMESTAMP},
            </if>
        </trim>
    </insert>
</mapper>

6.验证注册功能结果

在主类上添加包扫描路径(不能缺少,不然无法扫描到Mapper接口),配置主文件后启动项目,验证注册功能。

# 禁止使用thymeleaf模版的缓存功能呢
spring.thymeleaf.cache=false

# 数据库连接信息
spring.datasource.name=my-bbs-datasource
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/my_bbs_db?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoReconnect=true&useSSL=false&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=12345678
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=60000
spring.datasource.hikari.pool-name=hikariCP
spring.datasource.hikari.max-lifetime=600000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1

# mybatis config
mybatis.mapper-locations=classpath:mapper/*Mapper.xml

在这里插入图片描述
效果展示:
在这里插入图片描述
在这里插入图片描述
可以看到,注册成功了。至此,注册模块也就告一段落了。
项目源码下载地址:源码下载

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

picacho_pkq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值