前面一篇文章实现了用户登录验证: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&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数据库,创建两张表格:
- 用户表 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='用户表';
- 部门表 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>
- 这里重新编写了
selectAll
的sql
查询关联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写页面要注意:
xmlns:th="http://www.thymeleaf.org"
要引入命名空间,否则不能够使用thymeleaf语法。<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
使用th:href=@{文件路径}
引入css文件。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
th:fragment="topBar"
公共组件抽取,在其他页面可以使用<div th:replace="~{common/common::topBar}"></div>
就可以引入公共抽取页面。<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用户列表页面:
<div th:replace="~{common/common::topBar}"></div>
,<div th:replace="~{common/common::sideBar(active = 'list')}"></div>
分别引入之前在common.html
里面定义的公共组件。<tr th:each="user:${users}">
遍历用户别表。<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等组件。
点个关注。