springboot整合mybatis-puls登陆注册

目录

创建springboot项目

目录结构:

启动类

测试类

idea建表

pom文件

编写yml文件

qq邮箱设置

登陆注册代码

编写持久层(Dao)

注册代码

业务层

业务实现类

mapper

控制层

前端代码

注册页面

邮件正文:

登录代码

控制层

业务层:

业务实现类:

前端代码

自动登录


创建springboot项目

Maven类型+

Lombok依赖+spring web依赖+MySQL driver依赖+mybatis framework依赖+java Mail Sender依赖

目录结构:

有些类是自己写的不用看,看一下结构就可以

启动类

复制代码
@SpringBootApplication
@MapperScan("com.example.mapper")//将mapper路径下自动注册映射器接口为spring Bean
public class SpringBootDemo1Application {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemo1Application.class,args);
    }
}

测试类

复制代码
@SpringBootTest
@RunWith(SpringRunner.class)
class SpringBootTestApplicationTests {

}

idea建表

java 复制代码
use `数据库名`;
create table `user`(
    `id` int primary key auto_increment comment '主键id',
    `email` varchar(255) comment '用户邮箱',
    `password` varchar(255) comment '用户密码',
    `salt` varchar(255) comment '盐',
    `confirm_code` varchar(255) comment '确认码',
    `activation_time` datetime comment '激活时间',
    `is_valid` tinyint comment '账号状态'
)default charset=utf8 comment '用户表';

pom文件

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>springBoot-Test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springBoot-Test</name>
    <description>springBoot-Test</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.13</spring-boot.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>8.2.0</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--导入Mybatis坐标-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.2</version>
        </dependency>
        <!--导入mybatis-plus坐标-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.13</version>
        </dependency>
        <!--导入数据库druid坐标-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.22</version>
        </dependency>
        <!--简略get,set方法-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
        <!--模版引擎-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <!--swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--添加事务管理-->
        <!-- 支持使用 Spring AOP 和 AspectJ 进行切面编程。 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!-- SpringBoot集成FreeMarker的依赖 :模版引擎,生成输出文本-->
        <!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>-->
        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--邮箱发送-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <!--工具包:雪花算法:生成确认码-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.25</version>
        </dependency>

    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.example.springboottest.SpringBootTestApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

编写yml文件

复制代码
server:
  port: 8088
spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver # 配置数据库驱动程序,用于数据库通信和执行sql语句
      url: jdbc:mysql://localhost:3306/表名?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8 # 加数据库名
      username: root
      password: 
  mvc: # 处理springboot与swagger2冲突
    pathmatch:
      matching-strategy: ant_path_matcher
  freemarker:
    expose-session-attributes: true # 暴露session对象的属性
    settings:
      classic_compatible: true # 配置为传统模式,控制自动处理
    suffix: .ftl # 指定模版文件后缀
  mail:
    protocol: smtp # 邮箱协议
    host: smtp.qq.com # qq邮箱,如果用网易将qq改成163
    port: 25
    username:  # 发送人邮件名(这个地方可能出错,可能是由于名字问题)
    password: # 授权码
    default-encoding: utf-8
    properties:
      mail:
        debug: true # 开启debug模式会打印邮件发送过程的日志

