起名字
添加目录结构
更改设置
对应各个文件夹
接下来导入各种依赖包
搜索Maven repository,找spring springmvc 各种依赖坐标
pom.xml文件:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.practice</groupId>
<artifactId>SSMManager</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>SSMManager Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- Spring Spring MVC -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!--json支持-->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
<!-- Spring JDBC -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- Spring面向切面-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!--Spring-test-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.6.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- Mybatis-->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!--Mybatis分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.4</version>
</dependency>
<!-- Mybatis 整合 Spring -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!--数据库连接池和驱动-->
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
<!-- jstl servlet-api -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- mybatis generator-->
<!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.6</version>
</dependency>
</dependencies>
<build>
<finalName>SSMManager</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
引入静态文件
主页index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="zh-CN">
<head>
<title>欢迎使用</title>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="static/bootstrap-3.3.7-dist/js/jquery-3.2.1.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<!-- Bootstrap -->
<link href="static/bootstrap-3.3.7-dist/css/bootstrap.css" rel="stylesheet">
</head>
<body>
<h1>你好,世界!</h1>
<button class="btn btn-success">成功</button>
</body>
</html>
ssm关键配置文件
web.xml添加:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 启动spring的容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描所有组件-->
<context:component-scan base-package="com.ssmManager">
<!--不扫描controller-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- Spring的配置文件 主要配置和业务逻辑相关的-->
<!--====================================数据源=============================================-->
<context:property-placeholder location="classpath:dbconfig.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="maxActive" value="10"/>
<property name="minIdle" value="5"/>
</bean>
<!-- ================================配置和Mybatis的整合====================================-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--指定mybatis全局配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
<!-- 配置扫描器 动态将mybatis接口的实现加入到ioc容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--扫描所有的dao接口-->
<property name="basePackage" value="com.ssmManager.dao"/>
</bean>
<!--配置一个可以批量执行sql的sqlsession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
<constructor-arg name="executorType" value="BATCH"/>
</bean>
<!--====================================事务控制的配置========================================-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--控制住数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--开启基于注解的事务 比较重要的使用xml配置-->
<aop:config>
<!-- 切入点表达式-->
<aop:pointcut id="txPointcut" expression="execution(* com.ssmManager.service..*(..))"/>
<!-- 配置事务增强-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>
<!--配置事务增强 事务如何切入-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--所有方法都是事务方法-->
<tx:method name="*"/>
<!--以get开头的所有方法-->
<tx:method name="get*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- ====================以上就是spring配置的核心 数据源、与mybatis的整合、事务控制===================-->
</beans>
springMVC.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- SpringMVC 的配置文件 网站跳转逻辑-->
<!--
默认扫描base-package下的所有,禁用默认,改为只扫描@Controller的类
-->
<context:component-scan base-package="com.ssmManager" use-default-filters="false">
<!-- 只扫描控制器-->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 配置视图解析器 方便页面返回信息-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 两个标准配置 -->
<!-- 把springMVC不能处理的请求交给tomcat -->
<mvc:default-servlet-handler/>
<!-- 能支持springmvc更高级的功能 JSR303校验 快捷的ajax 映射动态请求等-->
<mvc:annotation-driven/>
</beans>
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">
<configuration>
<!--settings参考官方文档-->
<settings>
<!--驼峰命名-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--将动态拼接的sql打印在控制台-->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<typeAliases>
<!--类型别名-->
<package name="com.ssmManager.bean"/>
</typeAliases>
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库 -->
<property name="helperDialect" value="mysql" />
<!--分页合理化,大于总页数时显示最后一页-->
<property name="reasonable" value="true"/>
</plugin>
</plugins>
</configuration>
mybatis逆向工程:
到官网找quickstart的xml实例
修改为自己的东西
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <context id="DB2Tables" targetRuntime="MyBatis3"> <!--去除生成的注释--> <commentGenerator> <property name="suppressAllComments" value="true"/> </commentGenerator> <!-- 修改为自己的东西--> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/ssmManager" userId="root" password="123"> </jdbcConnection> <javaTypeResolver > <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!--javaBean生成的位置--> <javaModelGenerator targetPackage="com.ssmManager.bean" targetProject=".\src\main\java"> <property name="enableSubPackages" value="true" /> <property name="trimStrings" value="true" /> </javaModelGenerator> <!--指定sql映射文件生成位置--> <sqlMapGenerator targetPackage="mapper" targetProject=".\src\main\resources"> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <!-- 指定dao接口生成的位置 mapper接口--> <javaClientGenerator type="XMLMAPPER" targetPackage="com.ssmManager.dao" targetProject=".\src\main\java"> <property name="enableSubPackages" value="true" /> </javaClientGenerator> <!--table指定每个表的生成策略--> <table tableName="tbl_emp" domainObjectName="Employee"></table> <table tableName="tbl_dpt" domainObjectName="Department"></table> </context> </generatorConfiguration>
注意:当mysql驱动为高版本时url要写成这样: jdbc.url=jdbc:mysql://localhost:3306/ssmManager?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
- 执行代码生成(官网可以找到)
public class MabatisGeneratorTest { public static void main(String[] args) throws IOException, XMLParserException, InvalidConfigurationException, SQLException, InterruptedException { List<String> warnings = new ArrayList<String>(); boolean overwrite = true; File configFile = new File("F:\\workspaces\\SSMManager\\src\\main\\resources\\mybatis-generator.xml"); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(configFile); DefaultShellCallback callback = new DefaultShellCallback(overwrite); MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); } }
用spring提供的单元测试:
原生测试需要先创建sprig ioc容器,然后从容器中取bean
用spring的测试,注解帮我们创建容器,需要用什么就autowired就行了
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:applicationContext.xml"}) public class MapperTest { @Autowired DepartmentMapper departmentMapper; @Test public void test1(){ //原生测试 /* ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml"); DepartmentMapper departmentMapper = ioc.getBean(DepartmentMapper.class); */ //推荐使用spring测试 System.out.println(departmentMapper); } }
用spring提供的单元测试测MVC:
import com.github.pagehelper.PageInfo; import com.ssmManager.bean.Employee; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import java.util.Arrays; import java.util.List; /** * springMVC的测试方法 */ @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(locations = {"classpath:applicationContext.xml", "classpath:springMVC.xml"}) public class MVCTest { //传入springmvc的ioc容器 @Autowired WebApplicationContext context; //虚拟mvc请求,获取到处理结果 MockMvc mockMvc; @Before public void initMock() { mockMvc = MockMvcBuilders.webAppContextSetup(context).build(); } @Test public void test1() throws Exception { MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/emps").param("pagenumber", "5")).andReturn(); //检查请求域中是否有pageInfo MockHttpServletRequest request = result.getRequest(); PageInfo pageInfo = (PageInfo) request.getAttribute("pageInfo"); System.out.println("当前页码:" + pageInfo.getPageNum()); System.out.println("总页码:" + pageInfo.getPages()); System.out.println("总记录数:" + pageInfo.getTotal()); System.out.println("连续显示的页码:" + Arrays.toString(pageInfo.getNavigatepageNums())); List<Employee> list = pageInfo.getList(); for (Employee employee : list) { System.out.println(employee.toString()); } } }
前端的东西:
前端页面中项目路径的写法:
<%
application.setAttribute("APP_PATH",request.getContextPath());
%>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="${APP_PATH}/static/bootstrap-3.3.7-dist/js/jquery-3.2.1.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="${APP_PATH}/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<!-- Bootstrap -->
<link href="${APP_PATH}/static/bootstrap-3.3.7-dist/css/bootstrap.css" rel="stylesheet">
第一个页面list.jsp
(使用原生html写):
- c标签的使用
- bootstrap表格、按钮等的基本使用
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>员工列表</title>
<%
application.setAttribute("APP_PATH", request.getContextPath());
%>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="${APP_PATH}/static/bootstrap-3.3.7-dist/js/jquery-3.2.1.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="${APP_PATH}/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<!-- Bootstrap -->
<link href="${APP_PATH}/static/bootstrap-3.3.7-dist/css/bootstrap.css" rel="stylesheet">
</head>
<body>
<div class="container">
<%--标题--%>
<div class="row">
<div class="col-md-12">
<h1>人事管理</h1>
</div>
</div>
<%--两个按钮--%>
<div class="row">
<div class="col-md-4 col-md-offset-8">
<button type="button" class="btn btn-success btn-sm"> 新增 </button>
<button type="button" class="btn btn-danger btn-sm"> 删除 </button>
</div>
</div>
<%--表格--%>
<div class="row">
<div class="col-md-12">
<table class="table table-hover">
<tr>
<td>#</td>
<td>姓名</td>
<td>性别</td>
<td>email</td>
<td>部门</td>
<td>操作</td>
</tr>
<c:forEach items="${pageInfo.list}" var="emp">
<tr>
<td>${emp.empId}</td>
<td>${emp.empName}</td>
<td>${emp.gender=="M"?"男":"女"}</td>
<td>${emp.email}</td>
<td>${emp.department.deptName}</td>
<td>
<button type="button" class="btn btn-success btn-sm">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> 编辑
</button>
<button type="button" class="btn btn-danger btn-sm">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span> 删除
</button>
</td>
</tr>
</c:forEach>
</table>
</div>
</div>
<div class="row">
<div class="col-md-6">
当前第 ${pageInfo.pageNum} 页,总共 ${pageInfo.pages} 页,共${pageInfo.total}条记录
</div>
<div class="col-md-6">
<nav aria-label="Page navigation">
<ul class="pagination">
<li ><a href="${APP_PATH}/emps?pagenumber=1">首页</a></li>
<c:if test="${pageInfo.hasPreviousPage}">
<li>
<a href="${APP_PATH}/emps?pagenumber=${pageInfo.pageNum-1}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
</c:if>
<c:forEach items="${pageInfo.navigatepageNums}" var="page_Num">
<c:if test="${page_Num == pageInfo.pageNum}">
<li class="active"><a href="#">${page_Num}</a></li>
</c:if>
<c:if test="${page_Num != pageInfo.pageNum}">
<li><a href="${APP_PATH}/emps?pagenumber=${page_Num}">${page_Num}</a></li>
</c:if>
</c:forEach>
<c:if test="${pageInfo.hasNextPage}">
<li>
<a href="${APP_PATH}/emps?pagenumber=${pageInfo.pageNum+1}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</c:if>
<li ><a href="${APP_PATH}/emps?pagenumber=${pageInfo.pages}">末页</a></li>
</ul>
</nav>
</div>
</div>
</div>
</body>
</html>
效果图:
下面将熟悉使用ajax写法(所有与后端的交互都用ajax):
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
<%
application.setAttribute("APP_PATH", request.getContextPath());
%>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="${APP_PATH}/static/bootstrap-3.3.7-dist/js/jquery-3.2.1.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="${APP_PATH}/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<!-- Bootstrap -->
<link href="${APP_PATH}/static/bootstrap-3.3.7-dist/css/bootstrap.css" rel="stylesheet">
</head>
<body>
<!-- 员工添加模态框 -->
<div class="modal fade" id="empAddModal" 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" novalidate>
<div class="form-group">
<label class="col-sm-2 control-label">姓名</label>
<div class="col-sm-10">
<input name="empName" class="form-control" id="empNameInput" placeholder="姓名">
<span class="help-block"></span>
</div>
</div>
<div class="form-group">
<label for="emailInput" class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input name="email" class="form-control" id="emailInput" placeholder="Email">
<span class="help-block"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">性别</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="gender" id="maleRadio" value="M" checked="checked"> 男
</label>
<label class="radio-inline">
<input type="radio" name="gender" id="femaleRadio" value="F"> 女
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">部门</label>
<div class="col-sm-3">
<%--部门提交部门id即可--%>
<select name="dId" class="form-control">
</select>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-default" data-dismiss="modal">关闭</button>
<button id="empSaveBtn" class="btn btn-primary" onclick="empSave()">保存</button>
</div>
</div>
</div>
</div>
<!-- 员工修改模态框 -->
<div class="modal fade" id="empModifyModal" 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">员工修改</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" novalidate>
<div class="form-group">
<label class="col-sm-2 control-label">姓名</label>
<div class="col-sm-10">
<input name="empName" class="form-control" id="empNameModifyInput" placeholder="姓名">
<span class="help-block"></span>
</div>
</div>
<div class="form-group">
<label for="emailInput" class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input name="email" class="form-control" id="emailModifyInput" placeholder="Email">
<span class="help-block"></span>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">性别</label>
<div class="col-sm-10">
<label class="radio-inline">
<input type="radio" name="gender" id="maleModifyRadio" value="M" checked="checked"> 男
</label>
<label class="radio-inline">
<input type="radio" name="gender" id="femaleModifyRadio" value="F"> 女
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">部门</label>
<div class="col-sm-3">
<%--部门提交部门id即可--%>
<select id="dept_options" name="dId" class="form-control">
</select>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-default" data-dismiss="modal">关闭</button>
<button id="empModifyBtn" class="btn btn-primary" onclick="empModify()">更新</button>
</div>
</div>
</div>
</div>
<div class="container">
<%--标题--%>
<div class="row">
<div class="col-md-12">
<h1>人事管理</h1>
</div>
</div>
<%--两个按钮--%>
<div class="row">
<div class="col-md-4 col-md-offset-8">
<button id="emp_add_btn" type="button" class="btn btn-success btn-sm"> 新增</button>
<button id="emp_delete_all_btn" type="button" class="btn btn-danger btn-sm"> 删除</button>
</div>
</div>
<%--表格--%>
<div class="row">
<div class="col-md-12">
<table id="emps_table" class="table table-hover">
<thead>
<tr>
<td>
<input type="checkbox" id="check_all"/>
</td>
<td>#</td>
<td>姓名</td>
<td>性别</td>
<td>email</td>
<td>部门</td>
<td>操作</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<div class="row">
<div id="pageInfo_area" class="col-md-6"></div>
<div class="col-md-6">
<nav aria-label="Page navigation">
<ul id="page_nav_area" class="pagination">
</ul>
</nav>
</div>
</div>
<script type="text/javascript">
var currentPageNum;
//异步刷新page内容
function to_page(pagenumber) {
$.ajax({
url: "${APP_PATH}/emps",
data: "pagenumber=" + pagenumber,
type: "get",
success: function (result) {
//解析并显示员工数据
//console.log(result);
build_emps_table(result);
build_page_nav(result);
}
})
}
//页面加载完成后直接发送ajax请求要数据
$(function () {
to_page(1);
})
//添加表格数据
function build_emps_table(result) {
$("#emps_table tbody").empty();
var emps = result.extend.pageInfo.list;
$.each(emps, function (index, item) {
//alert(item.empName);
var empIdTd = $("<td></td>").append(item.empId);
var empNameTd = $("<td></td>").append(item.empName);
var empGenderTd = $("<td></td>").append(item.gender == 'M' ? "男" : "女");
var emailTd = $("<td></td>").append(item.email);
var deptNameTd = $("<td></td>").append(item.department.deptName);
var editBtn = $("<button></button>")
.addClass("btn btn-success btn-sm edit_btn").attr("edit_id", item.empId)
.append($("<span></span>").addClass("glyphicon glyphicon-pencil")).append(" 编辑");
//给更新按钮添加id
var deleteBtn = $("<button></button>")
.addClass("btn btn-danger btn-sm delete_btn").attr("delete_id", item.empId)
.append($("<span></span>").addClass("glyphicon glyphicon-trash")).append(" 删除");
var btnTd = $("<td></td>").append(editBtn).append(" ").append(deleteBtn);
var checkbox = $("<td><input type='checkbox' class='check_item'/></td>");
$("<tr></tr>").append(checkbox)
.append(empIdTd)
.append(empNameTd)
.append(empGenderTd)
.append(emailTd)
.append(deptNameTd)
.append(btnTd)
.appendTo("#emps_table tbody");
})
}
//添加页面信息和导航栏信息
function build_page_nav(result) {
var pageInfo = result.extend.pageInfo;
$("#pageInfo_area").empty();
$("#pageInfo_area").append("当前第" + pageInfo.pageNum + "页,共" + pageInfo.pages + "页,共" + pageInfo.total + "条记录");
currentPageNum = pageInfo.pageNum;
var pageNavArea = $("#page_nav_area");
pageNavArea.empty();
var firstPageLi = $("<li></li>").append($("<a></a>").append("首页"));
firstPageLi.click(function () {
to_page(1);
});
if (pageInfo.hasPreviousPage) {
var previousLi = $("<li></li>").append($("<a></a>").append("«"));
previousLi.click(function () {
to_page(pageInfo.pageNum - 1);
})
}
pageNavArea.append(firstPageLi).append(previousLi);
$.each(pageInfo.navigatepageNums, function (index, item) {
var numLi = $("<li></li>").append($("<a></a>").append(item));
if (pageInfo.pageNum === item) {
numLi.addClass("active");
}
numLi.click(function () {
to_page(item);
})
$("#page_nav_area").append(numLi);
})
if (pageInfo.hasNextPage) {
var nextLi = $("<li></li>").append($("<a></a>").append("»"));
nextLi.click(function () {
to_page(pageInfo.pageNum + 1);
});
}
var lastPageLi = $("<li></li>").append($("<a></a>").append("末页"));
lastPageLi.click(function () {
to_page(pageInfo.pages);
});
pageNavArea.append(nextLi).append(lastPageLi);
}
//姓名ajax校验是否可用
$("#empNameInput").change(function () {
var empName = this.value;
$.ajax({
url: "${APP_PATH}/checkuser",
data: "empName=" + empName,
type: "post",
success: function (result) {
if (result.code === 100) {
show_validate_msg($("#empNameInput"), "success", "用户名可用");
$("#empSaveBtn").attr("ajax_validate", "success");
} else if (result.code === 200) {
show_validate_msg($("#empNameInput"), "error", "用户名不可用");
$("#empSaveBtn").attr("ajax_validate", "error");
}
}
})
});
//表单校验
function validate_form() {
var empNameInput = $("#empNameInput");
var empName = empNameInput.val();
var regName = /^[a-zA-Z0-9_-]{4,16}$/;
if (!regName.test(empName)) {
show_validate_msg(empNameInput, "error", "用户名4到6位的字符");
return false;
} else {
show_validate_msg(empNameInput, "success", "");
}
var empEmailInput = $("#emailInput");
var regEmail = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
if (!regEmail.test(empEmailInput.val())) {
show_validate_msg(empEmailInput, "error", "邮箱格式不正确");
return false;
} else {
show_validate_msg(empEmailInput, "success", "");
}
return true;
}
//显示校验信息
function show_validate_msg(element, status, msg) {
element.parent().removeClass("has-success has-error");
element.next("span").text("");
if ("success" == status) {
element.parent().addClass("has-success");
} else if ("error" == status) {
element.parent().addClass("has-error");
}
element.next("span").text(msg);
}
//表单提交
function empSave() {
//先对要提交的进行校验
if (!validate_form()) {
return false;
}
if ($("#empSaveBtn").attr("ajax_validate") == "error") {
return false;
}
$.ajax({
url: "${APP_PATH}/emp",
type: "post",
data: $("#empAddModal form").serialize(),
success: function (result) {
if (result.code === 100) {
$("#empAddModal").modal("hide");
//由分页合理化插件去判别
to_page(9999);
} else {
alert("添加失败");
}
}
});
}
//表单重置
function form_reset(ele) {
ele[0].reset();
//清空样式
ele.find("*").removeClass("has-error has-success");
ele.find(".help-block").text("");
}
//ajax查出部门信息填充
function getDepts(container) {
var select = $(container + " select");
select.empty();
$.ajax({
url: "${APP_PATH}/depts",
type: "get",
success: function (result) {
//console.log(result);
var departments = result.extend.departments;
$.each(departments, function (index, item) {
select.append($("<option></option>>").append(item.deptName).attr("value", item.deptId));
})
}
});
}
//新增按钮点击事件
$("#emp_add_btn").click(function () {
//表单重置
form_reset($("#empAddModal form"));
getDepts("#empAddModal");
$("#empAddModal").modal({
backdrop: "static"
});
});
$('#empAddModal').on('shown.bs.modal', function () {
$('#empNameInput').focus(); //通过ID找到对应输入框,让其获得焦点
});
//编辑按钮事件
$(document).on("click", ".edit_btn", function () {
//填充部门
getDepts("#empModifyModal");
//填充信息
getEmp($(this).attr("edit_id"));
//给更新按钮添加id信息
$("#empModifyBtn").attr("edit_id", $(this).attr("edit_id"));
$("#empModifyModal").modal();
});
function getEmp(id) {
$.ajax({
url: "${APP_PATH}/emp/" + id,
type: "get",
success: function (result) {
console.log(result);
var empData = result.extend.emp;
$("#empModifyModal #empNameModifyInput").val(empData.empName);
$("#empModifyModal #emailModifyInput").val(empData.email);
$("#empModifyModal input[name=gender]").val([empData.gender]);
$("#empModifyModal select").val([empData.dId]);
}
})
}
//更新按钮事件
function empModify() {
//各种校验
//更新数据
$.ajax({
url: "${APP_PATH}/emp",
type: "put",
data: $("#empModifyModal form").serialize() + "&empId=" + $("#empModifyBtn").attr("edit_id"),
success: function (result) {
//console.log(result);
$("#empModifyModal").modal("hide");
to_page(currentPageNum);
}
})
}
//删除按钮事件
$(document).on("click", ".delete_btn", function () {
//第二个td的内容
var empName = $(this).parents("tr").find("td:eq(2)").text();
var empId = $(this).attr("delete_id");
if (confirm("确认删除【" + empName + "】吗?")) {
$.ajax({
url: "${APP_PATH}/emp/" + empId,
type: "delete",
success: function () {
to_page(currentPageNum);
}
})
}
});
//全选 全不选
$("#check_all").click(function () {
$(".check_item").prop("checked", $(this).prop("checked"));
});
//只要有一个不选,全选为false
$(document).on("click", ".check_item", function () {
var flag = $(".check_item:checked").lengeh == $(".check_item");
$("#check_all").prop("checked", flag);
})
//点击全部删除
$("#emp_delete_all_btn").click(function () {
var empNames = "";
var empIds = "";
$.each($(".check_item:checked"), function (index, item) {
empNames += $(this).parents("tr").find("td:eq(2)").text() + " ";
empIds += $(this).parents("tr").find("td:eq(1)").text()+"-";
});
empIds = empIds.substring(0,empIds.length-1);
if (confirm("确认删除【" + empNames + "】吗?")) {
$.ajax({
url: "${APP_PATH}/emp/" + empIds,
type: "delete",
success: function (result) {
to_page(currentPageNum);
}
})
}
});
</script>
</div>
</body>
</html>