springboot + bootstrap + thymeleaf +mybatis 编写员工管理系统

前面一篇文章实现了用户登录验证:springboot + thymeleaf +interceptor实现用户登录验证
今天接着上一篇文章,接入mybatis,实现员工管理系统的增删改查功能。
本文前端静态资源:bootstrap静态资源页面
首先贴一下maven配置:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.cpown</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--webjar 引入jquery-->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.4.1</version>
        </dependency>

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

        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.42</version>
        </dependency>


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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.7</version>
            <scope>compile</scope>
            <optional>true</optional>
        </dependency>

    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.7</version>
                <configuration>
                    <configurationFile>src/main/resources/generator/generatorConfig.xml</configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>5.1.42</version>
                    </dependency>
                </dependencies>

            </plugin>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

        </plugins>
    </build>

</project>

配置文件:

#数据库连接配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/yao?autoReconnect=true&amp;failOverReadOnly=false;useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456

#关闭thymeleaf缓存
spring.thymeleaf.cache=false
#sql日志打印级别 com.cpown.demo.mapper 对应的是自己的mapper.java文件存放路径
logging.level.com.cpown.demo.mapper=debug

#mybatisxml扫描
mybatis.mapper-locations=classpath:mapper/**/*.xml
#实体类
mybatis.type-aliases-package=com.cpown.demo.pojo

一、创建数据库表格以及映射文件

我们使用 mysql数据库,创建两张表格:

  1. 用户表 sys_user
