准备工作
- 新建一个项目
-
在网上下载bootstrap模板,html文件放在templates文件夹,静态资源放在static
-
使用thymeleaf模板
-
导入约束
<html lang="en" xmlns:th="http://www.thymeleaf.org">
- 修改指向
<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>
- 通过自定义方式扩展MVC,实现url和html页面的映射
- 用户访问/,会被解析到 index.html页面
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
}
- localhost:8080
数据库
- 部门表
CREATE DATABASE `springboot`;
USE `springboot`
CREATE TABLE `department`(
`id` INT(10) NOT NULL AUTO_INCREMENT,
`depName` VARCHAR(20) NOT NULL,
PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO department(id,depName) VALUES(101,'市场部');
INSERT INTO department(id,depName) VALUES(102,'教研部');
INSERT INTO department(id,depName) VALUES(103,'管理部');
INSERT INTO department(id,depName) VALUES(104,'后勤部');
- 员工表
CREATE TABLE `employee`(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`empName` VARCHAR(15) DEFAULT NULL COMMENT '用户名称',
`gender` INT(10) DEFAULT NULL COMMENT '性别(1:男、 0:女)',
`birthday` DATE DEFAULT NULL COMMENT '出生日期',
`phone` VARCHAR(15) DEFAULT NULL COMMENT '手机',
`address` VARCHAR(30) DEFAULT NULL COMMENT '地址',
`depId` INT(10) NOT NULL COMMENT'部门id',
PRIMARY KEY (`id`),
KEY `fkdepId` (`depId`),
CONSTRAINT `fkdepId` FOREIGN KEY (`depId`) REFERENCES `department` (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO employee() VALUES(1,'张三',1,'2020/1/2','12544556677','北京',102);
使用物理外键连接两个表,方便联表查询
- 登录用户表
CREATE TABLE `user`(
`ID` INT(10) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`userName` VARCHAR(100) NOT NULL COMMENT '用户姓名',
`password` VARCHAR(20) NOT NULL COMMENT '用户密码',
KEY `ID`(`ID`)
)ENGINE= INNODB CHARSET=utf8;
INSERT INTO `user`() VALUES(1,'admin','123456');
依赖
- 导入mysql连接依赖
- 导入log4j依赖
- 导入mybatis-springboot依赖
- 导入druid数据源
- 导入thymeleaf依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</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>
</dependency>
国际化功能实现
- 确保FileEncoding都是utf-8
- i18n:国际化的简写。i和n之间有18个字母
- 在i18n文件夹下创建两个配置文件,会自动生成一个文件夹包含这两个文件
- 右键该文件夹添加一个新的配置文件
- 添加一个英文的配置文件en_US
- 配置文件
//默认
login.password=密码
login.Remember=记住我
login.Sign=登录
login.tip=请登录
login.Username=用户名
//英文
login.password=Password
login.Remember=Remember me
login.Sign=Sign in
login.tip=Please sign in
login.Username=Username
//中文
login.password=密码
login.Remember=记住我
login.Sign=登录
login.tip=请登录
login.Username=用户名
识别配置文件
MessageSourceAutoConfiguration
#绑定国际化配置文件
spring:
messages:
basename: i18n.login
- 国际化的消息用#{ }来取值
- 标签体内容用[[$[ }]]来取值
前端代码
<form class="form-signin" th:action="@{/login}">
<img class="mb-4" th:src="@{/favicon.ico}" alt="" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal">[[#{login.tip}]]</h1>
<input id="userName" type="text" class="form-control"
th:placeholder="#{login.Username}" name="userName" required>
<input type="password" class="form-control"
th:placeholder="#{login.password}" name="password" required>
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> [[#{login.Remember}]]
</label>
</div>
<button class="btn btn-lg btn-primary btn-block"
type="submit">[[#{login.Sign}]]</button>
<p class="mt-5 mb-3 text-muted">© 2020-2021</p>
<a class="btn btn-sm">中文</a>
<a class="btn btn-sm">English</a>
</form>
点击按钮实现中英文切换
- thymleaf传参用( )
<a class="btn btn-sm" th:href="@{/index.html(lan='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(lan='en_US')}">English</a>
- 编写一个国际化配置类,实现localResolver接口
MyLocalResolver
//需要将该类交给spring托管
public class MyLocalResolver implements LocaleResolver {
//解析请求
@Override
public Locale resolveLocale(HttpServletRequest request) {
//得到前端传递的参数
String language = request.getParameter("lan");
System.out.println("Debug============"+language);
Locale locale = Locale.getDefault();//如果没有就使用默认的
//如果接受到的参数不为空
if(!(language==null ||"".equals(language))){
//切割字符串,得到国家和地区的数组strings[0]
String[] strings = language.split("_");
//根据国家和地区创建一个新的local并返回
locale= new Locale(strings[0],strings[1]);
}
//如果为空,直接返回默认的local
return locale;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, Locale locale) {
}
}
- 将该类注册到bean
MyMvcConfig
- 注意: 类名必须是localeResolver
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
//自定义的国际化组件生效
@Bean
public LocaleResolver localeResolver(){
return new MyLocalResolver();
}
}
- 中文
- 英文
登录功能实现
- 用户输入账号和密码,如果和数据库匹配则跳转到dashboard页面,否则提示账号或密码错误
前端
- input框name属性表示的是用户在输入框输入的提交到后台数据
<body class="text-center">
<form class="form-signin" th:action="@{/login}">
<img class="mb-4" th:src="@{/favicon.ico}" alt="" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal">[[#{login.tip}]]</h1>
<! --如果msg的值为空,则不显示消息-->
<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
<input id="userName" type="text" class="form-control"
th:placeholder="#{login.Username}" name="userName" required>
<input type="password" class="form-control"
th:placeholder="#{login.password}" name="password" required>
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> [[#{login.Remember}]]
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">[[#{login.Sign}]]</button>
<p class="mt-5 mb-3 text-muted">© 2020-2021</p>
<a class="btn btn-sm" th:href="@{/index.html(lan='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(lan='en_US')}">English</a>
</form>
</body>
后端
- springboot配置文件
#关闭thymeleaf缓存spring
thymeleaf:
cache: false
#配置数据源,使用druid数据源
spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
#Spring Boot默认是不注入这些属性值的,需要自己绑定
#druid数据源专有配置
initialsize: 5
minIdle: 5
maxActive: 20
maxwait: 60000
timeBetweenEvictionRunsMi1lis: 60000
minEvictableIdleTimeMil1lis: 300000
validationQuery: SELECT 1 FROM DUAL
testwhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#配置监控统计拦截的filters,stat:监控统计、Log4j:日志记录、wall:防御sqL注入
#使用日志功能导入log4j依赖即可
filters: stat,wall,log4j
maxPoo1PreparedstatementPerConnectionsize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
#绑定国际化配置文件
messages:
basename: i18n.login
#mybatis配置,别名和绑定mapper
mybatis:
type-aliases-package: com.rm.pojo
mapper-locations: classpath:mybatis/mapper/*.xml
mvcConfig
- mvc配置文件
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/main.html").setViewName("dashboard");
}
//自定义的国际化组件生效
@Bean
public LocaleResolver localeResolver(){
return new MyLocalResolver();
}
}
druidConfig
- druid配置文件
@Configuration
public class DruidConfig {
//配置文件和该类进行绑定
//使用配置文件的属性,初始化连接数等...
//将配置文件中的属性值注入到DruidDataSource中
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druidDataSource(){
return new DruidDataSource();
}
//后台监控功能
@Bean
public ServletRegistrationBean statViewServlet(){
//访问配置的url就能进入后台管理页面
ServletRegistrationBean<StatViewServlet> registrationBean =
new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
HashMap<String, String> initParameters = new HashMap<>();
//配置登录后台人员账号密码
//增加配置
initParameters.put("loginUsername","admin");//账号,key值是固定的
initParameters.put("loginPassword","123456");//密码
//允许谁可以访问
initParameters.put("allow","127.0.0.1");
//今朝谁访问
initParameters.put("deny","112.168.0.1");
//设置初始化参数
registrationBean.setInitParameters(initParameters);
return registrationBean;
}
//过滤功能
@Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();
bean.setFilter(new WebStatFilter());
Map<String, String> initParameters =new HashMap<>();
//可以配置的拦击功能在WebStatFilter类中
//排除哪些请求,哪些请求不被统计
initParameters.put("exclusions","*.js,*.css,/druid/*");
bean.setInitParameters(initParameters);
return bean;
}
}
- 编写和数据库对应的实体类
//登录用户表
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String userName;
private String password;
}
//部门表
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
public class Department {
private Integer id;
private Integer num;
private String depName;
}
//员工表
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class Employee {
private int id;
private String empName;
private int gender;
private Date birthday;
private String phone;
private String address;
@Autowired
private Department department;
}
Mapper层
- 业务接口Mapper
UserMapper
@Mapper
@Repository //该注解表示该类被spring托管
public interface UserMapper {
//根据userName获取用户信息
User getUserByName(String name);
//登录功能
User login(String userName,String password);
}
- 接口实现配置
UserMapper.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.rm.mapper.UserMapper">
<select id="login" resultType="user">
select * from user where userName= #{userName} and password= #{password};
</select>
<select id="getUserByName" resultType="user">
select * from user where userName = #{userName};
</select>
</mapper>
Service层
UserService
- service层,处理具体的业务
@Service
public interface UserService {
//根据userName获取用户信息
User getUserByName(String name);
//根据用户名查询密码
User login(String userName,String password);
}
UserServiceImpl
- 注意点:equals方法需要防止空指针异常
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User getUserByName(String userName) {
return userMapper.getUserByName(userName);
}
@Override
public User login(String userName, String password) {
//具体的业务,验证密码是否相同
//得到真实密码
User user = userMapper.getUserByName(userName);
//如果输入密码和真实密码相同,返回user,否则返回null
if((user.getPassword()).equals(password)){
return user;
}else {
return null;
}
}
}
Controller层
UserController
@Controller
public class UserController {
//调用service
@Autowired
private UserService userService;
@RequestMapping("/login")
//@RequestParam("userName")表示从前端提交过来的属性名为userName
public String getUserByName(
@RequestParam("userName") String userName,
@RequestParam("password") String password,
Model model) {
if (userService.login(userName,password)!=null){
//main.html在mvc配置类中映射为dashboard页面
return "redirect:/main.html";
}else {
model.addAttribute("msg","用户名或密码错误");
return "index";
}
}
}
登录测试
- admin,123456
- 密码输入错误
登录拦截器
- 登录成功才能进入main页面,否则跳转到登录页面
UserController
- 用户登录成功在session中存放一个数据
@Controller
public class UserController {
//调用service
@Autowired
private UserService userService;
@RequestMapping("/login")
//@RequestParam("userName")表示从前端提交过来的属性名为userName
public String getUserByName(@RequestParam("userName") String userName,
@RequestParam("password") String password,
Model model,
HttpSession session) {
if (userService.login(userName,password)!=null){
//登录成功,存放一个session
session.setAttribute("userName",userName);
//main.html在mvc配置类中映射为dashboard页面
return "redirect:/main.html";
}else {
model.addAttribute("msg","用户名或密码错误");
return "index";
}
}
}
LoginHandleInterceptor
- 存在该session,证明用户登录过了,允许访问主页
- 否则拦截该请求,重定向到登录页,并提示没有权限,请登录
//配置拦截器
public class LoginHandleInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//用户登录成功会存在一个session,存在该session放行,否则就重定向到登录页
HttpSession session = request.getSession();
if (session.getAttribute("userName") ==null){
request.setAttribute("msg","没有权限,请先登录");
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
}else {
return true;
}
}
}
MyMvcConfig
- 配置拦截器,拦截所有请求
- 放行登录请求,放行静态资源加载请求
//该配置类相当于springMVC的配置文件
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/main.html").setViewName("dashboard");
}
//自定义的国际化组件生效
@Bean
public LocaleResolver localeResolver(){
return new MyLocalResolver();
}
//配置拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//拦截哪些请求,放行哪些请求
registry.addInterceptor(new LoginHandleInterceptor())
.addPathPatterns("/**").
excludePathPatterns("/","/index.html","/css/*","/img/*","/js/*","/login");
}
}
- 取出session的值并展示
<p>[[${session.userName}]]</p>
退出功能实现
- 用户点击退出按钮,返回到登录页,清除session信息
<a class="nav-link" th:href="@{/signOut}">退出</a>
//退出登录,清除session,重定向到登录页
@RequestMapping("/signOut")
public String signOut(HttpSession session){
session.removeAttribute("userName");
return "index";
}
展示员工列表
- 提取公共页面
th:fragment="sidebar"
- 插入公共页面
<div th:replace="~{commons/commons::sidebar}"></div>
- 如果要传递参数,用()传递,接收判断即可
<table class="table table-striped table-sm">
<thead>
<tr>
<th>id</th>
<th>empName</th>
<th>gender</th>
<th>birthday</th>
<th>phone</th>
<th>address</th>
<th>department</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr th:each="emp : ${emps}">
<td>[[${emp.getId()}]]</td>
<td>[[${emp.getEmpName()}]]</td>
<td>[[${emp.getGender()=='0'?'女':'男'}]]</td>
<td th:text="${#dates.format(emp.getBirthday(),'yyyy-MM-dd HH:mm:ss')}"></td>
<td>[[${emp.getPhone()}]]</td>
<td>[[${emp.getAddress()}]]</td>
<td>[[${emp.department.getDepName}]]</td>
<td>
<div class="btn btn-sm btn-primary">修改</div>
<div class="btn btn-sm btn-danger">删除</div>
</td>
</tr>
</tbody>
</table>==
员工表
- 类属性是department,数据库字段depId
- 需要联表查询(多对一)
<?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.rm.mapper.EmpMapper">
<select id="getEmps" resultMap="empDep">
select * from employee;
</select>
<!--resultMap-->
<!--多对一,多个员工对应一个部门-->
<resultMap id="empDep" type="employee">
<!--实体类中是对象,数据库中的tid字段,要使这两个对应上-->
<!--复杂的属性,需要单独处理,实体类中的对象属性:association 集合:collection-->
<association property="department" column="depId" javaType="department" select="getDepart"/>
</resultMap>
<select id="getDepart" resultType="department">
select * from springboot.department where id =#{id};
</select>
</mapper>
EmpController
- 用户点击‘’员工‘’会跳转到该请求
<a class="nav-link" th:href="@{/list}">员工</a>
- 获取全部员工信息,封装到model中,跳转list页面
- 在list页面中展示数据
//员工controller层
@Controller
public class EmpController {
@Autowired
private EmpService empService;
@RequestMapping("/list")
public String emps(Model model){
List<Employee> emps = empService.getEmps();
model.addAttribute("emps",emps);
return "emp/list";
}
}
结果
添加员工
- 点击按钮,输入表单,提交表单
- 添加员工成功,返回list页面
提交的form表单
- 提交到/addEmp请求
<form class="form-horizontal" th:action="@{/addEmp}">
<div class="form-group">
<label>EmpName</label>
<input type="text" class="form-control" placeholder="empName" name="empName">
</div>
<div class="form-group">
<label>Gender</label><br/>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender"value="1">
<label class="form-check-label">男</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender"value="0">
<label class="form-check-label">女</label>
</div>
</div>
<div class="form-group">
<label>Department</label>
<!--要和数据库字段对应,数据库中是id-->
<select class="form-control" name="department.id">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</div>
<div class="form-group">
<label>Phone</label>
<input type="text" class="form-control" placeholder="phone" name="phone">
</div>
<div class="form-group">
<label>Address</label>
<input type="text" class="form-control" placeholder="address" name="address">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
部门应该显示部门名字,提交给后台的是部门id
- 用户点击添加员工按钮,到add请求
- 在该请求中查询所有部门信息,将数据封装在Model中返回给前端
- 前端遍历部门,将部门名字放在选择框中,部门id放在value中
Mapper
@Mapper
@Repository
public interface DepMapper {
//查询所有部门信息
List<Department> getDepartments();
}
<?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.rm.mapper.DepMapper">
<!--查询所有部门-->
<select id="getDepartments" resultType="department">
select * from springboot.department;
</select>
</mapper>
Service
@Service
public class DepServiceImpl implements DepService {
@Autowired
private DepMapper depMapper;
@Override
public List<Department> getDepartments() {
return depMapper.getDepartments();
}
}
Controller
//员工controller层
@Controller
public class EmpController {
@Autowired
private EmpService empService;
@Autowired
private DepService depService;
@RequestMapping("/list")
public String emps(Model model){
List<Employee> emps = empService.getEmps();
model.addAttribute("emps",emps);
return "emp/list";
}
//点击按钮跳转到添加员工页
//获取所有部门表信息返回
@RequestMapping("/toAddEmp")
public String toAddEmp(Model model){
List<Department> departments = depService.getDepartments();
model.addAttribute("departments",departments);
return "emp/add";
}
//表单提交的地方
@RequestMapping("/addEmp")
public String addEmp(){
//表单提交成功,跳转到list页面
return "redirect:emp/list";
}
}
- 遍历展示数据
<div class="form-group">
<label>Department</label>
<select class="form-control" name="department.id">
<option selected disabled>----请选择----</option>
<option th:each="dep:${departments}" th:text="${dep.getDepName()} " th:value="${dep.getId()}">
</option>
</select>
</div>
添加用户实现
- #{ }里面的参数是前端传递的参数,即表单中input标签的name属性对应填写的值
- 如果是单选框或复选框,#{ }里面的参数对应着value属性
mapper
<?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.rm.mapper.EmpMapper">
<select id="getEmps" resultMap="empDep">
select * from employee;
</select>
<!--resultMap-->
<!--多对一,多个员工对应一个部门-->
<resultMap id="empDep" type="employee">
<!--实体类中是对象,数据库中的tid字段,要使这两个对应上-->
<!--复杂的属性,需要单独处理,实体类中的对象属性:association 集合:collection-->
<association property="department" column="depId" javaType="department" select="getDepart"/>
</resultMap>
<select id="getDepart" resultType="department">
select * from springboot.department where id =#{id};
</select>
<!--添加一个员工-->
<!--#{ }里面的参数是前端传递的参数,即表单中input标签的name属性-->
<insert id="addEmp" parameterType="employee">
insert into springboot.employee ()
values (null,#{empName},#{gender},#{birthday},#{phone},#{address},#{department.id});
</insert>
</mapper>
- 前端表单
<!--表单提交使用post方式-->
<form class="form-horizontal" th:action="@{/addEmp}" method="post">
<div class="form-group">
<label>EmpName</label>
<input type="text" class="form-control" placeholder="zhangsan" name="empName">
</div>
<div class="form-group">
<label>Gender</label><br/>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender"value="1">
<label class="form-check-label">男</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender"value="0">
<label class="form-check-label">女</label>
</div>
</div>
<div class="form-group">
<label>Department</label>
<select class="form-control" name="department.id">
<option selected disabled>----请选择----</option>
<option th:each="dep:${departments}" th:text="${dep.getDepName()} " th:value="${dep.getId()}">
</option>
</select>
</div>
<div class="form-group">
<label>Phone</label>
<input type="text" class="form-control" placeholder="17688993322" name="phone">
</div>
<div class="form-group">
<label>Address</label>
<input type="text" class="form-control" placeholder="beijing" name="address">
</div>
<div class="form-group">
<label>Birthday</label>
<input type="text" class="form-control" placeholder="2020/01/01" name="birthday">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
注意:日期格式
- 默认:yyyy/MM/dd
- 如需修改,在配置文件中修改
spring:
mvc:
format:
date: yyyy-MM-dd
- 修改后的格式
修改员工信息
- 用户点击修改跳到修改页面,表单中存在查询出来的数据,用value展示
- 点击提交按钮,重定向到list页面
前端
- 用户需要修改的数据需要在输入框中显示出来
update.html
<!--表单提交使用post方式-->
<form class="form-horizontal" th:action="@{/update}" method="post">
<div class="form-group">
<label>EmpName</label>
<input type="text" class="form-control" name="empName" th:value="${empById.getEmpName}">
</div>
<div class="form-group">
<label>Gender</label><br/>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio"
th:checked="${empById.getGender()==1}" name="gender" value="1">
<label class="form-check-label">男</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio"
th:checked="${empById.getGender()==0}" name="gender" value="0">
<label class="form-check-label">女</label>
</div>
</div>
<div class="form-group">
<label>Department</label>
<select class="form-control" name="department.id">
<option disabled >----请选择----</option>
<!--选择的是查询出的对应的用户的id和部门id相同的部门-->
<option th:each="dep:${departments}" th:text="${dep.getDepName()} "
th:selected="${dep.getId()==empById.getDepartment().getId()}" th:value="${dep.getId()}">
</option>
</select>
</div>
<div class="form-group">
<label>Phone</label>
<input type="text" class="form-control" th:value="${empById.getPhone()}" name="phone">
</div>
<div class="form-group">
<label>Address</label>
<input type="text" class="form-control" name="address" th:value="${empById.getAddress()}">
</div>
<div class="form-group">
<label>Birthday</label>
<input type="text" class="form-control" name="birthday"
th:value="${#dates.format(empById.getBirthday(),'yyyy-MM-dd HH:mm:ss')}">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
- 根据id查询员工的信息,部门属性需要结果集映射
- 显示数据后,用户进行修改,提交到update请求
=前面是数据库字段,后面是前端input框中的name属性
实体类起到一个中间作用
<!--修改员工的信息-->
<update id="updateEmp" parameterType="employee">
update springboot.employee set empName=#{empName},
gender=#{gender},birthday=#{birthday},phone=#{phone},address=#{address},depId=#{department.id}
where id=#{id};
</update>
//修改用户表单提交的地方
@RequestMapping("/update")
public String update(Employee employee){
empService.updateEmp(employee);
return "redirect:/list";
}
删除功能
<!--根据id、删除员工-->
<delete id="deleteById" parameterType="_int">
delete from springboot.employee where id=#{id};
</delete>
//根据id删除用户
@RequestMapping("/delete/{id}")
public String delete(@PathVariable("id") int id){
empService.deleteById(id);
return "redirect:/list";
}
404处理
springboot中,只需要在template文件夹下新建一个error文件夹,将404.html页面放进去就行了