基于Spring Boot框架的员工管理系统的设计与实现(开源项目——实现CRUD功能整体流程超详细)

提示:此项目仅作为本博主的学习笔记记录,不作为商品售卖,文中某个方法或单词或许会因为马虎写错,但本文重点讲的是思路,资源可找博主私聊


前言

CRUD是指在数据库中进行的基本操作,即创建(Create)、读取(Retrieve)、更新(Update)和删除(Delete)。
在编程中,这些操作对应着对数据库中数据的增删改查。
提示:此项目我用的是idea工具,具体的一些配置可以看下面的链接
计算机专业、软件技术、工程等软件专业同学电脑必配环境

如果想从零开始写请看下面的SpringBoot项目构建方式链接
SpringBoot项目构建方式
开始会有个初始压缩包,在这个初始压缩包内写代码
在这里插入图片描述
在这里插入图片描述

进入初始项目后看到项目结构:
请添加图片描述

用户看的是View层视图层,数据从Controller/Action层过来

Controller控制器通过接收前端传过来的参数进行业务操作,在返回一个指定的路径或者数据表直接调用Service,Service调用Mapper

Service层, 存放业务逻辑处理,也是一些关于数据库处理的操作,但不是直接和数据库打交道,他有接口还有接口的实现方法,在接口的实现方法中需要导入mapper层,mapper层是直接跟数据库打交道的,他也是个接口,只有方法名字,具体实现在mapper.xml文件里,service是供我们使用的方法

Service的 impl 文件将Mapper和Service进行整合

Model层=entity层=pojo层,存放我们的实体类,与数据库中的属性值基本保持一致,与Mapper层连接

mapper层=dao层,对数据库进行数据持久化操作(把数据放到持久化的介质中,同时提供增删改查操作), 他的方法语句直接针对数据库操作 。
mapper的接口对应resources下的xml文件,它只有方法名,封装了对数据库进行的数据持久化操作

其中还有个core文件夹,里面放的是工具类包括一些拦截器

在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

本文SpringBoot 框架代码编写流程(看个人习惯,无硬性标准)
1、画页面 HTML
2、编写控制层代码的方法:Action / Controller
3、编写数据持久层代码:Mapper + Mapper.xml(数据库)
4、编写业务层代码:Service + Impl
5、完善控制层代码的方法:Action / Controller

关于Thymeleaf 前端

目前Java比较流行的模板引擎有Thymeleaf和Freemarker,Thymeleaf的话更适合当前的人员分工问题,回忆一下以前的Jsp页面,必须要动态渲染才能看到真实的效果,写页面的和写后端的分工不太明确 。

Thymeleaf是动静分离的,页面中的动态标签是需要传递有数据的时候才会渲染,不然就是原本默认的静态的样子 。
Thymeleaf 快速入门
Thymeleaf 官网

后台做逻辑会有个绑定,传到前端设计的页面上,后台如果传过来数据就会用后台数据,如果后台没有数据,也能用静态的形式展示出来

common文件夹介绍

在这里插入图片描述
LoginInterceptor登录拦截器,用于阻止未登录用户访问系统

CrossOriginInterceptor拦截器

在MyInterceptorConfig配置,interceptor实际上也是一种filter的实现 ,这里注册CrossOriginInterceptor拦截器,注册LoginInterceptor拦截器。并且所有路径都被拦截,除了静态不拦截路径

//拦截器
@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// TODO Auto-generated method stub
		WebMvcConfigurer.super.addInterceptors(registry);
		// 注册CrossOriginInterceptor拦截器
		registry.addInterceptor(new CrossOriginInterceptor());
		// 注册LoginInterceptor拦截器
		InterceptorRegistration registration = registry.addInterceptor(new LoginInterceptor());
		registration.addPathPatterns("/**"); // 所有路径都被拦截
		registration.excludePathPatterns( // 添加不拦截路径
				"/", // 首页
				"/user/login", // 登录
				"/user/addUser", // 注册
				"/user/checkUsername", // 检查用户名
				"/**/*.html", // html静态资源
				"/**/*.js", // js静态资源
				"/**/*.css", // css静态资源
				"/test/**" // css静态资源
		);	
	}

关于首页静态资源

所有静态资源都需要thymeleaf接管

可以在resources下创建目录处理静态资源,目录优先级是:resources > static(默认)> public