CREATE TABLE `sys_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `name` varchar(100) CHARACTER SET utf8 DEFAULT NULL COMMENT '用户名称',
  `password` varchar(20) CHARACTER SET utf8 DEFAULT NULL COMMENT '用户密码',
  `email` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT '邮箱',
  `sex` tinyint(4) DEFAULT NULL COMMENT '性别0 女 1男',
  `department_id` int(11) DEFAULT NULL COMMENT '部门id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
  1. 部门表 department
 CREATE TABLE `department` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '部门id',
  `department_name` varchar(255) DEFAULT NULL COMMENT '部门名称',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='部门表';

这里使用 maven 插件generator 生成 实体类 pojo+mapper.xml+mapper.java文件,可以参考下:
maven插件自动生成pojo以及mapper映射文件

<1> pojo实体类
toString()方法需要自己重写。

package com.cpown.demo.pojo;

public class Department {
    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column department.id
     *
     * @mbg.generated Tue Jul 14 20:30:14 CST 2020
     */
    private Integer id;

    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column department.department_name
     *
     * @mbg.generated Tue Jul 14 20:30:14 CST 2020
     */
    private String departmentName;

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column department.id
     *
     * @return the value of department.id
     *
     * @mbg.generated Tue Jul 14 20:30:14 CST 2020
     */
    public Integer getId() {
        return id;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column department.id
     *
     * @param id the value for department.id
     *
     * @mbg.generated Tue Jul 14 20:30:14 CST 2020
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column department.department_name
     *
     * @return the value of department.department_name
     *
     * @mbg.generated Tue Jul 14 20:30:14 CST 2020
     */
    public String getDepartmentName() {
        return departmentName;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column department.department_name
     *
     * @param departmentName the value for department.department_name
     *
     * @mbg.generated Tue Jul 14 20:30:14 CST 2020
     */
    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }

    @Override
    public String toString() {
        return "Department{" +
                "id=" + id +
                ", departmentName='" + departmentName + '\'' +
                '}';
    }
}
package com.cpown.demo.pojo;

import java.util.Date;

public class SysUser {
    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column sys_user.id
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    private Integer id;

    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column sys_user.name
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    private String name;

    private String password;

    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column sys_user.email
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    private String email;

    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column sys_user.sex
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    private Byte sex;

    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column sys_user.birth
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    private Date birth;

    /**
     *
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column sys_user.department_id
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    private Integer departmentId;

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column sys_user.id
     *
     * @return the value of sys_user.id
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    public Integer getId() {
        return id;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column sys_user.id
     *
     * @param id the value for sys_user.id
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column sys_user.name
     *
     * @return the value of sys_user.name
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    public String getName() {
        return name;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column sys_user.name
     *
     * @param name the value for sys_user.name
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column sys_user.email
     *
     * @return the value of sys_user.email
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    public String getEmail() {
        return email;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column sys_user.email
     *
     * @param email the value for sys_user.email
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    public void setEmail(String email) {
        this.email = email;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column sys_user.sex
     *
     * @return the value of sys_user.sex
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    public Byte getSex() {
        return sex;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column sys_user.sex
     *
     * @param sex the value for sys_user.sex
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    public void setSex(Byte sex) {
        this.sex = sex;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column sys_user.department_id
     *
     * @return the value of sys_user.department_id
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    public Integer getDepartmentId() {
        return departmentId;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column sys_user.department_id
     *
     * @param departmentId the value for sys_user.department_id
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    public void setDepartmentId(Integer departmentId) {
        this.departmentId = departmentId;
    }


    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "SysUser{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", email='" + email + '\'' +
                ", sex=" + sex +
                ", departmentId=" + departmentId +
                '}';
    }
}

<2> mapper映射文件

package com.cpown.demo.mapper;

import com.cpown.demo.pojo.Department;
import com.cpown.demo.pojo.SysUser;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface DepartmentMapper {
    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table department
     *
     * @mbg.generated Tue Jul 14 20:30:14 CST 2020
     */
    int deleteByPrimaryKey(Integer id);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table department
     *
     * @mbg.generated Tue Jul 14 20:30:14 CST 2020
     */
    int insert(Department record);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table department
     *
     * @mbg.generated Tue Jul 14 20:30:14 CST 2020
     */
    Department selectByPrimaryKey(Integer id);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table department
     *
     * @mbg.generated Tue Jul 14 20:30:14 CST 2020
     */
    List<Department> selectAll();

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table department
     *
     * @mbg.generated Tue Jul 14 20:30:14 CST 2020
     */
    int updateByPrimaryKey(Department record);

    List<Department> selectDepartmentByName(@Param("name")String name);

}
package com.cpown.demo.mapper;

import com.cpown.demo.dto.SysUserDto;
import com.cpown.demo.pojo.SysUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface SysUserMapper {
    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table sys_user
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    int deleteByPrimaryKey(Integer id);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table sys_user
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    int insert(SysUser record);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table sys_user
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    SysUser selectByPrimaryKey(Integer id);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table sys_user
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    List<SysUserDto> selectAll();

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table sys_user
     *
     * @mbg.generated Tue Jul 14 20:27:59 CST 2020
     */
    int updateByPrimaryKey(SysUser record);

    List<SysUser> selectSysUserByName(@Param("name")String name);
}

为了前端直接展示部门名称,定义Dto查询关联部门表,直接展示部门名称:

package com.cpown.demo.dto;

import com.cpown.demo.pojo.SysUser;

/**
 * 用户查询Dto
 */
public class SysUserDto extends SysUser {
    private String departmentName;

    public String getDepartmentName() {
        return departmentName;
    }

    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }
}

<3> xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cpown.demo.mapper.DepartmentMapper">
  <resultMap id="BaseResultMap" type="com.cpown.demo.pojo.Department">
    <!--
      WARNING - @mbg.generated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Tue Jul 14 20:30:14 CST 2020.
    -->
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="department_name" jdbcType="VARCHAR" property="departmentName" />
  </resultMap>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    <!--
      WARNING - @mbg.generated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Tue Jul 14 20:30:14 CST 2020.
    -->
    delete from department
    where id = #{id,jdbcType=INTEGER}
  </delete>
  <insert id="insert" parameterType="com.cpown.demo.pojo.Department">
    <!--
      WARNING - @mbg.generated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Tue Jul 14 20:30:14 CST 2020.
    -->
    insert into department (id, department_name)
    values (#{id,jdbcType=INTEGER}, #{departmentName,jdbcType=VARCHAR})
  </insert>
  <update id="updateByPrimaryKey" parameterType="com.cpown.demo.pojo.Department">
    <!--
      WARNING - @mbg.generated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Tue Jul 14 20:30:14 CST 2020.
    -->
    update department
    set department_name = #{departmentName,jdbcType=VARCHAR}
    where id = #{id,jdbcType=INTEGER}
  </update>
  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    <!--
      WARNING - @mbg.generated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Tue Jul 14 20:30:14 CST 2020.
    -->
    select id, department_name
    from department
    where id = #{id,jdbcType=INTEGER}
  </select>
  <select id="selectAll" resultMap="BaseResultMap">
    <!--
      WARNING - @mbg.generated
      This element is automatically generated by MyBatis Generator, do not modify.
      This element was generated on Tue Jul 14 20:30:14 CST 2020.
    -->
    select id, department_name
    from department
  </select>


  <select id="selectDepartmentByName" resultMap="BaseResultMap">
    select id, department_name
    from department where department_name = #{name}
  </select>

</mapper>
  • 这里重新编写了selectAllsql 查询关联department表查询部门名称,方便前端展示,UserResultMap编写dto返回Map。
<?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="com.cpown.demo.mapper.SysUserMapper">
  <resultMap id="BaseResultMap" type="com.cpown.demo.pojo.SysUser">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="password" jdbcType="VARCHAR" property="password" />
    <result column="email" jdbcType="VARCHAR" property="email" />
    <result column="sex" jdbcType="TINYINT" property="sex" />
    <result column="department_id" jdbcType="INTEGER" property="departmentId" />
  </resultMap>

  <resultMap id="UserResultMap" type="com.cpown.demo.dto.SysUserDto">
    <result column="department_name" jdbcType="VARCHAR" property="departmentName" />
  </resultMap>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    delete from sys_user
    where id = #{id,jdbcType=INTEGER}
  </delete>
  <insert id="insert" parameterType="com.cpown.demo.pojo.SysUser">
    insert into sys_user (id, name,password, email,
      sex, department_id
      )
    values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR},
      #{sex,jdbcType=TINYINT}, #{departmentId,jdbcType=INTEGER}
      )
  </insert>
  <update id="updateByPrimaryKey" parameterType="com.cpown.demo.pojo.SysUser">
    update sys_user
    set name = #{name,jdbcType=VARCHAR}, password = #{password,jdbcType=VARCHAR},
      email = #{email,jdbcType=VARCHAR},
      sex = #{sex,jdbcType=TINYINT},
      department_id = #{departmentId,jdbcType=INTEGER}
    where id = #{id,jdbcType=INTEGER}
  </update>
  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select id, name,password, email, sex, department_id
    from sys_user
    where id = #{id,jdbcType=INTEGER}
  </select>
   <!--
     重写selectAll方法关联部门表查询部门名称
    -->
  <select id="selectAll" resultMap="UserResultMap">
    select sysuser.id, sysuser.name,sysuser.password, sysuser.email, sysuser.sex, sysuser.department_id,dep.department_name
    from sys_user sysuser left join department dep on dep.id = sysuser.department_id
  </select>

  <select id="selectSysUserByName" resultMap="BaseResultMap">
    select sysuser.id, sysuser.name,sysuser.password, sysuser.email, sysuser.sex, sysuser.department_id
    from sys_user sysuser  where sysuser.name = #{name}
  </select>

</mapper>

生成文件中基本已经包含了增删改查的方法。

二、创建Service

service分别包含了所有mapper文件的访问方法。
部门Service

package com.cpown.demo.service;

import com.cpown.demo.mapper.DepartmentMapper;
import com.cpown.demo.pojo.Department;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 部门Service
 */
@Service
public class DepartmentService {

    @Resource
    DepartmentMapper departmentMapper;


    public Department getDepartmentById(Integer id){
        return departmentMapper.selectByPrimaryKey(id);
    }

    /**
     * 根据用户名称查询部门
     * @param name
     * @return
     */
    public List<Department> getDepartmentByName(String name){
        return departmentMapper.selectDepartmentByName(name);
    }

    /**
     * 查询所有用部门
     * @return
     */
    public List<Department> getAllDepartment(){
        return departmentMapper.selectAll();
    }

    /**
     * 插入部门
     */
    public void insertDepartment( Department department){
        departmentMapper.insert(department);
    }

    /**
     * 修改部门
     */
    public void updateDepartment( Department department){
        departmentMapper.updateByPrimaryKey(department);
    }

    /**
     * 刪除部门
     */
    public void deleteDepartment(Integer id){
        departmentMapper.deleteByPrimaryKey(id);
    }
}

用户Service

package com.cpown.demo.service;

import com.cpown.demo.dto.SysUserDto;
import com.cpown.demo.mapper.SysUserMapper;
import com.cpown.demo.pojo.SysUser;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 用户Service
 */
@Service
public class SysUserService {

    @Resource
    SysUserMapper sysUserMapper;


    /**
     * 根据主键查询
     * @param id
     * @return
     */
    public SysUser getDepartmentById(Integer id){
        return sysUserMapper.selectByPrimaryKey(id);
    }

    /**
     * 根据用户名称查询用户
     * @param name
     * @return
     */
    public List<SysUser> getSysUserByName(String name){
        return sysUserMapper.selectSysUserByName(name);
    }

    /**
     * 查询所有用户
     * @return
     */
    public List<SysUserDto> getAllUser(){
        return sysUserMapper.selectAll();
    }

    /**
     * 插入用户
     */
    public void insertUser(SysUser sysUser){
         sysUserMapper.insert(sysUser);
    }

    /**
     * 修改用户
     */
    public void updateUser(SysUser sysUser){
        sysUserMapper.updateByPrimaryKey(sysUser);
    }

    /**
     * 刪除用户
     */
    public void deleteUser(Integer id){
        sysUserMapper.deleteByPrimaryKey(id);
    }
}

三、创建Controller

LoginController 这是管理用户controller 在用户登录后,向session添加当前登录用户缓存。

package com.cpown.demo.controller;

import com.cpown.demo.mapper.SysUserMapper;
import com.cpown.demo.pojo.SysUser;
import com.cpown.demo.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import org.thymeleaf.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.Collection;
import java.util.List;

/**
 * 用户登录controller
 *
 */
@RestController
@RequestMapping("/sys")
@Slf4j
public class LoginController {
    @Resource
    private SysUserService sysUserService;

    @RequestMapping("/login")
    public ModelAndView login(@RequestParam("userName")String username, @RequestParam("password") String password, HttpSession session){
        //使用ModelAndView进行视图转发
        //如果是@Controller 直接使用 Model即可  转发视图直接为页面字符串
        ModelAndView modelAndView = new ModelAndView();
        log.info("username:"+username);
        //根据用户名称查询
        List<SysUser> users = sysUserService.getSysUserByName(username);

        //登录名为空  返回登录页并提示 错误信息
        if(CollectionUtils.isEmpty(users)){
            log.info("login faild");
            //使用modelAndView往前端传值的方式:modelAndView.addObject(key,value)
            modelAndView.addObject("msg","用户名不存在");
            modelAndView.setViewName("index");
            //登录名不为空  进入dashboard页面 并设置session
        }else{
            SysUser sysUser = users.get(0);
            //用户名密码都正确
            if(StringUtils.equals(sysUser.getPassword(),password)){
                modelAndView.setViewName("dashboard");
                //将用户放进缓存
                session.setAttribute("loginUser",sysUser);
            }else{
                //使用modelAndView往前端传值得另一种方式:modelAndView.getModel()
                modelAndView.getModel().put("msg","密码错误");
                modelAndView.setViewName("index");
            }
        }
        return modelAndView;
    }

    /**
     * 首页
     * @return
     */
    @RequestMapping("/dashboard")
    public ModelAndView toDashBoard(){
        return  new ModelAndView("dashboard");
    }


}

SysUserController 用户管理Controller 包含所有用户增删改查操作。

package com.cpown.demo.controller;

import com.cpown.demo.dto.SysUserDto;
import com.cpown.demo.pojo.SysUser;
import com.cpown.demo.service.DepartmentService;
import com.cpown.demo.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.thymeleaf.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * 用户管理controller
 */
@Controller
@RequestMapping("/user")
@Slf4j
public class SysUserController {
    @Resource
    private SysUserService sysUserService;
    @Resource
    private DepartmentService departmentService;

    /**
     * 跳转用户列表
     * @param model
     * @return
     */
    @RequestMapping("/list")
    public String goToList(Model model){
        List<SysUserDto> allUser = sysUserService.getAllUser();
        log.info("查询用户列表:数量={}",allUser.size());
        model.addAttribute("users",allUser);
        return "list";
    }


    /**
     * 跳轉添加用戶頁面
     * @return
     */
    @RequestMapping("/toAdd")
    public String  goToAdd(Model model){
        log.info("跳转用户编辑界面");
        model.addAttribute("departments",departmentService.getAllDepartment());
        return "adduser";
    }

    /**
     * 跳轉修改用戶頁面
     * @return
     */
    @RequestMapping("/toUpdate")
    public String  toUpdate(@RequestParam(value = "id", defaultValue = "")String id, Model model){
        log.info("跳转用户编辑界面");
        model.addAttribute("departments",departmentService.getAllDepartment());
        if(!StringUtils.isEmpty(id)){
            model.addAttribute("user",sysUserService.getDepartmentById(Integer.valueOf(id)));
        }
        return "adduser";
    }


    /**
     * 保存用戶
     * @param user
     * @return
     */
    @RequestMapping("/saveUser")
    public String saveUser(SysUser user){
        try {
            if(user.getId() == null){
                log.info("添加用户user={}",user.toString());
                sysUserService.insertUser(user);
            }else{
                log.info("修改用户user={}",user.toString());
                sysUserService.updateUser(user);
            }
        } catch (Exception e) {
        }
        return "redirect:/user/list";
    }
    /**
     * 删除用户
     * @return
     */
    @RequestMapping("/delete")
    public String  delete(String id){
        log.info("删除用户 userid={}",id);
        if(!StringUtils.isEmpty(id)){
            sysUserService.deleteUser(Integer.valueOf(id));
        }
        return "redirect:/user/list";
    }

}

部门管理Controller 包含所有部门管理操作。

package com.cpown.demo.controller;

import com.cpown.demo.pojo.Department;
import com.cpown.demo.pojo.SysUser;
import com.cpown.demo.service.DepartmentService;
import com.cpown.demo.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import org.thymeleaf.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 部门管理controller
 */
@Controller
@RequestMapping("/depart")
@Slf4j
public class DepartmentController {
    @Resource
    private DepartmentService departmentService;

    /**
     * 部门列表页面
     * 使用 ModelAndView 和 直接 retern String 都可以跳转到页面
     * 如果使用@RestController 则必须使用 ModelAndView跳转页面
     * @return
     */
    @RequestMapping("/list")
    public ModelAndView goToList(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("departlist");
        List<Department> allDepartment = departmentService.getAllDepartment();
        log.info("查询部门列表:数量={}",allDepartment.size());
        modelAndView.addObject("departments",allDepartment);
        return modelAndView;
    }


    /**
     * 跳轉添加部门頁面
     * @return
     */
    @RequestMapping("/toAdd")
    public ModelAndView goToAdd(){
        return new ModelAndView("addDepartment");
    }
    /**
     * 跳轉修改部门頁面
     * @return
     */
    @RequestMapping("/toUpdate")
    public String  toUpdate(@RequestParam(value = "id", defaultValue = "")String id, Model model){
        model.addAttribute("depart",departmentService.getDepartmentById(Integer.valueOf(id)));
        return "addDepartment";
    }
    /**
     * 保存部门
     * @param department
     * @return
     */
    @RequestMapping("/saveDepartment")
    public String saveUser(Department department, Model model){
        try {
            if(department.getId() == null ){
                departmentService.insertDepartment(department);
            }else{
                departmentService.updateDepartment(department);
            }
        } catch (Exception e) {
            log.error(e.getMessage(),e);
            //此处可以向页面传递 错误信息
            model.addAttribute("errormsg",e.getMessage());
        }
        return "redirect:/depart/list";
    }

    /**
     * 删除用户
     * @return
     */
    @RequestMapping("/delete")
    public String  delete(String id){
        log.info("删除部门 departmentId={}",id);
        if(!StringUtils.isEmpty(id)){
            departmentService.deleteDepartment(Integer.valueOf(id));
        }
        return "redirect:/depart/list";
    }
}

四、登录校验以及拦截器处理

这里是我们上一篇文章写到的,拦截器以及请求跳转处理。
创建拦截器类:

package com.cpown.demo.config;

import com.cpown.demo.pojo.SysUser;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 登录拦截器
 */
public class LoginHandlerInterceptor implements HandlerInterceptor {
    /**
     * 方法执行之前进行拦截
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        SysUser loginUser = (SysUser)request.getSession().getAttribute("loginUser");
        if(null == loginUser){
            System.out.println("没有登录:loginUser");
            request.setAttribute("msg","用户没有登录无法访问");
            //此处重定向地址  一定不能够被拦截 否则会陷入死循环
            request.getRequestDispatcher("/index.html").forward(request,response);
            //使用 重定向提交response以后  请求就结束了,必须返回false,如果返回true 会报错
            return false;
        }
        return true;
    }
}

将拦截器加载到springboot容器中。

package com.cpown.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 配置中心
 */
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    /**
     * 配置转发器
     * @param registry
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //可以将制定路径转发到别的页面    /  默认转发到 index页面
        registry.addViewController("/").setViewName("index");
        //index.html  默认也转发到 index页面
        registry.addViewController("/index.html").setViewName("index");
        registry.addViewController("/main.html").setViewName("dashboard");

    }

    /**
     * 自定义拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //拦截所有请求  除了 "/index","/user/login","/",/index.html
        //同时也要 排除拦截 静态资源 否则页面样式功能无法加载
        registry.addInterceptor(new LoginHandlerInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/index.html","/index","/sys/login","/","/css/*","/js/*","/img/*");
    }
}

五、前端页面

静态资源路径图:springboot默认resourse、static、templates都可以视为classpath,在引入文件时可以省略前面路劲。不了解的可以参考前面文章:springboot静态资源加载规则
在这里插入图片描述

使用thymeleaf写页面要注意:

  1. xmlns:th="http://www.thymeleaf.org" 要引入命名空间,否则不能够使用thymeleaf语法。
  2. <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">使用 th:href=@{文件路径}引入css文件。
  3. th:action="@{/sys/login}" 使用 th:action=@{接口地址}进行表单提交 在提交敏感信息是可以使用post请求。

首页登录页index.html:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
		<meta name="description" content="">
		<meta name="author" content="">
		<title>Signin Template for Bootstrap</title>
		<!-- Bootstrap core CSS -->
		<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
		<!-- Custom styles for this template -->
		<link th:href="@{/css/signin.css}" rel="stylesheet">
	</head>

	<body class="text-center">
			<!--此处使用post请求 可以隐藏登录参数 敏感信息-->
		<form class="form-signin" th:action="@{/sys/login}" method="post" >
			<img class="mb-4" th:src="@{/img/bootstrap-solid.svg}" alt="" width="72" height="72">
			<h1 class="h3 mb-3 font-weight-normal">员工管理系统</h1>
			<p style="color: #721c24" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
			<label class="sr-only">Username</label>
			<input type="text" class="form-control" name="userName" placeholder="Username" >
			<label class="sr-only">Password</label>
			<input type="password" class="form-control" name="password" placeholder="Password">
			<div class="checkbox mb-3">
				<label>
          <input type="checkbox" value="remember-me"> Remember me
        </label>
			</div>
			<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
			<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
			<a class="btn btn-sm">中文</a>
			<a class="btn btn-sm">English</a>
		</form>

	</body>

</html>

抽取公共页面放在common.html

  1. th:fragment="topBar"公共组件抽取,在其他页面可以使用 <div th:replace="~{common/common::topBar}"></div> 就可以引入公共抽取页面。
  2. <a th:class="${active == 'dashboard' ? 'nav-link active' : 'nav-link'}" th:href="@{/sys/dashboard}"> 这里为了有一个点击高亮展示,可以判断是哪个页面的引用组件,通过thymeleaf三元运算符进行展示样式。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--首页-->
    <nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topBar">
        <a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">员工管理系统</a>
        <input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
        <ul class="navbar-nav px-3">
            <li class="nav-item text-nowrap">
                <a class="nav-link" th:href="@{/dashboard}">退出</a>
            </li>
        </ul>
    </nav>

    <!--侧边栏-->

    <nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="sideBar">
        <div class="sidebar-sticky">
            <ul class="nav flex-column">
                <li class="nav-item">
                    <!--这例取出在子页面传递的值 实现按钮高亮-->
                    <a th:class="${active == 'dashboard' ? 'nav-link active' : 'nav-link'}" th:href="@{/sys/dashboard}">
                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home">
                            <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
                            <polyline points="9 22 9 12 15 12 15 22"></polyline>
                        </svg>
                        首页 <span class="sr-only">(current)</span>
                    </a>
                </li>
                <li class="nav-item">
                    <a th:class="${active == 'depart' ? 'nav-link active' : 'nav-link'}" th:href="@{/depart/list}">
                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shopping-cart">
                            <circle cx="9" cy="21" r="1"></circle>
                            <circle cx="20" cy="21" r="1"></circle>
                            <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path>
                        </svg>
                        部門管理
                    </a>
                </li>
                <li class="nav-item">
                    <a th:class="${active == 'list' ? 'nav-link active' : 'nav-link'}" th:href="@{/user/list}">
                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-users">
                            <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
                            <circle cx="9" cy="7" r="4"></circle>
                            <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>
                            <path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
                        </svg>
                        用戶管理
                    </a>
                </li>

            </ul>
        </div>
    </nav>

</body>
</html>

在这里插入图片描述
Dashboard首页:

<!DOCTYPE html>
<!-- saved from url=(0052)http://getbootstrap.com/docs/4.0/examples/dashboard/ -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
		<meta name="description" content="">
		<meta name="author" content="">

		<title>Dashboard Template for Bootstrap</title>
		<!-- Bootstrap core CSS -->
		<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">

		<!-- Custom styles for this template -->
		<link th:href="@{/css/dashboard.css}" rel="stylesheet">
		<style type="text/css">
			/* Chart.js */

			@-webkit-keyframes chartjs-render-animation {
				from {
					opacity: 0.99
				}
				to {
					opacity: 1
				}
			}

			@keyframes chartjs-render-animation {
				from {
					opacity: 0.99
				}
				to {
					opacity: 1
				}
			}

			.chartjs-render-monitor {
				-webkit-animation: chartjs-render-animation 0.001s;
				animation: chartjs-render-animation 0.001s;
			}
		</style>
	</head>

	<body>
		<!--replace / insert 都可以将抽取的公共组件引入到子页面-->
		<div th:replace="~{common/common::topBar}"></div>

		<div class="container-fluid">
			<div class="row">
				<!--replace / insert 都可以将抽取的公共组件引入到子页面-->
				<!--active = 'dashboard' 可以传递值  在子页面使用表达式取出判断需要展示的样式-->
				<div th:replace="~{common/common::sideBar(active = 'dashboard')}"></div>

				<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
					<div class="chartjs-size-monitor" style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: hidden; pointer-events: none; visibility: hidden; z-index: -1;">
						<div class="chartjs-size-monitor-expand" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;">
							<div style="position:absolute;width:1000000px;height:1000000px;left:0;top:0"></div>
						</div>
						<div class="chartjs-size-monitor-shrink" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;">
							<div style="position:absolute;width:200%;height:200%;left:0; top:0"></div>
						</div>
					</div>
					<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pb-2 mb-3 border-bottom">
						<h1 class="h2">Dashboard</h1>
						<div class="btn-toolbar mb-2 mb-md-0">
							<div class="btn-group mr-2">
								<button class="btn btn-sm btn-outline-secondary">Share</button>
								<button class="btn btn-sm btn-outline-secondary">Export</button>
							</div>
							<button class="btn btn-sm btn-outline-secondary dropdown-toggle">
                <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-calendar"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg>
                This week
              </button>
						</div>
					</div>

					<canvas class="my-4 chartjs-render-monitor" id="myChart" width="1076" height="454" style="display: block; width: 1076px; height: 454px;"></canvas>
				</main>
			</div>
		</div>

		<!-- Bootstrap core JavaScript
    ================================================== -->
		<!-- Placed at the end of the document so the pages load faster -->
		<script type="text/javascript" th:src="@{/js/jquery-3.2.1.slim.min.js}" ></script>
		<script type="text/javascript" th:src="@{/js/popper.min.js}" ></script>
		<script type="text/javascript" th:src="@{/js/bootstrap.min.js}" ></script>

		<!-- Icons -->
		<script type="text/javascript" th:src="@{/js/feather.min.js}" ></script>
		<script>
			feather.replace()
		</script>

		<!-- Graphs -->
		<script type="text/javascript" th:src="@{/js/Chart.min.js}" ></script>
		<script>
			var ctx = document.getElementById("myChart");
			var myChart = new Chart(ctx, {
				type: 'line',
				data: {
					labels: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
					datasets: [{
						data: [15339, 21345, 18483, 24003, 23489, 24092, 12034],
						lineTension: 0,
						backgroundColor: 'transparent',
						borderColor: '#007bff',
						borderWidth: 4,
						pointBackgroundColor: '#007bff'
					}]
				},
				options: {
					scales: {
						yAxes: [{
							ticks: {
								beginAtZero: false
							}
						}]
					},
					legend: {
						display: false,
					}
				}
			});
		</script>

	</body>

</html>

list.html用户列表页面:
在这里插入图片描述

  1. <div th:replace="~{common/common::topBar}"></div><div th:replace="~{common/common::sideBar(active = 'list')}"></div>分别引入之前在common.html里面定义的公共组件。
  2. <tr th:each="user:${users}">遍历用户别表。
  3. <a th:href="@{/user/toUpdate(id=${user.getId()})}" class="btn btn-sm btn-primary">修改</a><a th:href="@{/user/delete(id=${user.getId()})}" class="btn btn-sm btn-danger">删除</a>为修改和删除按钮,分别对应SysUserController里面的接口。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
		<meta name="description" content="">
		<meta name="author" content="">

		<title>Dashboard Template for Bootstrap</title>
		<!-- Bootstrap core CSS -->
		<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">

		<!-- Custom styles for this template -->
		<link th:href="@{/css/dashboard.css}" rel="stylesheet">
		<style type="text/css">
			/* Chart.js */
			
			@-webkit-keyframes chartjs-render-animation {
				from {
					opacity: 0.99
				}
				to {
					opacity: 1
				}
			}
			
			@keyframes chartjs-render-animation {
				from {
					opacity: 0.99
				}
				to {
					opacity: 1
				}
			}
		</style>
	</head>

	<body>
	<div th:replace="~{common/common::topBar}"></div>


	<div class="container-fluid">
			<div class="row">
				<div th:replace="~{common/common::sideBar(active = 'list')}"></div>

				<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
					<h2>用户列表</h2>
					<a class="btn btn-sm btn-primary" th:href="@{/user/toAdd}"> 添加用户</a>

					<div class="table-responsive">
						<table class="table table-striped table-sm">
							<thead>
								<tr>
									<th>用户id</th>
									<th>姓名</th>
									<th>密码</th>
									<th>邮箱</th>
									<th>性别</th>
									<th>部门</th>
									<th>操作</th>
								</tr>
							</thead>
							<tbody>
								<!--遍历所有的用户-->
								<tr th:each="user:${users}">
									<td th:text="${user.getId()}"></td>
									<td th:text="${user.getName()}"></td>
									<td th:text="${user.getPassword()}"></td>
									<td th:text="${user.getEmail()}"></td>
									<td th:text="${user.getSex() =='0' ?'女' : '男'}"></td>
									<td th:text="${user.getDepartmentName()}"></td>
									<td>
										<a th:href="@{/user/toUpdate(id=${user.getId()})}" class="btn btn-sm btn-primary">修改</a>
										<a th:href="@{/user/delete(id=${user.getId()})}" class="btn btn-sm btn-danger">删除</a>
									</td>
								</tr>
							</tbody>
						</table>
					</div>
				</main>
			</div>
		</div>

		<!-- Bootstrap core JavaScript
    ================================================== -->
		<!-- Placed at the end of the document so the pages load faster -->
		<script type="text/javascript" th:src="@{/js/jquery-3.2.1.slim.min.js}"></script>
		<script type="text/javascript" th:src="@{/js/popper.min.js}"></script>
		<script type="text/javascript" th:src="@{/js/bootstrap.min.js}"></script>

		<!-- Icons -->
		<script type="text/javascript" th:src="@{/js/feather.min.js}"></script>
		<script>
			feather.replace()
		</script>

		<!-- Graphs -->
		<script type="text/javascript" th:src="@{/js/Chart.min.js}"></script>

	</body>

</html>

在这里插入图片描述
用户添加页面:

  • 这就是一个普通的表单页面,保存到/user/saveUser接口。
  • 这里由于是和修改共用一个页面,所以隐藏了id input,同时使用th:value="${user != null ? user.getId() : ''}"对input框进行赋值操作,如果有值就会赋值,没有值则为空。
  • <option th:selected="${user != null ? user.getDepartmentId() == depart.getId() : false}" th:each="depart:${departments}" th:text="${depart.getDepartmentName()}" th:value="${depart.getId()}"></option>这里真是的部门是由后台查询的,添加了一个部门,就会动态的刷新一个新的部门。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
		<meta name="description" content="">
		<meta name="author" content="">

		<title>Dashboard Template for Bootstrap</title>
		<!-- Bootstrap core CSS -->
		<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">

		<!-- Custom styles for this template -->
		<link th:href="@{/css/dashboard.css}" rel="stylesheet">
		<style type="text/css">
			/* Chart.js */
			
			@-webkit-keyframes chartjs-render-animation {
				from {
					opacity: 0.99
				}
				to {
					opacity: 1
				}
			}
			
			@keyframes chartjs-render-animation {
				from {
					opacity: 0.99
				}
				to {
					opacity: 1
				}
			}
		</style>
	</head>

	<body>
	<div th:replace="~{common/common::topBar}"></div>


	<div class="container-fluid">
			<div class="row">
				<div th:replace="~{common/common::sideBar(active = 'list')}"></div>
				<main role="main" class="col-md-10 ml-sm-auto col-lg-10 pt-3 px-4">
					<h2>添加用户</h2>
					<form class="form-horizontal" th:action="@{/user/saveUser}" method="post"  id="addUserForm">
                        <div class="form-group" style="display: none">
                            <label for="name" class="control-label" >id</label>
                            <input type="text" class="form-control" name="id"  th:value="${user != null ? user.getId() : ''}" id="id">
                        </div>
                        <div class="form-group">
							<label for="name" class="control-label">name</label>
							<input type="text" class="form-control" name="name" th:value="${user != null ? user.getName() : ''}"  id="name" placeholder="用户名">
						</div>
						<div class="form-group">
							<label for="password" class="control-label">password</label>
							<input type="text" class="form-control" name="password" th:value="${user != null ? user.getPassword() : ''}" id="password" placeholder="Password">
						</div>
						<div class="form-group">
							<label for="email" class="control-label">email</label>
							<input type="text" class="form-control" name="email"  id="email" th:value="${user != null ? user.getEmail() : ''}" placeholder="email">
						</div>
						<div class="form-group">
							<label  class="control-label">性别</label>
							<select class="form-control" name="sex" >
								<option th:selected="${user != null ? user.getSex() == '1' : false}"  value="1"></option>
								<option th:selected="${user != null ? user.getSex() == '0' : false}" value="0"></option>
							</select>
						</div>
						<div class="form-group">
							<label  class="control-label">部门</label>
							<select class="form-control"  name="departmentId" >
								<option  th:selected="${user != null ? user.getDepartmentId() == depart.getId() : false}" th:each="depart:${departments}" th:text="${depart.getDepartmentName()}" th:value="${depart.getId()}"></option>
							</select>
						</div>
						<div class="form-group">
							<button type="submit" id="subitUser" class="btn btn-primary">保存</button>
						</div>
					</form>
				</main>
			</div>
		</div>


		<!-- Bootstrap core JavaScript
    ================================================== -->
		<!-- Placed at the end of the document so the pages load faster -->
		<script type="text/javascript" th:src="@{/js/jquery-3.2.1.slim.min.js}"></script>
		<script type="text/javascript" th:src="@{/js/popper.min.js}"></script>
		<script type="text/javascript" th:src="@{/js/bootstrap.min.js}"></script>
		<script type="text/javascript" th:src="@{/webjars/jquery/3.4.1/jquery.min.js}"></script>



	<!-- Icons -->
		<script type="text/javascript" th:src="@{/js/feather.min.js}"></script>
		<script>
			feather.replace()
		</script>

		<!-- Graphs -->
		<script type="text/javascript" th:src="@{/js/Chart.min.js}"></script>
		<script>
			/*不想使用 thymeleaf 的可以使用 ajax请求*/
			/*但要注意ajax请求,不支持重定向,无法转发到list页面*/
			$("#subitUser1").click(function(){
				var data = formData($('#addUserForm'));
				console.log(data)
				$.ajax({
					type: "get",
					url:  "http://localhost:8080/user/saveUser",
					dataType: "json",
					data: data,
					success: function(returnData) {
						// if (returnData.code != "0000") {
						// 	alert(returnData.msg)
						// 	return;
						// }else{
						// 	alert("操作成功")
						// }
					}
				});
			})

			//表单序列化 将表单内容转对象
			function formData(form) {
				var o = {}
				$.each(form.serializeArray(), function(index) {
					if (o[this['name']]) {
						o[this['name']] = o[this['name']] + ',' + (this['value'] != null && typeof(this['value']) == 'string' ? this['value'].trim() : this['value'])
					} else {
						o[this['name']] = (this['value'] != null && typeof(this['value']) == 'string' ? this['value'].trim() : this['value'])
					}
				})
				return o
			}
		</script>
	</body>

</html>

部门department.html与user.html类似:

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

	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
		<meta name="description" content="">
		<meta name="author" content="">

		<title>Dashboard Template for Bootstrap</title>
		<!-- Bootstrap core CSS -->
		<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">

		<!-- Custom styles for this template -->
		<link th:href="@{/css/dashboard.css}" rel="stylesheet">
		<style type="text/css">
			/* Chart.js */
			
			@-webkit-keyframes chartjs-render-animation {
				from {
					opacity: 0.99
				}
				to {
					opacity: 1
				}
			}
			
			@keyframes chartjs-render-animation {
				from {
					opacity: 0.99
				}
				to {
					opacity: 1
				}
			}
		</style>
	</head>

	<body>
	<div th:replace="~{common/common::topBar}"></div>


	<div class="container-fluid">
			<div class="row">
				<div th:replace="~{common/common::sideBar(active = 'depart')}"></div>

				<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
					<h2>部门列表</h2>
					<a class="btn btn-sm btn-primary" th:href="@{/depart/toAdd}"> 添加部门</a>

					<div class="table-responsive">
						<table class="table table-striped table-sm">
							<thead>
								<tr>
									<th>id</th>
									<th>部门</th>
									<th>操作</th>
								</tr>
							</thead>
							<tbody>
								<!--遍历所有的部门-->
								<tr th:each="department:${departments}">
									<td th:text="${department.getId()}"></td>
									<td th:text="${department.getDepartmentName()}"></td>
									<td>
										<a th:href="@{/depart/toUpdate(id=${department.getId()})}" class="btn btn-sm btn-primary">修改</a>
										<a th:href="@{/depart/delete(id=${department.getId()})}" class="btn btn-sm btn-danger">删除</a>
									</td>
								</tr>
							</tbody>
						</table>
					</div>
				</main>
			</div>
		</div>

		<!-- Bootstrap core JavaScript
    ================================================== -->
		<!-- Placed at the end of the document so the pages load faster -->
		<script type="text/javascript" th:src="@{/js/jquery-3.2.1.slim.min.js}"></script>
		<script type="text/javascript" th:src="@{/js/popper.min.js}"></script>
		<script type="text/javascript" th:src="@{/js/bootstrap.min.js}"></script>

		<!-- Icons -->
		<script type="text/javascript" th:src="@{/js/feather.min.js}"></script>
		<script>
			feather.replace()
		</script>

		<!-- Graphs -->
		<script type="text/javascript" th:src="@{/js/Chart.min.js}"></script>

	</body>

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

	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
		<meta name="description" content="">
		<meta name="author" content="">

		<title>Dashboard Template for Bootstrap</title>
		<!-- Bootstrap core CSS -->
		<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">

		<!-- Custom styles for this template -->
		<link th:href="@{/css/dashboard.css}" rel="stylesheet">
		<style type="text/css">
			/* Chart.js */
			
			@-webkit-keyframes chartjs-render-animation {
				from {
					opacity: 0.99
				}
				to {
					opacity: 1
				}
			}
			
			@keyframes chartjs-render-animation {
				from {
					opacity: 0.99
				}
				to {
					opacity: 1
				}
			}
		</style>
	</head>

	<body>
	<div th:replace="~{common/common::topBar}"></div>


	<div class="container-fluid">
			<div class="row">
				<div th:replace="~{common/common::sideBar(active = 'depart')}"></div>
				<main role="main" class="col-md-10 ml-sm-auto col-lg-10 pt-3 px-4">
					<h2>添加部门</h2>
					<form class="form-horizontal"  th:action="@{/depart/saveDepartment}">
						<div class="form-group" style="display: none">
							<label for="departmentName" class="control-label">id</label>
							<input type="text" class="form-control" th:value="${depart != null ? depart.getId() : ''}" name="id" id="id" >
						</div>
						<div class="form-group">
							<label for="departmentName" class="control-label">name</label>
							<input type="text" class="form-control" th:value="${depart != null ? depart.getDepartmentName() : ''}" name="departmentName" id="departmentName" placeholder="部门名称">
						</div>
						<div class="form-group">
							<button type="submit" id="subitUser" class="btn btn-primary">保存</button>
						</div>
					</form>
				</main>
			</div>
		</div>


		<!-- Bootstrap core JavaScript
    ================================================== -->
		<!-- Placed at the end of the document so the pages load faster -->
		<script type="text/javascript" th:src="@{/js/jquery-3.2.1.slim.min.js}"></script>
		<script type="text/javascript" th:src="@{/js/popper.min.js}"></script>
		<script type="text/javascript" th:src="@{/js/bootstrap.min.js}"></script>
<!--		<script type="text/javascript" th:src="@{/webjars/jquery/3.4.1/jquery.min.js}"></script>-->



	<!-- Icons -->
		<script type="text/javascript" th:src="@{/js/feather.min.js}"></script>
		<!-- Graphs -->
		<script type="text/javascript" th:src="@{/js/Chart.min.js}"></script>

	</body>

</html>

六、总结

这里我们所有的页面与后台都写完了,js与css样式这里不做展示了。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
全部页面都在这里啦。

本文代码已全部上传,git :https://github.com/chenpeng111/springboot

后续会陆续加入,shiro,dubbo,mq等组件。

点个关注。

  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值