mybatis-plus:
  # mybatis映射器XML文件位置 作用:定义sql语句和结果映射
  mapper-location: classpath:mapper/*.xml
  # 开启mybatis-plus的运行日志(建议)
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

qq邮箱设置

点击第二列的账号:开启服务,发送邮件,记下授权码 ok !

登陆注册代码

编写持久层(Dao)

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "user") 
public class User {
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
    @TableField(value = "email")
    private String email;
    @TableField(value = "password") // 密码,使用md5+盐加密
    private String password;
    @TableField(value = "salt")
    private String salt; // 盐
    @TableField(value = "confirm_code") // 确认码
    private String confirmCode;
    @TableField(value = "activation_time") // 激活失效时间
    private LocalDateTime activationTime;
    @TableField(value = "is_valid") // 账号状态
    private Byte isValid;


}

注册代码

业务层
java 复制代码
public interface UserService extends IService<User> {
    // 创建账号
    Map<String,Object> createAccount(User user);
    // 创建账号过程中,用于激活账号的确认码,没有激活不可以登录账号
    Map<String, Object> activation(String confirmCode);
    // 将用户信息录入数据库
    int insertUser(User user);
    // 通过确认码查找用户,不用担心确认码重复
    User selectUserByConfirmCode(String confirmCode);
    // 通过邮箱激活账号
    int updateUserByConfirmCode(String confirmCode);
    // 通过邮箱名查找用户(如果没有进行注册查重,那么将这个修改成List<User>有多个用户报异常)
    User selectUserByEmail(String email);
}
业务实现类
java 复制代码
@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper um;
    @Value("${spring.mail.username}")
    private String mailUsername; 
    @Resource //发送邮件,实现邮箱验证
    private JavaMailSender javaMailSender; 
    @Resource // 模版引擎
    private TemplateEngine templateEngine;
    @Override
    @Transactional // 事务管理
    /*
     * 创建账号:接收发送过来的邮件账号和密码,利用雪花算法生成确认码用于激活账号,使用MD5将密码进行加密
     * 设置激活时间和激活状态为未激活后添加到数据库,发送邮件领取激活码,激活账号*/
    public Map<String, Object> createAccount(User user) {
        // 检验账号是否重复

        // 雪花算法生成确认码
        String confirmCode = IdUtil.getSnowflake(1,1).nextIdStr();
        // 生成盐 随机数
        String salt = RandomUtil.randomString(6);
        // 加密密码:原始密码+盐
        String md5Pwd = SecureUtil.md5(user.getPassword()+salt);
        // 激活时间 有效时间
        LocalDateTime ldt = LocalDateTime.now().plusDays(1);
        user.setConfirmCode(confirmCode);
        user.setSalt(salt);
        user.setPassword(md5Pwd);
        user.setActivationTime(ldt);
        user.setIsValid((byte)0);
        // 新增账号
        int result = um.insert(user);
        HashMap<String, Object> hm = new HashMap<>();
        if(result > 0){
            // 发送邮件:前端会调用该路径下的方法并传递确认码参数
            String activationUrl = "http://localhost:8088/user/activation?confirmCode=" + confirmCode;
            sendMailForActivationAccount(activationUrl,user.getEmail());
            hm.put("code",200);
            hm.put("message","注册成功。请前往邮件进行账号激活");
        }else {
            hm.put("code",400);
            hm.put("message","注册失败");

        }
        return hm;
    }
    @Override
    @Transactional
    /*发送邮件申请激活账号:创建邮件,设置主题、发送者、接受者、发送日期、创建上下文环境(编写在        
    html)*/
    public void sendMailForActivationAccount(String activationUrl, String email) {
        // 创建邮件对象
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true);
            // 设置邮箱主题
            message.setSubject("抖音账号激活");
            // 设置邮件发送者
            message.setFrom(mailUsername);
            // 设置邮件接受者(可以设置多个)
            message.setTo(email);
            // 设置邮件发送日期
            message.setSentDate(new Date());
            // 创建上下文环境(正文) 用thymeleaf
            Context context = new Context();
            // 将url注入html中,在html中直接用
            // 当在页面点击链接时,会直接执行路径中方法
            context.setVariable("activationUrl",activationUrl);
            String text = templateEngine.process("activation-account.html",context);
            message.setText(text,true);

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
        // 发送邮件
        javaMailSender.send(mimeMessage);
    }
    @Override
    /*在注册阶段会调用该方法实现账号激活:根据注册阶段传递过来的确认码查询用户,调取用户信息
    判断是否是有效激活时间,返回结果*/
    public Map<String, Object> activation(String confirmCode) {
        Map<String, Object> hm = new HashMap<>();
        // 根据确认码查询用户
        User user = um.selectUserByConfirmCode(confirmCode);
        // 判断激活时间是否失效:现在时间是在激活时间之后吗
        boolean after = LocalDateTime.now().isAfter(user.getActivationTime());
        if(after){
            hm.put("code",400);
            hm.put("message","激活失效,请重启注册");
            return hm;
        }
        // 修改状态值
        int result = um.updateUserByConfirmCode(confirmCode);
        if(result > 0){
            hm.put("code",200);
            hm.put("message","激活成功");
            return hm;
        }else {
            hm.put("code",400);
            hm.put("message","激活失效,请联系管理员");
            return hm;
        }

    }
    
    @Override
    public int insertUser(User user) {
        return um.insert(user);
    }
    @Override
    public User selectUserByConfirmCode(String confirmCode) {
        return um.selectUserByConfirmCode(confirmCode);
    }
    @Override
    public int updateUserByConfirmCode(String confirmCode) {
        return um.updateUserByConfirmCode(confirmCode);
    }
    
    @Override
    public User selectUserByEmail(String email) {
        return um.selectUserByEmail(email);
    }
    
}
mapper
java 复制代码
public interface UserMapper extends BaseMapper<User> {
    /*
    * 根据确认码查询用户*/
    @Select("SELECT email,activation_time FROM user WHERE confirm_code = #{confirmCode} AND is_valid = 0")
    User selectUserByConfirmCode(@Param("confirmCode") String confirmCode);
    /*
    * 根据确认码查询用户并修改状态码为1*/
    @Update("UPDATE user SET is_valid = 1 WHERE confirm_code = #{confirmCode}")
    int updateUserByConfirmCode(@Param("confirmCode") String confirmCode);
    /*
    * 根据邮箱查询用户*/
    @Select("SELECT * FROM user WHERE email = #{email} AND is_valid = 1")
    User selectUserByEmail(@Param("email") String email);


}
控制层
java 复制代码
@Api("用户界面")
@RestController
@RequestMapping("user")
public class UserController {
    @Resource
    private UserService us;