测试:将静态资源文件放到resources/static/public或者**/****目录下资源都可以被访问, 比如在static下创建1.js文件,可以被访问localhost:8080/springbootdemo/1.js

模板引擎: 将 html 页面放在 resources/templates 包下 ,在templates目录下的所有页面,可以通过controller来跳转。

项目里使用了thymeleaf,所以得在pom.xml文件里加入thymeleaf 相关依赖

 <dependency>
     <groupId>org.thymeleaf</groupId>
     <artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>

<!--------- 或者 --------->

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

一、SpringBoot整合Mybatis

Mybatis简介

1、添加Mybatis的起步依赖

整合MyBatis

<!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>

添加数据库驱动坐标

<!-- MySQL连接驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

2、添加数据库连接信息

application-dev.yaml中添加数据量的连接信息,因为在application.yaml中配置了active: dev,所以生产环境application-pro.yaml不用管,只需要改application-dev.yaml

代码如下(示例):

# 开发环境
spring:
  #数据源配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/staff?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false
    username: root
    password: root
    hikari:
      maximum-pool-size: 2
      minimum-idle: 2

#mybatis配置
mybatis:
  #mapper配置文件
  config-location: classpath:mybatis-config.xml
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: cn.springbootdemo.model

3、创建实体Bean

接下来创建model层的User实体类

第一种:创建User实体类

我用的是这种
把数据库表里的字段定义一下变量,鼠标右键生成 get、set方法,重写toString方法
在这里插入图片描述

package cn.springbootdemo.model;

public class  User {
	private int userid;
	private String username;
	private String password;
	private String realname;
	private String birthdate;
	private String gender;
	private String interest;
	private String degree;
	private String intro;
	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 String getRealname() {
		return realname;
	}
	public void setRealname(String realname) {
		this.realname = realname;
	}
	public String getBirthdate() {
		return birthdate;
	}
	public void setBirthdate(String birthdate) {
		this.birthdate = birthdate;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public String getInterest() {
		return interest;
	}
	public void setInterest(String interest) {
		this.interest = interest;
	}
	public String getDegree() {
		return degree;
	}
	public void setDegree(String degree) {
		this.degree = degree;
	}
	public String getIntro() {
		return intro;
	}
	public void setIntro(String intro) {
		this.intro = intro;
	}
	@Override
	public String toString() {
		return "User [userid=" + userid + ", username=" + username + ", password=" + password + ", realname=" + realname
				+ ", birthdate=" + birthdate + ", gender=" + gender + ", interest=" + interest + ", degree=" + degree
				+ ", intro=" + intro + "]";
	}

}

第二种:创建User实体类

另外(为了方便使用先把lombok导入,在pom.xml中文件中加)

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

User实体类

package cn.springbootdemo.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data   //加了这个注解get、set方法就不用写了
@NoArgsConstructor
@AllArgsConstructor   //无参构造和全参构造可以不加
public class  User {
	private int userid;
	private String username;
	private String password;
	private String realname;
	private String birthdate;
	private String gender;
	private String interest;
	private String degree;
	private String intro;
	@Override   //重写toString
	public String toString() {
		return "User [userid=" + userid + ", username=" + username + ", password=" + password + ", realname=" + realname
				+ ", birthdate=" + birthdate + ", gender=" + gender + ", interest=" + interest + ", degree=" + degree
				+ ", intro=" + intro + "]";
	}
}

4、编写Mapper

注意:@Mapper标记该类是一个mybatis的mapper接口,可以被spring boot自动扫描到spring上下文中

与启动类同一级别创建mapper文件夹创建UserMapper接口
在这里插入图片描述

package cn.springbootdemo.mapper;

import cn.springbootdemo.model.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Mapper//使用@Mapper注解,表示这是操作数据库的mapper,SpringBoot自动扫描
//也可以在启动类里使用MapperScan("cn.springbootdemo.mapper")注解,参数是包名,一个效果
// Dao层,所以可以使用@Repository,当然也可以使用Component注解,不写也OK
@Repository
public interface UserMapper {

    void addUser(User user);//注册

}

5、配置Mapper映射文件

在resources文件夹下创建mapper文件夹,并创建UserMapper.xml文件
在这里插入图片描述

Mybatis中文文档官网:https://mybatis.net.cn/getting-started.html

其中:

1、namespace命名空间必须与@Mapper注解的Mapper接口的全类名一致
这里的全类名要去UserMapper.java里面去找://全类名: cn.springbootdemo.mapper.UserMapper
其中cn.springbootdemo.mapper就是第一行package后面的包
然后UserMapper是这个.java的接口名

2、xml文件名必须与@Mapper注解的接口名一致
3、标签中的 id必须与@Mapper注解的的接口中的方法名一致,且参数一致

这里需要确认:整合对应application-dev.yaml里type-aliases-package别名扫描包、mapper-locations 定义mapper位置 ,即加载Mybatis映射文件

<?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="cn.springbootdemo.mapper.UserMapper">
        <insert id="addUser" parameterType="User">
            insert into demo_users
            values(null,#{username},#{password},#{realname},#{birthdate},#{gender},#{interest},#{degree},#{intro})
        </insert>
</mapper>

接下来写service,定义一个UserService接口
在这里插入图片描述

@Service
public interface UserService {
    int addUser(User user);

    List<User> getUserList(User user);
}

然后对应着写接口的实现类UserServiceImpl
在这里插入图片描述

但是service.impl下的两个文件是有层级关系的,我们把UserService放在上一层
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

最后:
在这里插入图片描述

6、定义controller

定义service(以addUser为例) service.impl.UserServiceImpl

刚才在UserMapper.java中有个addUser注册方法,然后这个注册方法映射到UserMapper.xml里面执行了SQL语句

@Service //使用@Service注解,SpringBoot自动扫描
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper mapper;
    
    @Override
    public int addUser(User user) {
        //默认执行成功
        mapper.addUser(user);
        return 0;
    }
}

7、创建UserAction类

@Controller
@RequestMapping("/user")
public class UserAction {
      @Autowired
      private UserService userService;

      @RequestMapping("/addUser")
      public String addUser(User user, Map<String,String> m) {
          int f = userService.addUser(user);
          if (f == 0) {
              m.put("msg","注册成功");
          }
          return "login";
      }
}

现在我们运行一下看看结果
请添加图片描述

其中出生日期这里是可以选时间的,这里用了一个日期的校验,在home.html里
在这里插入图片描述

点击确定后显示的页面:
在这里插入图片描述

点击登录显示页面:
在这里插入图片描述

回到数据库可视化页面可以看到我刚刚加的这条数据:
在这里插入图片描述

如果数据库里没有更新数据,那就去数据库配置里面看:
数据库名字或密码改没改
在这里插入图片描述

二、做首页

①、新建HomeAction类

首先在action文件夹内新建HomeAction类
SpringBoot中Controller控制层重要注解

@Controller
@RequestMapping("/") //URL
public class HomeAction {
    @RequestMapping("/")// 直接访问http://localhost:8080/
    public String home(){
        return "home";
    }

    @RequestMapping("/login")// 访问http://localhost:8080/login
    public String login(){
        return "login";
    }
}

现在应该能显示首页了
请添加图片描述

②、将页面转化为Thymeleaf形式

现在是单纯的HTML页面,接下来把他转化为Thymeleaf形式,首先加入thymeleaf模板

<!doctype html>
<html lang="ch" xmlns:th="http://www.thymeleaf.org"> 

</html>

我们回到首页home.html
把第2行的<html>改成<html lang="ch" xmlns:th="http://www.thymeleaf.org">

把第18行的本地文件
<link rel="stylesheet" type="text/css" media="all" href="../static/daterangepicker/daterangepicker.css" />
改成Thymeleaf形式的:
<link rel="stylesheet" type="text/css" media="all" th:href="@{/daterangepicker/daterangepicker.css}" />

同样在22行把script src里面的内容也改成Thymeleaf形式的:<script th:src="@{/js/functions.js}"></script>

接下来把我们把from表单中的确定按钮的onclick事件去掉(大约在172行),然后把类型button改成submit,当点击确定的时候就相当于把后台服务器 type类型进行提交

//原来代码:
<button class="btn btn-primary" type="button" onclick="addUser()">确定</button>
//更改代码:
<button class="btn btn-primary" type="submit">确定</button>

当我们点击确定的时候,我们得把表单目的地址写上,回到 from表单起点位置(大约在41行),当点确定的时候需要对表单进行一个提交

//原来代码:
<form class="form" id="regForm"
//更改代码:
<form class="form" id="regForm" th:method="post" th:action="@{/user/addUser}">

现在就把home页面改造成了Thymeleaf形式了


home.html文件中用到了cdn加速(内容分发网络) 知识
就是一个文件在全国各地都有服务器,可以用cdn的技术进行就近分配,以速度最优为原则;也有图片优化等等。需要的话可以进下面网址找相应版本
cdn加速
在这里插入图片描述

③、javascript的编写

这里说的是验证的功能,做表单的时候一定要进行校验,小心被攻击,尤其是SQL注入的时候

<script type="text/javascript">
	$(function () {
		$("#regForm").bootstrapValidator({
			message: 'This value is not valid',
			feedbackIcons: {
				valid: 'glyphicon glyphicon-ok',
				invalid: 'glyphicon glyphicon-remove',
				validating: 'glyphicon glyphicon-refresh'
			},
			fields: {
				username: {
					message: '用户名验证失败',
					validators: {
						notEmpty: {
							message: '用户名不能为空'
						}
					}
				},
				password: {
					message: '密码验证失败',
					validators: {
						notEmpty: {
							message: '密码不能为空'
						}
					}
				},
				password1: {
					message: '密码确认验证失败',
					validators: {
						notEmpty: {
							message: '密码确认不能为空'
						}
					}
				},
				realname: {
					message: '姓名验证失败',
					validators: {
						notEmpty: {
							message: '姓名不能为空'
						}
					}
				}
			}
		});
	});

	$(document).ready(function () {
		$("#regForm #username").blur(checkName);
	});

	function checkName() {
		var username = $("#regForm #username").val();
		if (username) {
			$.post("./user/checkUsername",
					{username: username},
					function (data) {
						if (data.result == "yes") {
							$("#result").html("<p class='text-success'>恭喜您,用户名未被注册,请继续!</p>");
						} else {
							$("#result").html("<p class='text-danger'>对不起,用户名已被注册,请更换!</p>");
						}
					});

			/* $.ajax({
                url : "${pageContext.request.contextPath}/user/checkName",
                type : "post",
                // data表示发送的数据
                data :JSON.stringify({username:username}),
                // 定义发送请求的数据格式为JSON字符串
                contentType : "application/json;charset=UTF-8",
                //定义回调响应的数据格式为JSON字符串,该属性可以省略
                dataType : "json",
                //成功响应的结果
                success : function(data){
                    if(data.result){
                        $("#result").html("<p class='text-success'>恭喜您,用户名未被注册,请继续!</p>");
                    }else{
                        $("#result").html("<p class='text-danger'>对不起,用户名已被注册,请更换!</p>");
                    }
                }
            }); */
		}
	}
