给大家分享一个自己写过bootstrap的CRUD,仅供大家学习!
话不多说,直接上代码!
项目结构
项目采用三层架构,主体框架是SSM+Bootstrap
基本的实体bean和mapper都是采用mybatis插件自动生成,配置文件会放到文章的末尾
Department.class
package com.edu.bean;
public class Department {
private Integer deptId;
private String deptName;
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName == null ? null : deptName.trim();
}
}
Employee.class
@Pattern 使用注解的方式进行后台校验
@JsonFormat 将日期转换成"yyyy-MM-dd HH:mm:ss"格式
package com.edu.bean;
import java.util.Date;
import javax.validation.constraints.Pattern;
import com.fasterxml.jackson.annotation.JsonFormat;
public class Employee {
private Integer empId;
@Pattern(regexp = "(^[a-zA-Z0-9_-]{3,16}$)|(^[\\u2E80-\\u9FFF]{2,6}$)", message = "{employee.empName.error}")
private String empName;
@Pattern(regexp = "^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$", message = "{employee.empEmail.error}")
private String empEmail;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date empBirthday;
private String empSex;
private Integer deptId;
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName == null ? null : empName.trim();
}
public String getEmpEmail() {
return empEmail;
}
public void setEmpEmail(String empEmail) {
this.empEmail = empEmail == null ? null : empEmail.trim();
}
public Date getEmpBirthday() {
return empBirthday;
}
public void setEmpBirthday(Date empBirthday) {
this.empBirthday = empBirthday;
}
public String getEmpSex() {
return empSex;
}
public void setEmpSex(String empSex) {
this.empSex = empSex == null ? null : empSex.trim();
}
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
}
EmployeeExtend.class
此类为了联表查询
package com.edu.bean;
public class EmployeeExtend extends Employee {
private Department department;
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
}
Message.class
此封装类为了传输状态码给前端判断是否成功
package com.edu.bean;
import java.util.HashMap;
import java.util.Map;
public class Message {
private Integer code;//响应状态码,约定200成功,失败500
private String msg;//代表响应信息
private Map<String, Object> info=new HashMap<>();
public static Message success() {
Message message=new Message();
message.setCode(200);
message.setMsg("成功");
return message;
}
public static Message fail() {
Message message=new Message();
message.setCode(500);
message.setMsg("失败");
return message;
}
public Message addInfo(String key,Object value) {
getInfo().put(key, value);
return this;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Map<String, Object> getInfo() {
return info;
}
public void setInfo(Map<String, Object> info) {
this.info = info;
}
}
EmployeeController 控制器
package com.edu.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.edu.bean.Employee;
import com.edu.bean.EmployeeExtend;
import com.edu.bean.Message;
import com.edu.service.EmployeService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
@Controller
@RequestMapping(value = "/emp")
public class EmployeeController {
@Autowired
private EmployeService employeService;
final static Logger logger = LoggerFactory.getLogger(EmployeeController.class);
// @RequestMapping(value="/list",method= {RequestMethod.GET,RequestMethod.POST})
// public String list(@RequestParam(name="pg",defaultValue="1") int pg,Model model) {
// PageHelper.startPage(pg,6);
// List<EmployeeExtend> employees = employeService.getAll();
// PageInfo pageInfo = new PageInfo(employees,6);
// model.addAttribute("pageInfo", pageInfo);
// return "list";
// }
@ResponseBody
@RequestMapping(value = "/list", method = {RequestMethod.GET, RequestMethod.POST})
public Message list(@RequestParam(name = "pg", defaultValue = "1") int pg) {
logger.debug("调用list方法");
//pg代表页码 6代表每页显示的信息条数
PageHelper.startPage(pg, 6);
//用一个带部门信息的员工类接受查询出来的信息
List<EmployeeExtend> employees = employeService.getAll();
PageInfo pageInfo = new PageInfo(employees, 6);
return Message.success().addInfo("pageInfo", pageInfo);
}
@ResponseBody
@RequestMapping(value = "/edit", method = RequestMethod.POST)
public Message save(@Validated EmployeeExtend employeeExtend, BindingResult result) {
if (result.hasErrors()) {
List<FieldError> fieldErrors = result.getFieldErrors();
Map<String, Object> errosMap = new HashMap<String, Object>();
fieldErrors.forEach((error) -> {
errosMap.put(error.getField(), error.getDefaultMessage());
});
return Message.fail().addInfo("error", errosMap);
}
employeService.saveEmp(employeeExtend);
return Message.success();
}
@ResponseBody
@RequestMapping(value = "/edit/{empId}", method = RequestMethod.GET)
public Message editUI(@PathVariable("empId") int empId) {
Employee employee = employeService.getById(empId);
return Message.success().addInfo("employee", employee);
}
@ResponseBody
@RequestMapping(value = "/edit/{empId}", method = RequestMethod.PUT)
public Message edit(Employee employee) {
employeService.update(employee);
return Message.success();
}
@ResponseBody
@RequestMapping(value = "/edit/{empId}", method = RequestMethod.DELETE)
public Message del(@PathVariable("empId") String empId) {
if (empId.contains(",")) {
String[] empIds = empId.split(",");
for (int i = 0; i < empIds.length; i++) {
employeService.del(Integer.valueOf(empIds[i]));
}
} else {
employeService.del(Integer.valueOf(empId));
}
return Message.success();
}
@ResponseBody
@RequestMapping(value = "/edit/checkUserName", method = RequestMethod.GET)
public Message checkUserName(String empName) {
//校验用户名是否符合格式要求
String reg = "(^[a-zA-Z0-9_-]{3,16}$)|(^[\\u2E80-\\u9FFF]{2,6}$)";
if (empName.matches(reg)) {
Message.fail().addInfo("msg", "请输入3-16位的字符串或者2-6的中文");
}
boolean flag = employeService.checkUserName(empName);
return Message.success().addInfo("flag", flag);
}
}
EmployeService
package com.edu.service;
import java.util.List;
import com.edu.bean.Employee;
import com.edu.bean.EmployeeExtend;
public interface EmployeService {
List<EmployeeExtend> getAll();
void saveEmp(EmployeeExtend employeeExtend);
Employee getById(int empId);
void update(Employee employee);
void del(int empId);
boolean checkUserName(String empName);
}
EmployeServiceImpl
package com.edu.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.edu.bean.Employee;
import com.edu.bean.EmployeeExample;
import com.edu.bean.EmployeeExtend;
import com.edu.mapper.EmployeeExtendMapper;
import com.edu.mapper.EmployeeMapper;
import com.edu.service.EmployeService;
@Service
@Transactional
public class EmployeServiceImpl implements EmployeService {
@Autowired
private EmployeeExtendMapper employeeExtendMapper;
@Autowired
private EmployeeMapper employeeMapper;
@Override
public List<EmployeeExtend> getAll() {
// TODO Auto-generated method stub
return employeeExtendMapper.selectDeptByExample(null);
}
@Override
public void saveEmp(EmployeeExtend employeeExtend) {
employeeMapper.insertSelective(employeeExtend);
}
@Override
public Employee getById(int empId) {
return employeeMapper.selectByPrimaryKey(empId);
}
@Override
public void update(Employee employee) {
employeeMapper.updateByPrimaryKeySelective(employee);
}
@Override
public void del(int empId) {
employeeMapper.deleteByPrimaryKey(empId);
}
@Override
public boolean checkUserName(String empName) {
EmployeeExample example = new EmployeeExample();
example.createCriteria().andEmpNameEqualTo(empName);
long countByExample = employeeMapper.countByExample(example);
return countByExample > 0;
}
}
DepartmentController
package com.edu.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.edu.bean.Department;
import com.edu.bean.Message;
import com.edu.service.DepartmentService;
@Controller
@RequestMapping(value = "/dept")
public class DepartmentController {
@Autowired
private DepartmentService departmentService;
@ResponseBody
@RequestMapping(value = "/list", method = {RequestMethod.GET, RequestMethod.POST})
public Message list() {
List<Department> departmentList = departmentService.getAll();
return Message.success().addInfo("departmentList", departmentList);
}
}
DepartmentService
package com.edu.service;
import java.util.List;
import com.edu.bean.Department;
public interface DepartmentService {
List<Department> getAll();
}
DepartmentServiceImpl
package com.edu.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.edu.bean.Department;
import com.edu.bean.EmployeeExtend;
import com.edu.mapper.DepartmentMapper;
import com.edu.mapper.EmployeeExtendMapper;
import com.edu.service.DepartmentService;
import com.edu.service.EmployeService;
@Service
@Transactional
public class DepartmentServiceImpl implements DepartmentService {
@Autowired
private DepartmentMapper departmentMapper;
@Override
public List<Department> getAll() {
return departmentMapper.selectByExample(null);
}
}
EmployeeExtendMapper 个人部门信息封装mapper
package com.edu.mapper;
import com.edu.bean.EmployeeExample;
import com.edu.bean.EmployeeExtend;
import java.util.List;
public interface EmployeeExtendMapper {
//带有部门信息的多条件查询
List<EmployeeExtend> selectDeptByExample(EmployeeExample example);
//带有部门的信息的根据主键查询
EmployeeExtend selectDeptByPrimaryKey(Integer empId);
//批量删除
void batchDel(int[] ids);
}
EmployeeExtendMapper.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.edu.mapper.EmployeeExtendMapper">
<resultMap id="BaseAndDeptResultMap" type="com.edu.bean.EmployeeExtend">
<id column="emp_id" jdbcType="INTEGER" property="empId"/>
<result column="emp_name" jdbcType="VARCHAR" property="empName"/>
<result column="emp_email" jdbcType="VARCHAR" property="empEmail"/>
<result column="emp_birthday" jdbcType="DATE" property="empBirthday"/>
<result column="emp_sex" jdbcType="VARCHAR" property="empSex"/>
<result column="dept_id" jdbcType="INTEGER" property="deptId"/>
<association property="department" javaType="com.edu.bean.Department">
<id column="dept_id" property="deptId"/>
<result column="dept_name" property="deptName"/>
</association>
</resultMap>
<sql id="Base_Dept_Column_List">
e.emp_id, e.emp_name, e.emp_email, e.emp_birthday, e.emp_sex, e.dept_id,d.dept_name
</sql>
<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="("
separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<select id="selectDeptByExample" parameterType="com.edu.bean.EmployeeExtend" resultMap="BaseAndDeptResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Dept_Column_List"/>
from employee e LEFT OUTER JOIN department d ON d.dept_id = e.dept_id
<if test="_parameter != null">
<include refid="Example_Where_Clause"/>
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectDeptByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseAndDeptResultMap">
select
<include refid="Base_Dept_Column_List"/>
from employee e LEFT OUTER JOIN department d ON d.dept_id = e.dept_id
where emp_id = #{empId,jdbcType=INTEGER}
</select>
</mapper>
其他两个都是自动生成的,github有项目源码,地址会在文章末尾。
以下是本项目的基本配置文件
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- mybatis的配置文件用的跟标签 -->
<configuration>
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<typeAliases>
<!-- 给类 取別名 -->
<!-- <typeAlias type="com.edu.bean.Students" alias="Students"/> -->
<!--
採用掃描的方式給com.edu.bean下面所有的類都去了別名,
默認別名為類的名稱或者類的首字母小寫
當前的別名就是: Students 或者students
-->
<package name="com.edu.bean"/>
</typeAliases>
<!-- 引入 pageHelper插件 -->
<!--注意这里要写成PageInterceptor, 5.0之前的版本都是写PageHelper, 5.0之后要换成PageInterceptor-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- reasonable:分页合理化参数,默认值为false,直接根据参数进行查询。
当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。 -->
<property name="PageHelper" value="mysql"/>
<property name="reasonable" value="true"/>
</plugin>
</plugins>
</configuration>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 把service交给sprign容器来进行管理 -->
<!-- <context:component-scan base-package="com.edu" use-default-filters="false">
排除掉打了Controller注解的包
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan> -->
<context:component-scan base-package="com.edu.service"></context:component-scan>
<!-- 加载配置文件 -->
<context:property-placeholder
location="classpath:dbUtil.properties"/>
<!-- 配置数据源 druid -->
<bean id="dataSource"
class="com.alibaba.druid.pool.DruidDataSource" init-method="init"
destroy-method="close">
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
<property name="driverClassName" value="${mysql.driver}"/>
<!-- 初始化连接大小 -->
<property name="initialSize" value="0"/>
<!-- 连接池最大使用连接数量 -->
<property name="maxActive" value="20"/>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="20"/>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="0"/>
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000"/>
<!-- <property name="poolPreparedStatements" value="true" /> <property
name="maxPoolPreparedStatementPerConnectionSize" value="33" /> -->
<property name="testOnBorrow" value="false"/>
<property name="testOnReturn" value="false"/>
<property name="testWhileIdle" value="true"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="25200000"/>
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="true"/>
<!-- 1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="1800"/>
<!-- 关闭abanded连接时输出错误日志 -->
<property name="logAbandoned" value="true"/>
<!-- 监控数据库 -->
<!-- <property name="filters" value="stat" /> -->
<property name="filters" value="mergeStat"/>
</bean>
<!-- 配置一个SqlSessionFactory工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
<constructor-arg name="executorType" value="BATCH"></constructor-arg>
</bean>
<!-- mapper的扫描接口 -->
<!-- 配置mapper接口的扫描路径 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.edu.mapper"></property>
</bean>
<!--定义一个事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 采用注解的方式来进行事务管理 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd">
<!--配置控制器的扫描路径 -->
<context:component-scan
base-package="com.edu.controller"></context:component-scan>
<!--基于注解处理器映射器 和处理器适配器 -->
<mvc:annotation-driven
conversion-service="convertersDateService" validator="validator"/>
<!-- 配置一个基于jsp的视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<mvc:default-servlet-handler/>
<!-- 配置一个日期类型的格式转换器 -->
<bean id="convertersDateService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.edu.convertor.DateConvertor"></bean>
</list>
</property>
</bean>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property>
<property name="validationMessageSource" ref="validationMessageSource"></property>
</bean>
<!-- 配置validationMessageSource -->
<bean id="validationMessageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 指定校验信息的资源文件的基本文件名称,不包括后缀,后缀默认是properties -->
<property name="basenames">
<list>
<value>classpath:validationMessageSource</value>
</list>
</property>
<!-- 指定文件的编码 -->
<property name="fileEncodings" value="utf8"></property>
<!-- 对资源文件内容缓存的时间,单位秒 -->
<property name="cacheSeconds" value="120"></property>
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"/><!-- 默认编码ISO-8859-1 -->
<property name="maxInMemorySize" value="10240"/><!-- 最大内存 10M -->
<property name="uploadTempDir" value="/upload/"/><!-- 上传的文件名字 -->
<property name="maxUploadSize" value="-1"/><!-- 最大文件,-1不限制 -->
</bean>
<!-- <mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
<mvc:resources location="/js/" mapping="/js/**"></mvc:resources> -->
<bean class="com.edu.exception.MyHandlerExceptionResolver"></bean>
<!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->
<bean id="mappingJacksonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="mappingJacksonHttpMessageConverter"/><!-- json转换器 -->
</list>
</property>
</bean>
</beans>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="${pageContext.request.contextPath }/css/bootstrap.min.css"
rel="stylesheet">
<script src="${pageContext.request.contextPath}/js/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
<title>Insert title here</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-12">
<h1>员工的CRUD操作</h1>
</div>
</div>
<div class="row">
<div class="col-md-4 col-md-offset-8">
<button id="btnSaveUI" class="btn btn-info" data-toggle="modal">新增</button>
<button class="btn btn-danger" id="batchDel">批量删除</button>
</div>
</div>
<div class="row">
<div class="col-md-12">
<table class="table table-hover">
<thead>
<tr>
<th><input type="checkbox" id="ckAll" onclick="$('input[name=ids]').prop('checked',this.checked);">
</th>
<th>员工的姓名</th>
<th>员工的部门</th>
<th>员工的邮箱</th>
<th>员工的性别</th>
<th>员工的生日</th>
<th>操作</th>
</tr>
</thead>
<tbody id="myData">
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-md-6" id="pageSpan"></div>
<div class="col-md-6" id="myPageDetail">
</div>
</div>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">新增员工信息</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" id="empSaveForm">
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">员工姓名</label>
<div class="col-sm-10">
<input type="text" name="empName" class="form-control" id="empName" placeholder="输入姓名">
<span id="helpBlockName" class="help-block"></span>
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">员工邮箱</label>
<div class="col-sm-10">
<input type="text" name="empEmail" class="form-control" id="empEmail"
placeholder="输入邮箱">
<span id="helpBlockEmail" class="help-block"></span>
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">员工生日</label>
<div class="col-sm-10">
<input type="text" name="empBirthday" class="form-control" id="empBirthday"
placeholder="输入生日">
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">员工性别</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="empSex" id="empSex" value="M"> 男
</label>
<label class="radio-inline">
<input type="radio" name="empSex" id="empSex" value="N"> 女
</label>
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">部门</label>
<div class="col-sm-6">
<select class="form-control" name="deptId" id="selectDept"></select>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" id="btnSave">保存</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="myEditModal" tabindex="-1" role="dialog" aria-labelledby="myModaEditlLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModaEditlLabel">修改员工信息</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" id="empEditFrom">
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">员工姓名</label>
<div class="col-sm-10">
<p class="form-control-static" id="empEditName"></p>
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">员工邮箱</label>
<div class="col-sm-10">
<input type="text" name="empEmail" class="form-control" id="empEditEmail"
placeholder="输入邮箱">
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">员工生日</label>
<div class="col-sm-10">
<input type="text" name="empBirthday" class="form-control" id="empEditBirthday"
placeholder="输入生日">
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">员工性别</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="empSex" id="inlineRadio1" value="N"> 男
</label>
<label class="radio-inline">
<input type="radio" name="empSex" id="inlineRadio2" value="M"> 女
</label>
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">部门</label>
<div class="col-sm-6">
<select class="form-control" name="deptId" id="empEditDept"></select>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" id="btnEdit">保存</button>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var rowPage;
var pageNum;
$(function () {
gotoPage(1);
});
//跳转页码
function gotoPage(pg) {
if ($("#ckAll").prop("checked")) {
$("#ckAll").prop("checked", false);
}
$.ajax({
type: "GET",
url: "${pageContext.request.contextPath}/emp/list",
data: "pg=" + pg,
dataType: "json",
success: function (data) {
// 1.获取表格数据
addEmpData(data);
// 2.获取页面详情
pageSpan(data);
// 3.获取页码信息
addPageDetail(data);
}
});
};
//添加部门信息
function addDeptsData(ele) {
var _selectDept = $(ele);
_selectDept.empty();
//发送ajax请求,动态添加部门数据
$.ajax({
type: "GET",
url: "${pageContext.request.contextPath}/dept/list",
dataType: "json",
async: false,
success: function (data) {
var _deptData = data.info.departmentList;
$.each(_deptData, function (index, item) {
$("<option></option>").attr("value", item.deptId)
.append(item.deptName).appendTo(_selectDept);
})
}
});
}
function addPageDetail(data) {
var _PageDetail = $("#myPageDetail");
_PageDetail.empty();
var _nav = $("<nav></nav>").attr("aria-label", "Page navigation");
var _ul = $("<ul></ul>").addClass("pagination");
var _isFirstPage = $("<li></li>");
if (data.info.pageInfo.isFirstPage) {
_isFirstPage.addClass("disabled").append($("<a></a>").attr("href", "javascript:void(0);").append("首页"));
} else {
_isFirstPage.append($("<a></a>").attr("href", "javascript:gotoPage(" + data.info.pageInfo.pageNum + ")").append("首页"));
}
var _hasPreviousPage = $("<li></li>");
if (data.info.pageInfo.hasPreviousPage) {
var pPage = data.info.pageInfo.pageNum - 1;
_hasPreviousPage.append($("<a></a>").attr("href", "javascript:gotoPage(" + pPage + ");")
.attr("aria-label", "Previous").append($("<span></span>").attr("aria-hidden", "true").append("«")));
} else {
_hasPreviousPage.addClass("disabled").append($("<a></a>").attr("href", "javascript:void(0)")
.attr("aria-label", "Previous").append($("<span></span>").attr("aria-hidden", "true").append("«")));
}
_ul.append(_isFirstPage).append(_hasPreviousPage);
$.each(data.info.pageInfo.navigatepageNums, function (index, item) {
var _li = $("<li></li>");
if (item == data.info.pageInfo.pageNum) {
_li.addClass("active").append($("<a></a>").attr("href", "javascript:void(0);")
.append(item).append($("<span></span>").addClass("sr-only").append("(current)")));
} else {
_li.append($("<a></a>").attr("href", "javascript:gotoPage(" + item + ");").append(item));
}
_ul.append(_li);
});
var _hasNextPage = $("<li></li>");
if (data.info.pageInfo.hasNextPage) {
var nPage = data.info.pageInfo.pageNum + 1;
_hasNextPage.append($("<a></a>").attr("href", "javascript:gotoPage(" + nPage + ")")
.attr("aria-label", "Next").append($("<span></span>").attr("aria-hidden", "true").append("»")));
} else {
_hasNextPage.addClass("disabled").append($("<a></a>").attr("href", "javascript:void(0)")
.attr("aria-label", "Next").append($("<span></span>").attr("aria-hidden", "true").append("»")));
}
var _isLastPage = $("<li></li>");
if (data.info.pageInfo.isLastPage) {
_isLastPage.addClass("disabled").append($("<a></a>").attr("href", "javascript:void(0)").append("末页"));
} else {
_isLastPage.append($("<a></a>").attr("href", "javascript:gotoPage(" + data.info.pageInfo.pages + ")").append("末页"));
}
_ul.append(_hasNextPage).append(_isLastPage);
_nav.append(_ul).appendTo(_PageDetail);
};
function pageSpan(data) {
var _pageNum = data.info.pageInfo.pageNum;
var _pages = data.info.pageInfo.pages;
var _pageSize = data.info.pageInfo.pageSize;
var _total = data.info.pageInfo.total;
var _div = $("#pageSpan");
_div.empty();
_div.append("当前" + _pageNum + "页/总" + _pages + "页,每页显示" + _pageSize
+ "条数据,总共" + _total + "条数据");
rowPage = _total;
pageNum = _pageNum;
};
function addEmpData(data) {
var _list = data.info.pageInfo.list;
var _tbody = $("#myData");
_tbody.empty();
$.each(_list,
function (index, item) {
var _tr = $("<tr></tr>");
var _empId = $("<th></th>").attr("scope", "row").append($("<input>")
.attr("type", "checkbox").attr("name", "ids").attr("value", item.empId));
var _empName = $("<td></td>").append(item.empName);
var _deptName = $("<td></td>").append(
item.department.deptName);
var _empEmail = $("<td></td>").append(item.empEmail);
var _empSex = $("<td></td>").append(
item.empSex == "M" ? "女" : "男");
var _empBirthday = $("<td></td>").append(
item.empBirthday);
var _btnTd = $("<td></td>");
var _btnEdit = $("<button></button>").addClass(
"btn btn-sm btn-primary btn-edit").attr("aria-label",
"Left Align").attr("empId", item.empId).append(
$("<span></span>").addClass(
"glyphicon glyphicon-pencil").attr(
"aria-hidden", "true")).append("修改");
var _btnDelete = $("<button></button>").addClass(
"btn btn-sm btn-danger btn-del").attr("aria-label",
"Left Align").attr("empId", item.empId).append(
$("<span></span>").addClass(
"glyphicon glyphicon-trash").attr(
"aria-hidden", "true")).append("删除");
_btnTd.append(_btnEdit).append(" ").append(_btnDelete);
_tr.append(_empId).append(_empName).append(_deptName)
.append(_empEmail).append(_empSex).append(
_empBirthday).append(_btnTd);
_tbody.append(_tr);
});
};
//校验
function common_validate(el, state, msg) {
if ("success" == state) {
$(el).parent().removeClass("has-error").addClass("has-success");
$(el).next().text("");
} else {
$(el).parent().removeClass("has-success").addClass("has-error");
$(el).next().text(msg);
}
};
function validateFormFunction() {
//校验姓名
var _empName = $("#empName").val();
var _empNameReg = /(^[a-zA-Z0-9_-]{3,16}$)|(^[\u2E80-\u9FFF]{2,6}$)/;
if (_empNameReg.test(_empName)) {
common_validate("#empName", "success", "");
} else {
common_validate("#empName", "error", "请输入3-16位的字符串或者2-6的中文");
return false;
}
//校验邮箱
var _empEmail = $("#empEmail").val();
var _empEmailReg = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
if (_empEmailReg.test(_empEmail)) {
common_validate("#empEmail", "success", "");
} else {
common_validate("#empEmail", "error", "请输入合法的邮箱格式");
return false;
}
return true;
};
$("#empName").change(function () {
var _empName = $(this).val();
$.ajax({
url: '${pageContext.request.contextPath}/emp/edit/checkUserName',
type: 'GET',
dataType: 'json',
data: "empName=" + _empName,
success: function (data) {
if (data.code == 500) {
$("#btnSave").attr("is-validate", "error");
common_validate("#empName", "error", date.info.msg);
return;
}
if (data.info.flag) {
$("#btnSave").attr("is-validate", "error");
common_validate("#empName", "error", "当前用户已经存在");
} else {
$("#btnSave").attr("is-validate", "success");
common_validate("#empName", "success", "当前用户可以使用");
}
}
});
});
//点击新增按钮
$("#btnSave").click(function () {
//校验表单
var flag = validateFormFunction();
if (!flag) {
return;
}
var _validate = $(this).attr("is-validate");
if ("error" == _validate) {
return;
}
$.ajax({
url: '${pageContext.request.contextPath}/emp/edit',
type: 'post',
dataType: 'json',
data: $("#empSaveForm").serialize(),
success: function (data) {
if (data.code == 200) {
$('#myModal').modal("hide");
gotoPage(rowPage);
}
}
});
});
function cleraAllContent() {
$("#empSaveForm").get(0).reset();
$("#empSaveForm").find("*").removeClass("has-error has-success");
$("#empSaveForm .help-block").text("");
}
//点击新增按钮
$("#btnSaveUI").click(function () {
cleraAllContent();
//弹出对话框,拿到部门信息
addDeptsData("#selectDept");
$('#myModal').modal({
"backdrop": "static"
});
});
//给每个修改按钮绑定一个点击事件
$(document).on("click", ".btn-edit", function (index, item) {
var empId = $(this).attr("empid");
addDeptsData("#empEditDept");
addEmpByEmpId(empId);
$("#btnEdit").attr("edit-id", empId)
$("#myEditModal").modal({
"backdrop": "static"
});
});
function addEmpByEmpId(empId) {
$.ajax({
type: "GET",
url: "${pageContext.request.contextPath}/emp/edit/" + empId,
dataType: "json",
async: false,
success: function (data) {
var _emp = data.info.employee;
console.log(_emp);
$("#empEditName").text(_emp.empName);
$("#empEditEmail").val(_emp.empEmail);
$("#empEditBirthday").val(_emp.empBirthday);
$("#empEditFrom input[name = 'empSex']").val([_emp.empSex]);
$("#empEditDept").val([_emp.deptId]);
}
});
};
$("#btnEdit").click(function () {
var edit_id = $(this).attr("edit-id");
// 发送ajax请求,进行页面修改的操作
$.ajax({
type: "PUT",
url: "${pageContext.request.contextPath}/emp/edit/" + edit_id,
data: $("#empEditFrom").serialize(),
dataType: "json",
success: function (data) {
if (data.code == 200) {
// 关闭修改窗口
$("#myEditModal").modal("hide");
// 跳转到当前的页面
gotoPage(pageNum);
}
}
});
});
//给每个删除按钮绑定一个点击事件
$(document).on("click", ".btn-del", function (index, item) {
var empId = $(this).attr("empid");
var empName = $(this).parents("tr").find("td:eq(0)").text();
var flag = window.confirm("你确定删除" + empName + "吗?");
if (flag) {
delEmpByEmpId(empId);
} else {
gotoPage(pageNum);
}
});
function delEmpByEmpId(empId) {
$.ajax({
type: "DELETE",
url: "${pageContext.request.contextPath}/emp/edit/" + empId,
dataType: "json",
success: function (data) {
if (data.code == 200) {
gotoPage(pageNum);
}
}
});
};
//给每一个复选框绑定一个点击事件
$(document).on("click", "input[name='ids']", function () {
var _len = $("input[name='ids").length;
var _cks = $("input[name='ids']:checked").length;
if (_len == _cks) {
$("#ckAll").prop("checked", true);
} else {
$("#ckAll").prop("checked", false);
}
});
$("#batchDel").click(function () {
var _cks = $("input[name='ids']:checked");
var _len = _cks.length;
if (_len > 0) {
var _emps = [];
var _empIds = [];
$.each(_cks, function (index, item) {
_emps.push($(this).parent("th").next("td").text());
_empIds.push($(this).val());
});
if (window.confirm("你确定要删除[" + _emps.join(" ") + "]吗?")) {
var _emp = _empIds.join(",");
$.ajax({
type: "DELETE",
url: "${pageContext.request.contextPath}/emp/edit/" + _emp,
dataType: "json",
success: function (data) {
if (data.code == 200) {
gotoPage(pageNum);
}
}
});
}
} else {
alert("你至少选中一项数据进行删除")
}
});
</script>
</body>
</html>
该项目主要是对SSM整合然后结合Bootstrap框架实现的CRUD操作,以上是一些核心代码,我已把项目开源到GitHub上,URL=https://github.com/LikemeXY/SSM-EMP.git
还望各位大佬可以在评论区讨论并指出此项目的不足之处!