    @ApiOperation(value = "注册账号")
    @PostMapping("create")
    public Map<String,Object> createAccount(@RequestBody User user){
        return us.createAccount(user);
    }
    @ApiOperation(value = "激活账号")
    @GetMapping("activation")
    /*通过邮件激活相当于网页传递数据。因为路径中追加了confirmCode所以会自动传参*/
    public Map<String,Object> activation(String confirmCode){
        return us.activation(confirmCode);
    }

}
前端代码

因为用的是thymeleaf写的所以目录结构如下(记得写在templates中)

注册页面
html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- 引入 jQuery -->
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <style>
    body {
      background: url('https://cdn.pixabay.com/photo/2018/08/14/13/23/ocean-3605547_1280.jpg') no-repeat;
      background-size: 100% 130%;
    }

    #login_box {
      width: 20%;
      height: 400px;
      background-color: #00000060;
      margin: auto;
      margin-top: 10%;
      text-align: center;
      border-radius: 10px;
      padding: 50px 50px;
    }

    h2 {
      color: #ffffff90;
      margin-top: 5%;
    }

    #input-box {
      margin-top: 5%;
    }

    span {
      color: #fff;
    }

    input {
      border: 0;
      width: 60%;
      font-size: 15px;
      color: #fff;
      background: transparent;
      border-bottom: 2px solid #fff;
      padding: 5px 10px;
      outline: none;
      margin-top: 10px;
    }

    button {
      margin-top: 50px;
      width: 60%;
      height: 30px;
      border-radius: 10px;
      border: 0;
      color: #fff;
      text-align: center;
      line-height: 30px;
      font-size: 15px;
      background-image: linear-gradient(to right, #30cfd0, #330867);
    }

    #sign_up {
      margin-top: 45%;
      margin-left: 60%;
    }

    a {
      color: #b94648;
    }
  </style>
</head>

<body>
<div id="login_box">
  <h2>REGISTRY</h2>
  <div id="input_box">
    <input type="text" id = "email" name="email" placeholder="请输入用户名">
  </div>
  <div class="input_box">
    <input type="password" id = "password" name="password" placeholder="请输入密码">
  </div>

  <button id = "registry">注册</button><br><br>

    <p>Come to us ? <a href="login">Login</a></p>

</div>
/*当id:registry发生点击行为thymeleaf会接受相应过来的数据并转换成json格式,然后调用url路径下的方法创建账号
  * result接收控制层返回的数据(Map)在网页提示创建成功或创建失败*/
<script type="text/javascript" charset="UTF-8">
  $("#registry").on("click",function (){
    $.ajax({
      url:"/user/create",
      type: "POST",
      contentType: "application/json",
      data: JSON.stringify({ 
        email: $("#email").val(),
        password: $("#password").val()
      }),
      dataType: "json",
      success: function(result){
        alert(result.message);
      },
      error: function(result){
        alert("发生错误");
      }
    });
  });
</script>
</body>
</html>
邮件正文:
html 复制代码
<html>
<body>
<!--根据自己需要编写,-->
<div>
    <p>Email 地址验证</p> <!--target:新的窗口打开超链接-->
    <p>这封信是由<a href="https://www.douyin.com" target = "_blank">抖音</a>发送的</p>
    <p>
        由于你在抖音进行了新用户注册或用户修改,如果你没有进行过此操作,请忽略这封邮件。如果你是新用户或者修改你的账号
        请点击下方链接:
    </p>
    <p>
        <a th:href="@{${activationUrl}}"><span th:text="${activationUrl}"></span></a>
        感谢你的访问,祝你生活愉快。
    </p>

</div>
</body>
</html>

登录代码

控制层

登录界面:http://localhost:8088/gameLogin/login