</script>

完整的home.html代码

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Insert title here</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Hello, Bootstrap Table!</title>
    <!-- 最新 Bootstrap4 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css">

    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js"></script>
    <!-- bootstrap.bundle.min.js 用于弹窗、提示、下拉菜单,包含了 popper.min.js -->
    <script src="https://cdn.staticfile.org/popper.js/1.16.0/umd/popper.min.js"></script>
    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
    <script src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
    <!-- DaterangePicker -->
    <link rel="stylesheet" type="text/css" media="all" th:href="@{/daterangepicker/daterangepicker.css}"/>
    <!-- BootStrapValidator -->
    <link rel="stylesheet"
          href="https://cdn.bootcss.com/jquery.bootstrapvalidator/0.5.3/css/bootstrapValidator.min.css">
    <script type="text/javascript"
            src="https://cdn.bootcss.com/jquery.bootstrapvalidator/0.5.3/js/bootstrapValidator.min.js"></script>
    <script th:src="@{/js/functions.js}"></script>
    <script type="text/javascript">
        $(function () {
            $("#regForm").bootstrapValidator({
                message: 'This value is not valid',
                feedbackIcons: {
                    valid: 'glyphicon glyphicon-ok',
                    invalid: 'glyphicon glyphicon-remove',
                    validating: 'glyphicon glyphicon-refresh'
                },
                fields: {
                    username: {
                        message: '用户名验证失败',
                        validators: {
                            notEmpty: {
                                message: '用户名不能为空'
                            }
                        }
                    },
                    password: {
                        message: '密码验证失败',
                        validators: {
                            notEmpty: {
                                message: '密码不能为空'
                            }
                        }
                    },
                    password1: {
                        message: '密码确认验证失败',
                        validators: {
                            notEmpty: {
                                message: '密码确认不能为空'
                            }
                        }
                    },
                    realname: {
                        message: '姓名验证失败',
                        validators: {
                            notEmpty: {
                                message: '姓名不能为空'
                            }
                        }
                    }
                }
            });
        });

        $(document).ready(function () {
            $("#regForm #username").blur(checkName);
        });

        function checkName() {
            var username = $("#regForm #username").val();
            if (username) {
                $.post("./user/checkUsername",
                    {username: username},
                    function (data) {
                        if (data.result == "yes") {
                            $("#result").html("<p class='text-success'>恭喜您,用户名未被注册,请继续!</p>");
                        } else {
                            $("#result").html("<p class='text-danger'>对不起,用户名已被注册,请更换!</p>");
                        }
                    });

                /* $.ajax({
                    url : "${pageContext.request.contextPath}/user/checkName",
                    type : "post",
                    // data表示发送的数据
                    data :JSON.stringify({username:username}),
                    // 定义发送请求的数据格式为JSON字符串
                    contentType : "application/json;charset=UTF-8",
                    //定义回调响应的数据格式为JSON字符串,该属性可以省略
                    dataType : "json",
                    //成功响应的结果
                    success : function(data){
                        if(data.result){
                            $("#result").html("<p class='text-success'>恭喜您,用户名未被注册,请继续!</p>");
                        }else{
                            $("#result").html("<p class='text-danger'>对不起,用户名已被注册,请更换!</p>");
                        }
                    }
                }); */
            }
        }

    </script>
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-12">
            <div class="text-center">
                <a type="button" class="btn btn-outline-info" th:href="@{/user/getUserListWithPage}">查看所有用户信息</a>
            </div>
        </div>
    </div>
    <hr>

    <div class="row">
        <div class="col-md-10 offset-md-1">
            <form class="form" id="regForm" th:method="post" th:action="@{/user/addUser}">
                <div class="modal-header">
                    <h4 class="modal-title">请填写注册信息</h4>
                </div>
                <div class="modal-body">
                    <div class="form-group row">
                        <div class="col-md-2">
                            <label for="username">用户名</label>
                        </div>
                        <div class="col-md-6">
                            <input type="text" id="username" name="username"
                                   class="form-control input-sm" placeholder="用户名" required/> <span
                                id="result"></span>
                        </div>
                    </div>
                    <div class="form-group row">
                        <div class="col-md-2">
                            <label for="password">密码</label>
                        </div>
                        <div class="col-md-6">
                            <input type="password" id="password" name="password"
                                   class="form-control input-sm" placeholder="密码" required/>
                        </div>
                    </div>

                    <div class="form-group row">
                        <div class="col-md-2">
                            <label for="password1">密码确认</label>
                        </div>
                        <div class="col-md-6">
                            <input type="password" id="password1" name="password1"
                                   class="form-control input-sm" placeholder="密码确认" required/>
                        </div>
                    </div>

                    <div class="form-group row">
                        <div class="col-md-2">
                            <label for="realname">姓名</label>
                        </div>
                        <div class="col-md-6">
                            <input type="text" id="realname" name="realname"
                                   class="form-control input-sm" placeholder="姓名"/>
                        </div>
                    </div>

                    <div class="form-group row">
                        <div class="col-md-2">
                            <label for="birthdate">出生日期</label>
                        </div>
                        <div class="col-md-6">
                            <input type="text" id="birthdate" name="birthdate"
                                   class="form-control input-sm">
                            <script type="text/javascript"
                                    src="./daterangepicker/require.js"
                                    data-main="./daterangepicker/main.js"></script>
                        </div>
                    </div>

                    <div class="form-group row">
                        <div class="col-md-2">
                            <label for="gender">性别</label>
                        </div>
                        <div class="col-md-6">
                            <div class="form-check form-check-inline">
                                <input type="radio" class="form-check-input" name="gender"
                                       value="1" checked> <label class="form-check-label"
                                                                 for="gender"></label>
                            </div>
                            <div class="form-check form-check-inline">
                                <input type="radio" class="form-check-input" name="gender"
                                       value="0"> <label class="form-check-label"
                                                         for="gender"></label>
                            </div>
                        </div>
                    </div>

                    <div class="form-group row">
                        <div class="col-md-2">
                            <label for="interest">爱好</label>
                        </div>
                        <div class="col-md-6">
                            <div class="form-check form-check-inline">
                                <input type="checkbox" class="form-check-input" name="interest" value="旅游">
                                <label class="form-check-label" for="interest">旅游</label>
                            </div>
                            <div class="form-check form-check-inline">
                                <input type="checkbox" class="form-check-input" name="interest" value="登山">
                                <label class="form-check-label" for="interest">登山</label>
                            </div>
                            <div class="form-check form-check-inline">
                                <input type="checkbox" class="form-check-input" name="interest" value="健身">
                                <label class="form-check-label" for="interest">健身</label>
                            </div>
                            <div class="form-check form-check-inline">
                                <input type="checkbox" class="form-check-input" name="interest" value="上网">
                                <label class="form-check-label" for="interest">上网</label>
                            </div>
                            <div class="form-check form-check-inline">
                                <input type="checkbox" class="form-check-input" name="interest" value="游泳">
                                <label class="form-check-label" for="interest">游泳</label>
                            </div>
                        </div>
                    </div>

                    <div class="form-group row">
                        <div class="col-md-2">
                            <label for="degree">学历</label>
                        </div>
                        <div class="col-md-6">
                            <select id="degree" name="degree" class="form-control">
                                <option value="0" selected>--请选择--</option>
                                <option value="1">高中</option>
                                <option value="2">专科</option>
                                <option value="3">本科</option>
                                <option value="4">研究生</option>
                            </select>
                        </div>
                    </div>

                    <div class="form-group row">
                        <div class="col-md-2">
                            <label for="intro">自我介绍</label>
                        </div>
                        <div class="col-md-6">
                            <textarea name="intro" rows="5" cols="20" class="form-control"></textarea>
                        </div>
                    </div>
                </div>
                <div class="modal-footer">
                    <div class="form-group">
                        <div class="text-center">
                            <button class="btn btn-primary" type="submit">确定</button>
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                            <button class="btn btn-secondary" type="reset">重置</button>
                        </div>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>