java 复制代码
@Api(value = "登录页面")
@Controller
@RequestMapping("gameLogin")
public class LoginController {
    @Resource
    private UserService us;
    @GetMapping("login") 
    public String login(){
        return "login";
    }
    @GetMapping("registry")
    public String registry(){
        return "registry";
    }
    @PostMapping("loginAccount")
    @ResponseBody
    public Map<String,Object> loginAccount(@RequestBody User user){
        return us.loginAccount(user);
    }
}
业务层:
java 复制代码
public interface UserService extends IService<User> {
    Map<String,Object> loginAccount(User user);
}
业务实现类:
java 复制代码
@Override
    /*
     * 登录账号*/
    public Map<String, Object> loginAccount(User user) {
        Map<String, Object> hm = new HashMap<>();
        User user1 = um.selectUserByEmail(user.getEmail());
        // 如果账号不存在或未激活
        if(user1 == null || user1.getIsValid() == (byte)0){
            hm.put("code",400);
            hm.put("message","该账户不存在或未激活");
            return hm;
        }
        // 进行密码比对
        String md5Pwd = SecureUtil.md5(user.getPassword()+user1.getSalt());
        if(!md5Pwd.equals(user1.getPassword())){
            hm.put("code",400);
            hm.put("message","用户名或密码错误");
            return hm;
        }
        hm.put("code",200);
        hm.put("message","登陆成功");
        return hm;
    }
前端代码
html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- 引入 jQuery -->
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <style>
    body {
      background: url('https://cdn.pixabay.com/photo/2018/08/14/13/23/ocean-3605547_1280.jpg') no-repeat;
      background-size: 100% 130%;
    }

    #login_box {
      width: 20%;
      height: 400px;
      background-color: #00000060;
      margin: auto;
      margin-top: 10%;
      text-align: center;
      border-radius: 10px;
      padding: 50px 50px;
    }

    h2 {
      color: #ffffff90;
      margin-top: 5%;
    }

    #input-box {
      margin-top: 5%;
    }

    span {
      color: #fff;
    }

    input {
      border: 0;
      width: 60%;
      font-size: 15px;
      color: #fff;
      background: transparent;
      border-bottom: 2px solid #fff;
      padding: 5px 10px;
      outline: none;
      margin-top: 10px;
    }

    button {
      margin-top: 50px;
      width: 60%;
      height: 30px;
      border-radius: 10px;
      border: 0;
      color: #fff;
      text-align: center;
      line-height: 30px;
      font-size: 15px;
      background-image: linear-gradient(to right, #30cfd0, #330867);
    }

    #sign_up {
      margin-top: 45%;
      margin-left: 60%;
    }

    a {
      color: #b94648;
    }
  </style>
</head>

<body>
<div id="login_box">
  <h2>LOGIN</h2>
  <div id="input_box">
    <input type="text" id="email" name="email" placeholder="请输入用户名">
  </div>
  <div class="input_box">
    <input type="password" id="password" name="password" placeholder="请输入密码">
  </div>

  <button id = "login">登录</button><br><br>

    <p>New to us ? <a href="registry">Registry</a></p>
</div>
<script type="text/javascript" charset="UTF-8">
  $("#login").on("click",function (){
    $.ajax({
      url:"/gameLogin/loginAccount",
      type: "POST",
      contentType: "application/json",
      data: JSON.stringify({ // 将对象转化为json格式
        email: $("#email").val(),
        password: $("#password").val()
      }),
      dataType: "json",
      success: function(result){
        alert(result.message);
        if(200 == result.code) {
          window.location.href = "https://www.douyin.com"
        }
      },
      error: function(result){
        alert("发生错误");
      }
    });
  });
</script>
</body>
</html>

自动登录

java 复制代码
package com.example.utils;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringBootConfiguration;

@SpringBootConfiguration
public class AutoStartLogin implements CommandLineRunner {
    @Override
    public void run(String ... args) {
        try {
            Runtime.getRuntime().exec("cmd /c start http://localhost:8088/gameLogin/login");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
相关推荐
·云扬·3 分钟前
Lambda 表达式详解
java·开发语言·笔记·学习·1024程序员节
2401_8570262338 分钟前
SpringBoot环境下的共享汽车管理策略
spring boot·后端·汽车
星叔1 小时前
ARXML汽车可扩展标记性语言规范讲解
java·前端·汽车
2401_857636391 小时前
SpringBoot赋能的共享汽车业务管理系统
数据库·spring boot·汽车
2401_857622661 小时前
共享汽车管理:SpringBoot技术实现与优化
spring boot·后端·汽车
2401_857600951 小时前
SpringBoot框架:共享汽车管理的创新工具
java·spring boot·汽车
夜色呦1 小时前
SpringBoot助力的共享汽车业务优化系统
spring boot·后端·汽车
代码小鑫1 小时前
A15基于Spring Boot的宠物爱心组织管理系统的设计与实现
java·开发语言·spring boot·后端·毕业设计·宠物
qq_171538851 小时前
深入 MyBatis-Plus 插件:解锁高级数据库功能
mybatis
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ1 小时前
mapper.xml 使用大于号、小于号示例
xml·java·数据库