</body>
</html>

1、注册页面的完善(增)

接下来我们把注册功能完善下,因为用户注册后不可能去看数据库,我们要有个显示页面,显示注册成功还是失败,而且在注册时我们是默认他是注册成功的,实际情况下注册的用户名是一不一样? 注册完后还有个返回首页,注册成功后要有个登录功能

1、我们先写注册失败的代码,在UserAction里面:

 public String addUser(User user, Map<String,String> m) {
          int f = userService.addUser(user);
          if (f == 0) {
              m.put("result","yes");
              m.put("msg","注册成功");
          }else if(f==1){
              m.put("result","no");
              m.put("msg","注册失败,用户名重复");
          }else {
              m.put("result","no");
              m.put("msg", "注册失败,数据库错误");
          }
          return "login";
      }

我们之前写得 f==0,f在userService里来的,userService这有个addUser方法
之前addUser只是返回0,现在我们让他返回1或2

2、我们回到UserService:
UserService已经有一个addUser接口了,他具体的实现在UserServiceImpl内
在这里插入图片描述

我们就去看UserServiceImpl,在这里面我们要加一些其他的方法
比如先看注册失败,用户名重复,这个错误
在里面加个try catch语句,如果有错误就用catch语句捕获这个Exception异常并打印

3、我们先判断这个数据库有没有这个用户,对数据库进行一个查询操作
在mapper包下的UserMapper接口中加入下面代码

 //查询有没有这个用户:0011
    int existUser(User user);///1、使用count查以0011为名字的用户
    User existsUser(User user);//2、查以0011为名字的用户

接下来去UserMapper.xml里面写数据库查询操作语句
先写第一个:使用count查以0011为名字的用户

    <select id="existUser" parameterType="User" resultType="int">
        select count(*) from demo_users where username = #{username}
    </select>
     <!--第一个:使用count查以0011为名字的用户,上面的username是变量-->

但是查询语句对不对呢?这时候可以打开idea内显示图形化页面,然后把查询语句复制进去验证
在这里插入图片描述
值得注意的是:select count(*) from demo_users where username = #{username}中的 #{username}是个变量
比如说我们查询以0011为名字的:select count(*) from demo_users where username = '0011'
在这里插入图片描述

count这里返回1,说明有一个用户的名字是0011
当然count也可以不做统计,把以0011做名字的用户返回回来:select * from demo_users where username = '0011'
在这里插入图片描述
下面接着写第二个:查以0011为名字的用户

    <select id="existsUser" parameterType="User" resultType="User">
        select userid,username from demo_users where username=#{username} and password=#{password}
    </select>
    <!--第二个:查以0011为名字的用户,username和password是变量,
    在图形化页面中的查询语句是:select userid,username from demo_users where username='0011' and password='0011'
    -->

4、现在我们就可以在UserServiceImpl 里面写 try catch语句了,当然前面写得默认注册成功就要删掉了

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper mapper;
    @Override
    public int addUser(User user) {
      //  默认执行成功
      //  mapper.addUser(user);
      //  return 0;
        try{
            //如果你的数据库没有这个用户返回0,否则返回1
            if(mapper.existUser(user)==0){
                return 0;  //用户不存在,可以注册
            }else{
                return 1;  //用户存在,不可注册
            }
        }catch (Exception e){
            e.printStackTrace();
            return 2; //如果报错返回2
        }
    }

    @Override
    public List<User> getUserList(User user) {
        return null;
    }
}

5、现在注册功能就写得差不多了,但是在UserAction中我们写的是返回login页面,我们应该让他返回到 result结果页面
我是复制的home.html,再粘贴到user文件夹下,重命名为:result.html
请添加图片描述
所以在UserAction最后一行返回login改成:return "user/result";
把 result.html里面的代码改成:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
	<title>Insert title here</title>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
	<title>Hello, Bootstrap Table!</title>
	<!-- 最新 Bootstrap4 核心 CSS 文件 -->
	<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css">

	<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
	<script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js"></script>
	<!-- bootstrap.bundle.min.js 用于弹窗、提示、下拉菜单,包含了 popper.min.js -->
	<script src="https://cdn.staticfile.org/popper.js/1.16.0/umd/popper.min.js"></script>
	<!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
	<script src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
	<!-- DaterangePicker -->
	<link rel="stylesheet" type="text/css" media="all" th:href="@{/daterangepicker/daterangepicker.css}"/>
	<!-- BootStrapValidator -->
	<link rel="stylesheet"
		  href="https://cdn.bootcss.com/jquery.bootstrapvalidator/0.5.3/css/bootstrapValidator.min.css">
	<script type="text/javascript"
			src="https://cdn.bootcss.com/jquery.bootstrapvalidator/0.5.3/js/bootstrapValidator.min.js"></script>
	<script th:src="@{/js/functions.js}"></script>

</head>
<body style="margin: 200px">
<div class="container-fluid">
	<div class="row">
		<div class="m-auto">
			<p class = "text-success" th:if="${result=='yes'}"><span th:text="${msg}"></span></p>
			<p class = "text-danger" th:if="${result=='no'}"><span th:text="${msg}"></span></p>
		</div>
	</div>
</div>
</body>
</html>

这时候我们再重新运行下,再注册一个数据库里有的名字
在这里插入图片描述
点击确定后:
在这里插入图片描述

6、现在注册不成功的结果出来了,但是页面太简单了,起码有个跳转加个超链接,不可能让用户按左上角返回箭头返回,无论注册成功与否都要有个超链接,让他跳转一下
所以接着写result.html页面:

	<div class = "row">
		<div class="m-auto">
			<a th:href="@{/}">返回首页</a>
			<a th:href="@{/user/getUserList}">查看所有用户</a>
		</div>
	</div>

然后就多了这两个超链接,点进去后他们显示的页面也分别放在了下面
在这里插入图片描述

在点查看用户的时候显示的是:
{“login”:“请先登录”,“redirUrl”:“/user/getUserList”}
要求先登录,跳转的路径是/user/getUserList,假如要在做其他的东西,必须要把login这个功能做了,否则他都会拦截
在common文件夹里有个LoginInterceptor.java(拦截器功能)
在这里插入图片描述

在新的页面中可以看到:他的要求就是请先登录
在这里插入图片描述

2、登录功能(查)

我们先把LoginInterceptor.java(拦截器功能)里面最后几行注释掉,这几行是输出流的功能
需要注释的代码:
在这里插入图片描述
我们在这注释代码下面做一个跳转到登录页面的功能:

arg0.getRequestDispatcher("login").forward(arg0,arg1);

再运行下:
还是先显示注册页面,添加信息
在这里插入图片描述
然后这次点击查看所有用户
在这里插入图片描述
然后就跳转到 login页面了
在这里插入图片描述

注册前的检测

这个功能就是在你注册这个用户前检测数据库有没有这个用户名
这个功能的实现的逻辑在home.html页面内
在这里插入图片描述
1、我们回到UserAction里写checkUsername这个函数

    @ResponseBody
    @RequestMapping("/checkUsername")
    public Map<String, String> checkUsername(User user) {
        System.out.println("checkUsername=================" + user);
        boolean f = userService.checkUsername(user); //可以注册
        Map<String, String> m = new HashMap<String,String>();
        if (f) {
            m.put("result", "yes");
            m.put("msg", "");
        } else {
            m.put("result", "no");
            m.put("msg", "对不起,该用户名已存在,请更换");
        }
        System.out.println("checkUsername : " + m);
        return m;
    }

2、这时候我们可以看到checkUsername这里有个报错,我们把鼠标放上去后点击红色的提示,在UserService里面创建这个checkUsername方法,它会自动生成
自动生成的那行代码的意思是:根据用户名判断是否有该用户,如果没有则可以注册
在这里插入图片描述
3、这时候UserServiceImpl类中有个报错,我们【Alt+回车】导入这个方法即可
然后在这里面写个简单的逻辑:
如果existUser(user)==0就是没有注册,如果 !=0 就是已经注册了

  @Override
    public boolean checkUsername(User user) {
        if(mapper.existUser(user)==0){
            return true;
        }else{
        return false;
        }
    }

运行截图:
在这里插入图片描述
在这里插入图片描述

登录功能的编写

1、我们现在统一一下 login.html页面
完整的 login.html代码

里面就是一个表单和俩按钮

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Insert title here</title>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title></title>
    <!-- 最新 Bootstrap4 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css">
    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js"></script>
    <!-- bootstrap.bundle.min.js 用于弹窗、提示、下拉菜单,包含了 popper.min.js -->
    <script src="https://cdn.staticfile.org/popper.js/1.16.0/umd/popper.min.js"></script>
    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
    <script src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
    <script th:src="@{/js/functions.js}"></script>
    <script type="text/javascript" th:inline="javascript">
        $(document).ready(
            function () {
                $('#loginFormModal').modal();
            }
        );
    </script>
</head>
<body>
<div class="modal fade" id="loginFormModal" role="dialog" aria-hidden="true" aria-labelledby="myModalLabel">
    <div class="modal-dialog">
        <div class="modal-content">  <!-- 对loginForm这个表单进行提交,提交方式是post,提交路径是/user/login -->
            <form class="form-signin" id="loginForm" th:method="post" th:action="@{/user/login}">
                <div class="modal-header">
                    <h5 class="modal-title" id="myModalLabel">用户登录</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <label for="username" class="sr-only">用户名</label>
                    <input type="text" id="username" name="username" class="form-control"
                           placeholder="用户名" required autofocus>
                    <label for="password" class="sr-only">密码</label>
                    <input type="password" id="password" name="password" class="form-control"
                           placeholder="密码" required>
                    <div class="text-danger" th:text="${login!='yes'?login:''}"></div>
                </div>
                <div class="modal-footer">

                    <button class="btn btn-primary" type="submit" id="loginBtn">登录</button>
                    <button class="btn btn-secondary" type="button" data-dismiss="modal">关闭窗口</button>
                </div>
            </form>
        </div>
    </div>
</div>
</body>
</html>

我们现在需要写一个http://localhost:8080/springbootdemo/user/login这样的URL,到这个里面写逻辑

2、我们直接进到action这个页面,写user/login这个逻辑

  1. 查数据库有没有这个人
  2. 如果有就登入,登录信息存起来,跳转到目标页
  3. 没有还得回到登录页

因为我们在UserMapper接口里面已经定义完了,所以我们先进到UserService接口里面查有没有这个人
在这里插入图片描述
3、UserService接口内新增代码:User existsUser(User user);

然后到UserServiceImpl实现类里面【Alt+回车】把这个方法加进来
其实就是向数据库查,查有没有这个人,查询的语句写过了,我们调用一下就行:return mapper.existsUser(user);

4、现在就可以到 action里面写逻辑了

//登录功能
    @RequestMapping("/login") //目标地址
    public String login(User user, HttpSession session, Map<String, String> m) {
        //1、查数据库有没有这个人
        User dbUser=userService.existsUser(user);
        //2、如果有就登入,登录信息存起来,跳转到目标页
        if(dbUser !=null){
            session.setAttribute(Constants.LOGIN_USER,dbUser);  //存起来
            m.put("login","yes");
           String redirUrl = (String) session.getAttribute(Constants.ORIGINAL_URL);
           return "/redirect"+redirUrl;
        }else{
        //3、没有还得回到登录页
            m.put("login",Constants.LOGIN_ERR);
        return "/login";
        }
    }

其中Constants. 后面的名字在core文件夹下的Constants类里面找,或者在这里面改
在这里插入图片描述

运行后查看所有用户后登录:
在这里插入图片描述

3、显示用户表格页面(查)

紧接上图,因为user/getUserList还没写,他就是向后台拿所有的用户信息,把所有的用户拿到后存到一个list里面,然后通过前端Thymeleaf把他渲染出来

1、我们接着去UserAction里面去写getUserList

    @RequestMapping("/getUserList")
    public String getUserList(User user, Map<String, List<User>> m) {
        //向数据库查询user信息,存储到list里,再把list放到map里
         return "user/userList";
    }

2、我们现在还没有 userList页面,需要创建一个
我直接就把 user文件夹下的 result.html复制了一下,重新粘回 user文件夹下,重命名为:userList.html
在这里面随便写点东西,看看能不能返回
在运行程序后,填写注册信息后点击确定,选择查看所有用户
在这里插入图片描述
可以看到里面已近有返回了

3、我们接着写UserAction里的逻辑,我们向数据库查,是操作xml文件,在这里面进行数据库的增删改查,对应的Mapper接口文件里定义查询规则

首先在mapper文件夹下的UserMapper里面定义规则 List

    List<User> getUserList(User user); //查询数据库里面所有用户信息

4、然后到UserMapper.xml 里面写查询语句:
我们不仅要查全部的,还要有模糊查询(用户名、性别)

    <select id="getUserList" parameterType="User" resultType="User">
        select  * from demo_users
        <where>
            <if test = "username != null and username != ''">
                and username like concat('%',#{username},'%')
                  <!-- SELECT * FROM demo_users WHERE username LIKE CONCAT('%','a','%')
                    这条语句是在图形可视化页面查找用户名带a的 -->
            </if>
            <if test = "gender != null and gender != ''">
                and gender = #{gender}
            </if>
        </where>
    </select>

5、接着就在service定义接口,然后在接口实现类把他的逻辑写出来
首先在service文件夹下的UserService接口里面写接口:

List<User> getUserList(User user);//查询用户信息,存到list里

然后在实现类impl文件夹下的UserServiceImpl里面(导包),把返回值改一下:

return mapper.getUserList(user);

6、接着回到controller里面写逻辑

    @RequestMapping("/getUserList")
    public String getUserList(User user, Map<String, List<User>> m) {
        //向数据库查询user信息,存储到list里,再把list放到map里
        //Mapper定义规则List<User>,在xml里查询
        List<User> userList = userService.getUserList(user);
        System.out.println("userList----:"+userList);//sout快捷键
        return "user/userList";
    }

随后我们运行程序,输入注册信息后点击查看所有用户,再点击登录:
能显示页面
并且回到控制台看到有输出,证明已经从后台已经读到user了,并且存到list了
在这里插入图片描述

现在已经拿到userList了,接着存到map里面
在 return “user/userList”; 上面写:

        m.put("userList",userList);
        System.out.println("m----:"+m);//sout快捷键

随后我们运行程序,输入注册信息后点击查看所有用户,再点击登录:
能显示页面
并且回到控制台看到m也有输出
在这里插入图片描述

7、下面就到前端去做userList页面渲染
这里用到了bootstrap表格

<body style="margin: 200px">
<div class="container-fluid" >
	<div class="row">
		<div class="col-md-12" >
			<table class="table table-bordered">
				<caption>边框表格布局</caption>
				<thead>
				<tr>
					<th>用户名</th>
					<th>真名</th>
					<th>生日</th>
					<th>性别</th>
					<th>兴趣爱好</th>
					<th>学历</th>
					<th>自我介绍</th>
					<th>操作</th>
				</tr>
				</thead>
				<tbody>
				<tr>
					<td>Tanmay</td>
					<td>Bangalore</td>
					<td>560001</td>
					<td>Tanmay</td>
					<td>Bangalore</td>
					<td>560001</td>
					<td>Tanmay</td>
					<td>Bangalore</td>
				</tr>
				</tbody>
			</table>
		</div>
	</div>
</div>
</body>

刚才在controller里面已经能从数据库查的数据,这个userList,这个数据拿到后已经能存到map里面了,而且map在做页面跳转的时候通过键值对的形式已经把userList传递给user/userList页面了
我们拿到数据后对userList做循环(对数据做循环):th:each="tag:${user.getTags()}"

所以userList页面里面的body代码改成:

<body style="margin: 200px">
<div class="container-fluid" >
	<div class="row">
		<div class="col-md-12" >
			<table class="table table-bordered">
				<caption>边框表格布局</caption>
				<thead>
				<tr>
					<th>序号</th>
					<th>用户名</th>
					<th>真名</th>
					<th>生日</th>
					<th>性别</th>
					<th>兴趣爱好</th>
					<th>学历</th>
					<th>自我介绍</th>
					<th>操作</th>
				</tr>
				</thead>
				<tbody>
				<tr th:each="user,stat:${userList}">
					<td th:text="${stat.count}">1</td>
					<td th:text="${user.username}">Tanmay</td>
					<td th:text="${user.realname}">二哈喇子</td>
					<td th:text="${user.birthdate}">2022-09-08</td>
					<td th:text="${user.gender == '1'?'男':'女'}">1</td>
					<td th:switch="${user.degree}">
						<span th:case="'0'">高中</span>
						<span th:case="'1'">专科</span>
						<span th:case="'2'">本科</span>
						<span th:case="'3'">研究生</span>
					</td>
					<td th:text="${user.intro}">本人积极向上</td>
					<td>
						<a href="#">修改</a>
						<a href="#">删除</a>
					</td>

				</tr>
				</tbody>
			</table>
		</div>
	</div>
</div>
</body>

随后我们运行程序,输入注册信息后点击查看所有用户,看到的显示用户表格页面
在这里插入图片描述

模糊查询和返回首页按钮功能

我们继续完善该页面,加入模糊查询和返回首页按钮
模糊查询代码:

放在<div class="row">之上

	    <hr>
	    <div class="row">
	        <div class="col-md-12">
	            <form class="form-inline" role="form" id="searchForm" th:method="post" th:action="@{/user/getUserList}">
	                <div class="form-group col-md-2 offset-1">
	                    <input class="form-control input-sm" type="text" id="username" name="username" placeholder="用户名"
						th:value="${param.username}"/>
	                </div>
	                <div class="form-group col-md-2">
	                    <select class="form-control input-sm" id="gender" name="gender" >
	                        <option value="">---不限制性别---</option>
	                        <option value="1" th:selected="${#strings.trim(param.gender)=='1'}"></option>
	                        <option value="0" th:selected="${#strings.trim(param.gender)=='0'}"></option>
	                    </select>
	                </div>
	                <div class="form-group col-md-1">
	                    <button class="btn btn-primary btn-sm" type="submit" >搜索</button>
	                </div>
	            </form>
	        </div>
	    </div>
	    <hr>

返回首页按钮代码

放在表格之下

	    <hr>
	    <div class="row">
	        <div class="col-md-12">
	            <div class="text-center">
	                <a type="button" class="btn btn-outline-info" th:href="@{/}">返回首页</a>
	            </div>
	        </div>
	    </div>

页面显示:
在这里插入图片描述
模糊查询功能实现页面
在这里插入图片描述
在这里插入图片描述
返回首页功能页面
在这里插入图片描述


三、修改用户

在点击修改按钮后(userList页面)→在action里写逻辑:弹出新页面 edit.html →新页面里显示已经有的用户信息→使用表单元素展示(输入框)展示已有信息→修改信息→点击表单的提交→@{/user/updateUser}(方法)→数据库进行更新(service→mapper→xml)→在页面返回结果 result

1、入口地址:userList.html中:

代码如下(示例):

<a th:href="@{/user/getUser(userid=${user.userid})}">修改</a>

2、写修改功能的第一步的Controller层代码:
UserAction.java的getUser()方法:

代码如下(示例):

//查询用户信息,弹出新页面edit.html
    @RequestMapping( "/getUser")
    public String getUser(String userid,Map<String,String> m) {
        //返回跳转地址
        return "/user/edit";
    }

3、写修改功能的第一步的View层代码:
edit.html: 我是随便写了点,看能不能显示

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <title>Insert title here</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <title>Hello, Bootstrap Table!</title>
  <!-- 最新 Bootstrap4 核心 CSS 文件 -->
  <link rel="stylesheet" th:href="@{//cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css}">
  <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
  <script th:src="@{//cdn.staticfile.org/jquery/3.4.1/jquery.min.js}"></script>
  <!-- bootstrap.bundle.min.js 用于弹窗、提示、下拉菜单,包含了 popper.min.js -->
  <script th:src="@{//cdn.staticfile.org/popper.js/1.16.0/umd/popper.min.js}"></script>
  <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
  <script th:src="@{//cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js}"></script>
  <!-- DaterangePicker -->
  <link rel="stylesheet" type="text/css" media="all" th:href="@{/daterangepicker/daterangepicker.css}" />
  <!-- BootStrapValidator -->
  <link rel="stylesheet" th:href="@{/css/bootstrapValidator.css}">
  <script type="text/javascript" th:src="@{/js/bootstrapValidator.js}"></script>
  <script th:src="@{/js/functions.js}"></script>
  <script type="text/javascript" th:src="@{/js/validate.js}"></script>
  <script type="text/javascript">
    $(document).ready(function() {
      validateForm("editForm");
    });
  </script>
</head>
<body>
<div class="container-fluid">
  <div class="row">
    <div class="col-md-12">
      <div class="text-center">
        <a type="button" class="btn btn-outline-info" th:href="@{/user/getUserList}">查看所有用户信息</a>
      </div>
    </div>
  </div>
  <hr>
</div>

  <div class="row">
    <div class="col-md-10 offset-md-1">
      <form class="form" id="editForm" th:method="post" th:action="@{/user/updateUser}">
        <input type="hidden" name="userid" th:value="${user.userid}">
        <div class="modal-header">
          <h4 class="modal-title">请填写修改信息</h4>
        </div>
        <div class="modal-body">
          <div class="form-group row">
            <div class="col-md-2">
              <label for="username">用户名</label>
            </div>
            <div class="col-md-6">
              <input type="text" id="username" name="username" th:value="${user.username}"
                     class="form-control input-sm" placeholder="用户名" required readonly/> <span
                    id="result"></span>
            </div>
          </div>
          <div class="form-group row">
            <div class="col-md-2">
              <label for="password">密码</label>
            </div>
            <div class="col-md-6">
              <input type="password" id="password" name="password" th:value="${user.password}"
                     class="form-control input-sm" placeholder="密码" required />
            </div>
          </div>

          <div class="form-group row">
            <div class="col-md-2">
              <label for="password1">密码确认</label>
            </div>
            <div class="col-md-6">
              <input type="password" id="password1" name="password1" th:value="${user.password}"
                     class="form-control input-sm" placeholder="密码确认" required />
            </div>
          </div>

          <div class="form-group row">
            <div class="col-md-2">
              <label for="realname">姓名</label>
            </div>
            <div class="col-md-6">
              <input type="text" id="realname" name="realname"
                     th:value="${user.realname}" class="form-control input-sm" placeholder="姓名" />
            </div>
          </div>

          <div class="form-group row">
            <div class="col-md-2">
              <label for="birthdate">出生日期</label>
            </div>
            <div class="col-md-6">
              <input type="text" id="birthdate" name="birthdate"  th:value="${user.birthdate}"
                     class="form-control input-sm">
              <script type="text/javascript"
                      src="./daterangepicker/require.js"
                      data-main="./daterangepicker/main.js"></script>
            </div>
          </div>

          <div class="form-group row">
            <div class="col-md-2">
              <label for="gender">性别</label>
            </div>
            <div class="col-md-6">
              <div class="form-check form-check-inline">
                <input type="radio" class="form-check-input" name="gender"
                       value="1" th:checked="${user.gender}==1"> <label class="form-check-label"
                                                                        for="gender"></label>
              </div>
              <div class="form-check form-check-inline">
                <input type="radio" class="form-check-input" name="gender"
                       value="0" th:checked="${user.gender}==0"> <label class="form-check-label"
                                                                        for="gender"></label>
              </div>
            </div>
          </div>

          <div class="form-group row">
            <div class="col-md-2">
              <label for="interest">爱好</label>
            </div>
            <div class="col-md-6">
              <div class="form-check form-check-inline">
                <input type="checkbox" class="form-check-input" name="interest"	value="旅游" th:checked="${#strings.contains(user.interest,'旅游')}" >
                <label class="form-check-label"	for="interest">旅游</label>
              </div>
              <div class="form-check form-check-inline">
                <input type="checkbox" class="form-check-input" name="interest"	value="登山" th:checked="${#strings.contains(user.interest,'登山')}">
                <label class="form-check-label"	for="interest">登山</label>
              </div>
              <div class="form-check form-check-inline">
                <input type="checkbox" class="form-check-input" name="interest"	value="健身" th:checked="${#strings.contains(user.interest,'健身')}">
                <label class="form-check-label"	for="interest">健身</label>
              </div>
              <div class="form-check form-check-inline">
                <input type="checkbox" class="form-check-input" name="interest"	value="上网" th:checked="${#strings.contains(user.interest,'上网')}">
                <label class="form-check-label"	for="interest">上网</label>
              </div>
              <div class="form-check form-check-inline">
                <input type="checkbox" class="form-check-input" name="interest"	value="游泳" th:checked="${#strings.contains(user.interest,'游泳')}">
                <label class="form-check-label"	for="interest">游泳</label>
              </div>
            </div>
          </div>

          <div class="form-group row">
            <div class="col-md-2">
              <label for="degree">学历</label>
            </div>
            <div class="col-md-6">
              <select id="degree" name="degree" class="form-control">
                <option value="0" selected>--请选择--</option>
                <option value="1" th:selected="${user.degree}==1">高中</option>
                <option value="2" th:selected="${user.degree}==2">专科</option>
                <option value="3" th:selected="${user.degree}==3">本科</option>
                <option value="4" th:selected="${user.degree}==4">研究生</option>
              </select>
            </div>
          </div>

          <div class="form-group row">
            <div class="col-md-2">
              <label for="intro">自我介绍</label>
            </div>
            <div class="col-md-6">
              <textarea name="intro" rows="5" cols="20" class="form-control">[[${user.intro}]]</textarea>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <div class="form-group">
            <div class="text-center">
              <button class="btn btn-primary" type="submit">确定</button>
              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
              <button class="btn btn-secondary" type="reset">重置</button>
            </div>
          </div>
        </div>
      </form>
    </div>
  </div>
</div>
</body>
</html>

4、写修改功能的第一步的Mapper层代码:
UserMapper.java(接口)的getUser()方法(抽象方法):

User getUser(String userid);

写修改功能的第一步的Mapper层xml代码:
UserMapper.xml(实现文件):

    <select id="getUser" resultType="User">
        select * from demo_users where userid=#{userid}
    </select>

5、写修改功能的第一步的Service层代码:
UserService.java(接口)的 getUser()方法(抽象方法):

User getUser(String userid);

写修改功能的第二步的Service层实现类代码:
UserServiceImpl.java(实现类)的getUser()方法(具体方法):

    @Override
    public User getUser(String userid) {
        return mapper.getUser(userid);
    }

6、最后写修改功能的控制层代码:
UserAction.java的getUser()方法:

   //查询用户信息,弹出新页面edit.html
    @RequestMapping( "/getUser")
    public String getUser(String userid,Map<String,User> m) {
        System.out.println("getUser-----------------------:");
        //调用业务层方法(根据userid查找用户信息)
        User user= userService.getUser(userid);
        m.put("user",user);
        //返回跳转地址
        return "/user/edit";
    }

7、写修改功能的第二步的Mapper层方法:
UserMapper.java(接口)的updateUser方法(抽象方法):

void updateUser(User user);

UserMapper.xml(实现文件):

    <update id="updateUser">
        update demo_users set username=#{username},password=#{password},realname=#{realname},
            birthdate=#{birthdate},gender=#{gender},interest=#{interest},
            degree=#{degree} ,intro=#{intro} where userid=#{userid}
    </update>

8、写修改功能的第二步的业务层代码:
UserService的 updateUser方法(抽象方法):

boolean updateUser(User user);

UserServiceImpl的updateUser方法(具体方法):

    @Override
    public boolean updateUser(User user) {
        try{
            mapper.updateUser(user);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

9、最后在action里继续写updateUser方法

    @RequestMapping( "/updateUser")
    public String updateUser(User user, Map<String, String> m) {
        boolean f=userService.updateUser(user);
        if(f) {
            m.put("result", "yes" ) ;
            m.put("msg","恭喜您,修改成功");
        }else {
            m.put("result","no");
            m.put("msg","对不起,修改失败");
        }
        return "/user/result";
    }

页面显示:

我们运行程序,输入注册信息后点击查看所有用户后,看到的显示用户表格页面
在这里插入图片描述
在这里插入图片描述
显示:修改成功,再点击查看所有用户
在这里插入图片描述
在这里插入图片描述

四、删除用户

1、首先在UserList.html中加入删除按钮

<a th:href="@{/user/deleteUser(userid=${user.userid}) }" onclick="return confirm('确认删除吗?')">删除</a>

2、写删除功能的Controller层代码:
UserAction.java的deleteUser()方法:

//删除用户信息
    @RequestMapping( "/deleteUser")
    public String deleteUser(String userid, Map<String,User> m) {
    
            return "/user/result";
    }

3、写删除功能的Mapper层代码:
UserMapper.java(接口)的deleteUser()方法(抽象方法):

void deleteUser(User user);

UserMapper.xml(实现文件):

    <delete id="deleteUser">
        delete from demo_users where userid=#{userid}
    </delete>

4、写删除功能的Service层代码:
UserService.java(接口)的deleteUser()方法(抽象方法):

boolean deleteUser(User user);

UserServiceImpl.java(实现类)的deleteUser()方法(具体方法):

    @Override
    public boolean deleteUser(User user) {
        try{
            mapper.deleteUser(user);
            return true;
        }catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

5、回到action里面继续写删除逻辑

    //删除用户信息
    @RequestMapping( "/deleteUser")
    public String deleteUser(User user, Map<String,String> m) {
        boolean f=userService.deleteUser(user);
        if(f) {
            m.put("result", "yes" ) ;
            m.put("msg","恭喜您,用户删除成功");
        }else {
            m.put("result","no");
            m.put("msg","对不起,用户删除失败");
        }
        return "/user/result";
    }

在这里插入图片描述
然后会提示数据删除成功
请添加图片描述
数据没有了
请添加图片描述


源码获取:

提示:此项目仅作为本博主的学习笔记记录,不作为商品售卖,文中某个方法或单词或许会因为马虎写错,但本文重点讲的是思路

点击此处转到源码地址:
基于Spring Boot框架的员工管理系统的设计与实现

  • Gitee提取地址:

Springboot员工管理系统初始框架

Springboot员工管理系统完整框架
在这里插入图片描述

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

二哈喇子!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值