> 文档中心 > SSM整合项目

SSM整合项目

文章目录

  • SSM整合项目
    • 一、项目简介
      • 1.项目简介
      • 2.主要实现的功能
      • 3.涉及的技术
      • 4.最终效果图
    • 二、搭建环境
      • 1.创建Maven工程,添加依赖
      • 2.再Maven下部署web工程
      • 3.在resources目录中配置框架的配置文件
        • 1.SpringMVC的配置文件
        • 2.Spring的配置文件
        • 3.jdbc信息 jdbc.properties
        • 4.MyBatis的配置文件
        • 5.MyBatis逆向工程的配置
        • 6.创建数据库表
      • 4.完成逆向工程创建
    • 三、查询功能实现
      • 1.需要实现的功能
      • 2.利用zui前端框架快速搭建index.html页面
      • 3.修改EmpMapper接口
      • 4.修改EmpMapper.xml文件
      • 5.添加 Msg 类引入链式编程
      • 5.编写service层的方法
      • 6.编写Controller层的方法
      • 效果图:
    • 四、新增功能的实现
      • 1.需要实现的功能
      • 2.编写service层的方法
      • 3.编写Controller层的方法
      • 4.index.html界面(部分)
      • 效果图:
    • 五、修改数据的实现
      • 1.需要实现的功能
      • 2.编写Service层的方法
      • 3.编写Controller层的方法
      • 4.index.html界面(部分)
      • 效果图
    • 六、删除数据的实现
      • 1.需要实现的功能
      • 2.编写Service层的方法
      • 3.编写Controller层的方法
      • 4.index.html界面(部分)
      • 效果图:
    • 项目总结

[GitHub项目地址:]https://github.com/sundaybody/SSM-study.git

SSM整合项目

一、项目简介

1.项目简介

使用ssm框架搭建出一套简单的CRUD的项目,主要涉及员工表和部门表,实现员工表的增删改查,其中每个员工对应这一个部门,属于多对一的关系,部门表和员工表属于多对一的关系

2.主要实现的功能

1.分页展示所有员工的基本信息

2.实现添加员工和删除员工

3.实现修改员工信息

4.实现批量删除员工信息

5.实现员工添加和修改时的数据校验工作

​ ▪jQuery前端校验用户名和邮箱是否合法

​ ▪Ajax请求校验用户名是否重复

​ ▪JSR303后端检验用户名、邮箱是否合法以及用户名是否重复

3.涉及的技术

1.后端框架:Spring5+SpringMVC+MyBatis3

2.前端技术:zui开源HTML5框架,html5

3.视图渲染技术:thymeleaf

4.MyBatis分页插件:PageHelper

5.MyBatis逆向工程:mybatis-generator

6.RESTfui风格url

7.数据库:MySql 5.7+c3p0数据库连接池技术

4.最终效果图

在这里插入图片描述

二、搭建环境

本次项目的环境:

idea 2021.2.1

Tomcat 8.0.24

Maven 3.6.3

jdk8

其他依赖版本见pom.xml文件

1.创建Maven工程,添加依赖

pom.xml文件 注意:打包方式为war

<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.wang.ssm</groupId>    <artifactId>ssmbuild2.0</artifactId>    <version>1.0-SNAPSHOT</version>    <packaging>war</packaging>    <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target>    </properties>            <dependencies> <dependency>     <groupId>org.springframework</groupId>     <artifactId>spring-webmvc</artifactId>     <version>5.3.9</version> </dependency>  <dependency>     <groupId>org.springframework</groupId>     <artifactId>spring-jdbc</artifactId>     <version>5.3.9</version> </dependency>  <dependency>     <groupId>org.springframework</groupId>     <artifactId>spring-test</artifactId>     <version>5.3.9</version>     <scope>test</scope> </dependency>  <dependency>     <groupId>org.springframework</groupId>     <artifactId>spring-aspects</artifactId>     <version>5.3.9</version> </dependency>  <dependency>     <groupId>org.mybatis</groupId>     <artifactId>mybatis</artifactId>     <version>3.4.6</version> </dependency>  <dependency>     <groupId>org.mybatis</groupId>     <artifactId>mybatis-spring</artifactId>     <version>1.3.2</version> </dependency>  <dependency>     <groupId>com.mchange</groupId>     <artifactId>c3p0</artifactId>     <version>0.9.5.2</version> </dependency> <dependency>     <groupId>mysql</groupId>     <artifactId>mysql-connector-java</artifactId>     <version>8.0.27</version> </dependency>  <dependency>     <groupId>javax.servlet</groupId>     <artifactId>jstl</artifactId>     <version>1.2</version> </dependency> <dependency>     <groupId>javax.servlet</groupId>     <artifactId>javax.servlet-api</artifactId>     <version>3.1.0</version>     <scope>provided</scope> </dependency> <dependency>     <groupId>junit</groupId>     <artifactId>junit</artifactId>     <version>4.12</version>     <scope>test</scope> </dependency>  <dependency>     <groupId>org.thymeleaf</groupId>     <artifactId>thymeleaf-spring5</artifactId>     <version>3.0.12.RELEASE</version> </dependency>  <dependency>     <groupId>org.mybatis.generator</groupId>     <artifactId>mybatis-generator-core</artifactId>     <version>1.3.5</version> </dependency>  <dependency>     <groupId>com.github.pagehelper</groupId>     <artifactId>pagehelper</artifactId>     <version>5.2.0</version> </dependency>  <dependency>     <groupId>com.fasterxml.jackson.core</groupId>     <artifactId>jackson-databind</artifactId>     <version>2.12.1</version> </dependency>  <dependency>     <groupId>org.hibernate</groupId>     <artifactId>hibernate-validator</artifactId>     <version>6.0.17.Final</version> </dependency>     </dependencies>    <build>  <plugins>          <plugin>  <groupId>org.mybatis.generator</groupId>  <artifactId>mybatis-generator-maven-plugin</artifactId>  <version>1.3.0</version>    <dependencies>            <dependency>   <groupId>org.mybatis.generator</groupId>   <artifactId>mybatis-generator-core</artifactId>   <version>1.3.5</version>      </dependency>            <dependency>   <groupId>com.mchange</groupId>   <artifactId>c3p0</artifactId>   <version>0.9.5.2</version>      </dependency>            <dependency>   <groupId>mysql</groupId>   <artifactId>mysql-connector-java</artifactId>   <version>8.0.27</version>      </dependency>  </dependencies>     </plugin> </plugins>    </build></project>

2.再Maven下部署web工程

在/src/main 下创建webapp目录配置web.xml文件

web.xml 整合Spring和SpringMVC

字符编码过滤器 ,一定要放在所有过滤器之前

<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">        <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>        <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param>     <param-name>contextConfigLocation</param-name>     <param-value>classpath:SpringMVC.xml</param-value> </init-param> <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern>    </servlet-mapping>        <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param>     <param-name>encoding</param-name>     <param-value>utf-8</param-value> </init-param> <init-param>     <param-name>forceResponseEncoding</param-name>     <param-value>true</param-value> </init-param>    </filter>    <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern>    </filter-mapping>        <filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter </filter-class>    </filter>    <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern>    </filter-mapping>        <filter> <filter-name>FormContentFilter</filter-name> <filter-class>org.springframework.web.filter.FormContentFilter</filter-class>    </filter>    <filter-mapping> <filter-name>FormContentFilter</filter-name> <url-pattern>/*</url-pattern>    </filter-mapping></web-app

3.在resources目录中配置框架的配置文件

1.SpringMVC的配置文件

主要负责处理前端发送的请求,配置Thymeleaf视图解析器

<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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">            <context:component-scan base-package="com.wang.ssm"></context:component-scan>            <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"> <property name="order" value="1"/> <property name="characterEncoding" value="UTF-8"/> <property name="templateEngine">     <bean class="org.thymeleaf.spring5.SpringTemplateEngine">  <property name="templateResolver">      <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">      <property name="prefix" value="/WEB-INF/templates/"/>      <property name="suffix" value=".html"/>   <property name="templateMode" value="HTML5"/>   <property name="characterEncoding" value="UTF-8" />      </bean>  </property>     </bean> </property>    </bean>        <mvc:view-controller path="/" view-name="index"></mvc:view-controller>            <mvc:default-servlet-handler/>        <mvc:annotation-driven/></beans>

2.Spring的配置文件

applicationContext.xml 主要配置和业务逻辑有关的以及和MyBatis的整合

<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: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/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/tx http://www.springframework.org/schema/tx/spring-tx.xsd">        <context:component-scan base-package="com.wang"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>    </context:component-scan>        <context:property-placeholder location="classpath:jdbc.properties"/>        <bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property>    </bean>        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  <property name="configLocation" value="classpath:mybatis-config.xml"></property> <property name="dataSource" ref="pooledDataSource"></property>  <property name="mapperLocations" value="classpath:mapper/*.xml"></property>    </bean>        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  <property name="basePackage" value="com.wang.ssm.dao"></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>        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  <property name="dataSource" ref="pooledDataSource"></property>    </bean>        <aop:config>  <aop:pointcut id="txPonit" expression="execution(* com.wang.ssm.service..*(..))"/>  <aop:advisor advice-ref="txAdvice" pointcut-ref="txPonit"></aop:advisor>    </aop:config>        <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes>          <tx:method name="*"/>          <tx:method name="get*" read-only="true"/> </tx:attributes>    </tx:advice></beans>

3.jdbc信息 jdbc.properties

jdbc.driverClass=com.mysql.cj.jdbc.Driverjdbc.jdbcUrl=jdbc:mysql://localhost:13306/ssmcrudjdbc.user=rootjdbc.password=123456

4.MyBatis的配置文件

mybatis-config.xml

<configuration>    <properties resource="jdbc.properties"/>    <settings> <setting name="mapUnderscoreToCamelCase" value="true"/>    </settings>    <typeAliases> <package name="com.wang.ssm.pojo"/>    </typeAliases>    <plugins>  <plugin interceptor="com.github.pagehelper.PageInterceptor">     <property name="reasonable" value="true"/> </plugin>    </plugins>    <mappers> <package name="mapper"/>    </mappers></configuration>

5.MyBatis逆向工程的配置

generatorConfig.xml

<generatorConfiguration>        <context id="DB2Tables" targetRuntime="MyBatis3"> <commentGenerator>          <property name="suppressAllComments" value="true"/> </commentGenerator>  <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"   connectionURL="jdbc:mysql://localhost:13306/ssmcrud"   userId="root"   password="123456"> </jdbcConnection>  <javaModelGenerator targetPackage="com.wang.ssm.pojo" targetProject=".\src\main\java">     <property name="enableSubPackages" value="true" />     <property name="trimStrings" value="true" /> </javaModelGenerator>  <sqlMapGenerator targetPackage="mapper"    targetProject=".\src\main\resources">     <property name="enableSubPackages" value="true" /> </sqlMapGenerator>  <javaClientGenerator type="XMLMAPPER" targetPackage="com.wang.ssm.dao" targetProject=".\src\main\java">     <property name="enableSubPackages" value="true" /> </javaClientGenerator>    <table tableName="tbl_emp" domainObjectName="Emp"/> <table tableName="tbl_dept" domainObjectName="Dept"/>    </context></generatorConfiguration>

6.创建数据库表

CREATE TABLE `tbl_emp` (  `emp_id` int(11) NOT NULL AUTO_INCREMENT,  `emp_name` varchar(255) DEFAULT NULL,  `gender` char(1) DEFAULT NULL,  `email` varchar(255) DEFAULT NULL,  `d_id` int(11) DEFAULT NULL,  PRIMARY KEY (`emp_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE TABLE `tbl_dept` (  `dept_id` int(11) NOT NULL AUTO_INCREMENT,  `dept_name` varchar(255) DEFAULT NULL,  PRIMARY KEY (`dept_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

4.完成逆向工程创建

在pom.xml中依赖导入之后可见

在这里插入图片描述

Plugins下会出现mybatis-generator,点击下面的mybatis-generator:generate即可完成逆向工程的创建

会自动生成如下红色部分的图片

在这里插入图片描述

三、查询功能实现

1.需要实现的功能

(1)第一步,用 JSTL 实现(URI:/emps):

  • 访问 index.html 页面。
  • index.html 发送出查询员工列表的请求。
  • EmController 接收请求,查出员工的数据。
  • 来到index.html 页面进行展示。
  • 使用 PageHelper 分页插件完成分页查询的功能。

(2)第二步,用 Ajax 实现:

  • index.html 页面直接发送 Ajax 请求,进行员工分页数据的查询。
  • 服务器将查出来的数据,通过 JSON 字符串的形式返回给浏览器。
  • 浏览器收到 JSON 字符串后,用 JS 对JSON 解析,通过 DOM 增删改查页面。
  • 返回 JSON,实现客户端的无关性。

2.利用zui前端框架快速搭建index.html页面

注意:这里是完整的前端页面

<html lang="en" xmlns:th="http://www.thymeleaf.org"><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1">    <title>Title</title>    <link rel="stylesheet" th:href="@{static/dist/css/zui.min.css}">    <!--        <script th:src="@{static/dist/lib/jquery/jquery.js}"></script>        <script th:src="@{static/dist/js/zui.min.js}"></script></head><body><div class="modal fade" id="empUpdateModel">    <div class="modal-dialog"> <div class="modal-content">     <div class="modal-header">  <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">关闭</span></button>  <h4 class="modal-title">员工修改</h4>     </div>     <div class="modal-body">  <form class="form-horizontal">      <div class="form-group">   <label for="empName_update_static" class="col-sm-2">empName</label>   <div class="col-md-6 col-sm-10"><p type="text" name="empName" class="form-control-static" id="empName_update_static" placeholder="empName"></p><div class="help-block"></div>   </div>      </div>      <div class="form-group">   <label for="email_update_input" class="col-sm-2">email</label>   <div class="col-md-6 col-sm-10"><input type="text" name="email" class="form-control" id="email_update_input" placeholder="email@999.com"><div class="help-block"></div>   </div>      </div>      <div class="form-group">   <label  class="col-sm-2">gender</label>   <div class="col-md-6 col-sm-10"><label class="radio-inline">    <input type="radio" id="gender1_update_input" name="gender" value="M" checked></label><label class="radio-inline">    <input type="radio" id="gender2_update_input" name="gender" value="F"></label>   </div>      </div>      <div class="form-group">   <label for="dept_update_select" class="col-sm-2">deptName</label>   <div class="col-sm-3"><select class="form-control" name="dId" id="dept_update_select"></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="emp_update_btn">更新</button>     </div> </div>    </div></div><div class="modal fade" id="empAddModel">    <div class="modal-dialog"> <div class="modal-content">     <div class="modal-header">  <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">关闭</span></button>  <h4 class="modal-title">员工添加</h4>     </div>     <div class="modal-body">  <form class="form-horizontal">      <div class="form-group">   <label for="empName_add_input" class="col-sm-2">empName</label>   <div class="col-md-6 col-sm-10"><input type="text" name="empName" class="form-control" id="empName_add_input" placeholder="empName"><div class="help-block"></div>   </div>      </div>      <div class="form-group">   <label for="email_add_input" class="col-sm-2">email</label>   <div class="col-md-6 col-sm-10"><input type="text" name="email" class="form-control" id="email_add_input" placeholder="email@999.com"><div class="help-block"></div>   </div>      </div>      <div class="form-group">   <label  class="col-sm-2">gender</label>   <div class="col-md-6 col-sm-10"><label class="radio-inline">    <input type="radio" id="gender1_add_input" name="gender" value="M" checked></label><label class="radio-inline">    <input type="radio" id="gender2_add_input" name="gender" value="F"></label>   </div>      </div>      <div class="form-group">   <label for="dept_add_select" class="col-sm-2">deptName</label>   <div class="col-sm-3"><select class="form-control" name="dId" id="dept_add_select"></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="emp_save_btn">保存</button>     </div> </div>    </div></div><div class="container">        <div class="row"> <div class="col-md-12">     <h1>SSM_CRUD</h1> </div>    </div>        <div class="row"> <div class="col-md-4 col-md-offset-8">     <button class="btn btn-primary" id="emp_add_model_btn">新增</button>     <button class="btn btn-danger" id="emp_delete_all_btn">删除</button> </div>    </div>        <div class="row"> <div class="col-md-12">     <table class="table table-hover" id="emps_table">  <thead>      <tr>   <th><input type="checkbox" id="check_all">   </th>   <th>id</th>   <th>empName</th>   <th>gender</th>   <th>email</th>   <th>deptName</th>   <th>操作</th>      </tr>  </thead>  <tbody >  </tbody>     </table> </div>    </div>        <div class="row">  <div class="col-md-6" id="page_info_area"> </div>  <div class="col-md-6" id="page_nav_area"> </div>    </div></div><script type="text/javascript">    /*全局变量*/    var totalRecord;//总页数    var currentPage;//当前页    /*1.页面加载完成以后,直接发送一个ajax请求,要到分页数据*/    $(function () { //去首页 to_page(1)    });    function to_page(pn){ $.ajax({     url: "emps",     data: "pn="+pn,     type: "GET",     success: function (result) {  // console.log(result);  //    1.解析并显示员工数据  build_emps_table(result);  //    2.解析并显示分页信息  build_page_info(result);  //3.解析并显示分页条信息  build_page_nav(result);     } });    }    //    1.解析并显示员工数据    function build_emps_table(result) { //清空表格 否则会显示上一页的数据 $("#emps_table tbody").empty(); var emps = result.extend.pageInfo.list; $.each(emps, function (index, item) {     var checkBok=$("")     var empIdTd= $("").append(item.empId);     var  empNameTd=$("").append(item.empName);     var  genderTd=$("").append(item.gender=='M'? "男":"女");     var  emailTd=$("").append(item.email);     var  deptName=$("").append(item.dept.deptName);     var editBtn=$("").addClass("btn btn-primary edit_btn")      .append($("").addClass("icon icon-edit")).append("编辑");     //为编辑按钮添加一个自定义的属性,来表示当前员工的id     editBtn.attr("edit-id",item.empId);     var delBtn=$("").addClass("btn btn-danger delete_btn")      .append($("").addClass("icon icon-remove-sign")).append("删除");     //为删除按钮添加一个自定义的属性,来表示删除当前员工的id     delBtn.attr("del-id",item.empId);     var btnTd=$("").append(editBtn).append(" ").append(delBtn);     //append方法返回的是append     $("").     append(checkBok).     append(empIdTd).     append(empNameTd)  .append(genderTd).append(emailTd).append(deptName)  .append(btnTd)  .appendTo("#emps_table tbody"); });    }    // 2.解析并显示分页信息    function build_page_info(result){ $("#page_info_area").empty() $("#page_info_area").append("当前"+result.extend.pageInfo.pageNum+"页,总" +     result.extend.pageInfo.pages+"页,总" +result.extend.pageInfo.total+     "条记录数"); //总页数 totalRecord=result.extend.pageInfo.pages //当前页数 currentPage=result.extend.pageInfo.pageNum    }    //    2.解析并显示分页条信息    function build_page_nav(result) {    //page_nav_area $("#page_nav_area").empty(); var ul=$("
    "
    ).addClass("pager"); var firstPageLi=$("
  • "
    ).append($("").append("首页")); //构建翻页元素 var prePageLi=$("
  • "
    ).append($("").append("«")); if (result.extend.pageInfo.hasPreviousPage==false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); } //为元素添加点击翻页事件 firstPageLi.click(function (){ to_page(1); }); prePageLi.click(function (){ to_page(result.extend.pageInfo.pageNum-1); }); var nextPageLi=$("
  • "
    ).append($("").append("»")); var lastPageLi=$("
  • "
    ).append($("").append("尾页")); if (result.extend.pageInfo.hasNextPage==false){ nextPageLi.addClass("disabled"); lastPageLi.addClass("disabled"); } nextPageLi.click(function (){ to_page(result.extend.pageInfo.pageNum+1); }); lastPageLi.click(function (){ to_page(result.extend.pageInfo.pages); }); //添加首页和前一页的提示 ul.append(firstPageLi).append(prePageLi); $.each(result.extend.pageInfo.navigatepageNums,function (index,item){ var numLi=$("
  • "
    ).append($("").append(item).attr("th:href","#")); if (result.extend.pageInfo.pageNum==item){ numLi.addClass("active") } numLi.click(function (){ to_page(item) }); ul.append(numLi); }); //添加末页和后一页的提示 ul.append(nextPageLi).append(lastPageLi); ul.appendTo(page_nav_area); } //清空表单样式及内容 function reset_from(ele){ $(ele)[0].reset(); // 清空表单样式 $(ele).find("*").removeClass("has-success has-error"); $(ele).find(".help-block").text("") } //点击新增按钮 $("#emp_add_model_btn").click(function (){ //清除表单数据 (表单重置)全部重置 reset_from("#empAddModel form") //发送ajax请求,查出不部门的信息,显示下拉列表 getDepts("#dept_add_select"); //弹出模态框 $("#empAddModel").modal({ backdrop:"static" }) }); //查出所有的部门信息并显示在下拉列表中 function getDepts(ele){ //清空之前下拉列表的值 $(ele).empty(); $.ajax({ url:"depts", type: "GET", success:function (result){ // console.log(result) // {"code":100,"msg":"处理成功","extend":{"depts":[{"deptId":1,"deptName":"测试部"},{"deptId":2,"deptName":"开发部"}]}} // 显示部门信息在下拉列表中 // $("#dept_add_select").append() $.each(result.extend.depts,function (){ var optionEle=$("").append(this.deptName).attr("value",this.deptId); optionEle.appendTo(ele) }) } }); } //检验表单数据 function validate_add_form(){ // 1.拿过来要检验数据,使用正则表达式 var empName = $("#empName_add_input").val(); var regName =/(^[a-zA_Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5})/; // 校验名字 if (!regName.test(empName)) { // alert("用户名可以2-5位中文6-16英文和数字的组合") //应该清空这个元素之前的格式 show_validate_msg("#empName_add_input","error","用户名可以2-5位中文6-16英文和数字的组合"); return false; }else { show_validate_msg("#empName_add_input","success",""); } // 校验邮箱 var email =$("#email_add_input").val(); var regEmail=/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/; if (!regEmail.test(email)){ // alert("邮箱格式不正确") show_validate_msg("#email_add_input","error","邮箱格式不正确"); return false; }else { show_validate_msg("#email_add_input","success",""); } return true; } //显示校验结果的提示信息 function show_validate_msg(ele,status,msg){ //应该清空这个元素之前的格式 $(ele).parent().removeClass("has-success has-error"); $(ele).next("div").text(""); if ("success"==status){ $(ele).parent().addClass("has-success"); $(ele).next("div").text(""); }else if ("error"==status){ $(ele).parent().addClass("has-error"); $(ele).next("div").text(msg); } } $("#empName_add_input").change(function (){ // 发送ajax请求校验用户名是否可用 var empName=this.value; $.ajax({ url:"checkemp", data:"empName="+empName, type:"POST", success:function (result){ if (result.code==100){ show_validate_msg("#empName_add_input","success","用户名可用"); //给按钮添加自定义属性,用于校验数据是否合法能保存 $("#emp_save_btn").attr("ajax-va","success") }else { show_validate_msg("#empName_add_input","error",result.extend.va_msg); $("#emp_save_btn").attr("ajax-va","error") } } }); }); //点击保存,保存员工 $("#emp_save_btn").click(function (){ // 1.模态框中填写的表单数据提交给服务器进行保存 // 1.1 先对要提交给服务器的数据进行校验 if (!validate_add_form()){ return false; } // 1.2判断ajax用户名校验是否成功了成功才添加 if ($(this).attr("ajax-va")=="error"){ return false; } // 2.发送ajax请求保存员工 empAddModel $.ajax({ url:"emp", type:"POST", data:$("#empAddModel form").serialize(), success:function (result){ // alert(result.msg) if (result.code==200){ //显示失败信息 //有哪个字段的错误信息就显示哪个字段的 if (undefined!=result.extend.errorFields.email){ //显示邮箱错误信息 show_validate_msg("#email_add_input","error",result.extend.errorFields.email); } if (undefined!=result.extend.errorFields.empName){ //显示员工错误信息 show_validate_msg("#empName_add_input","error",result.extend.errorFields.empName); } }else { // 员工保存成功: // 1.关闭模拟框 $("#empAddModel").modal('hide'); // 2.来到最后一页,显示刚才保存的数据 // 显示最后一页数据 to_page(totalRecord); } } }); }); //1.我们是按钮创建之前就绑定了click,所以绑不上 // 1)可以在创建按钮的时候绑定 // 2)绑定点击 .live jQuery给所有匹配的元素附加一个事件,即使是以后添加的元素再添加进来也是有效的 //jQuery新版没有live,是用on方法替代 $(document).on("click",".edit_btn",function (){ // alert("edit") // 0查出员工信息,并显示员工信息 getEmp($(this).attr("edit-id")); // 1.查出部门信息,并显示部门列表 getDepts("#dept_update_select"); // 2 弹出模态框查出 // 3.把员工的id传递给模态框的更新按钮 $("#emp_update_btn").attr("edit-id",$(this).attr("edit-id")); $("#empUpdateModel").modal({ backdrop:"static" }) }); //绑定点击删除事件 单个删除 $(document).on("click",".delete_btn",function (){ // 1.弹出是否确认删除对话 var empName= $(this).parents("tr").find("td:eq(2)").text(); var empId = $(this).attr("del-id"); if (confirm("确认删除【"+empName+"】吗?")){ // 点击确认,发送ajax请求删除即可 $.ajax({ url:"emp/"+empId, type:"DELETE", success:function (resulet){ alert(resulet.msg); to_page(currentPage); } }); } }); //获取指定id的员工 function getEmp(id){ $.ajax({ url:"emp/"+id, type:"GET", success:function (result){ // console.log(result) var empData=result.extend.emp; $("#empName_update_static").text(empData.empName); $("#email_update_input").val(empData.email); $("#empUpdateModel input[name=gender]").val([empData.gender]); $("#empUpdateModel select").val([empData.dId]) } }); }// 点击更新,更新员工信息 $("#emp_update_btn").click(function (){ // 验证邮箱是否合法 // 校验邮箱 var email =$("#email_update_input").val(); var regEmail=/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/; if (!regEmail.test(email)){ // alert("邮箱格式不正确") show_validate_msg("#email_update_input","error","邮箱格式不正确"); return false; }else { show_validate_msg("#email_update_input","success",""); } // 2.发送ajax请求保存更新的员工数据 $.ajax({ url:"emp/"+$(this).attr("edit-id"), type:"PUT", data:$("#empUpdateModel form").serialize(), success:function (result){ // alert(result.msg); // 1.关闭对话框 $("#empUpdateModel").modal("hide"); // 2.回到本页面 to_page(currentPage); } }); });// 完成点击全选/全不选功能 $("#check_all").click(function(){ //attr获取checked是undefined //我们这些dom原生的属性;attr获取自定义属性的值 // prop修改和读取dom原生的属性 $(".check_item").prop("checked",$(this).prop("checked")); });// check_item 当手动全选的时候自动全选也要选中 $(document).on("click",".check_item",function (){ //判断当前选中的元素是不是所有元素 //checked匹配所有选中的被选中的元素 var flag=$(".check_item:checked").length==$(".check_item").length $("#check_all").prop("checked",flag) })// 点击全部删除,就批量删除 $("#emp_delete_all_btn").click(function (){ var empNames=""; var del_idstr=""; $.each($(".check_item:checked"),function (){ // this empNames+=$(this).parents("tr").find("td:eq(2)").text()+","; del_idstr+=$(this).parents("tr").find("td:eq(1)").text()+"-"; }); //取出empNames中多余的逗号 empNames=empNames.substring(0,empNames.length-1) del_idstr=del_idstr.substring(0,del_idstr.length-1) if (confirm("确认删除【"+empNames+"】吗?")){ // 发送ajax请求删除 $.ajax({ url:"emp/"+del_idstr, type:"DELETE", success:function (result){ alert(result.msg); //回到当前页面 to_page(currentPage) $("#check_all").prop("checked",false) } }); } });
    </script></body></html>

    3.修改EmpMapper接口

    由于在页面显示时,同时会显示出部门信息,所以可以在接口中添加一个多表查询的功能

    …:表示前面逆向工程自动生成的方法

    package com.wang.ssm.dao;import com.wang.ssm.pojo.Emp;import com.wang.ssm.pojo.EmpExample;import java.util.List;import org.apache.ibatis.annotations.Param;public interface EmpMapper {    ........ //  根据条件查询带部门信息的员工表    List<Emp> selectByExampleWithDept(EmpExample example);//  根据主键查询带部门信息的员工表    Emp selectByPrimaryKeyWithDept(Integer empId); ........}

    4.修改EmpMapper.xml文件

    .........<resultMap id="withDeptBaseResultMap" type="com.wang.ssm.pojo.Emp"> <id column="emp_id" jdbcType="INTEGER" property="empId"/> <result column="emp_name" jdbcType="VARCHAR" property="empName"/> <result column="gender" jdbcType="CHAR" property="gender"/> <result column="email" jdbcType="VARCHAR" property="email"/> <result column="d_id" jdbcType="INTEGER" property="dId"/> <association property="dept" javaType="dept">     <id property="deptId" column="dept_id"></id>     <result property="deptName" column="dept_name"></result> </association></resultMap><!--List selectByExampleWithDept(EmpExample example);-->    <sql id="Withdept_Column_List"> e.emp_id, e.emp_name, e.gender, e.email, e.d_id,d.dept_id,d.dept_name    </sql>    <select id="selectByExampleWithDept" resultMap="withDeptBaseResultMap"> select <if test="distinct">     distinct </if> <include refid="Withdept_Column_List"/> FROM tbl_emp e LEFT JOIN tbl_dept d ON e.d_id=d.dept_id <if test="_parameter != null">     <include refid="Example_Where_Clause"/> </if> <if test="orderByClause != null">     order by ${orderByClause} </if> <if test="orderByClause == null">     ORDER BY emp_id </if>    </select>        <select id="selectByPrimaryKeyWithDept" resultMap="withDeptBaseResultMap"> select <include refid="Withdept_Column_List"/> FROM tbl_emp e LEFT JOIN tbl_dept d ON e.d_id=d.dept_id where emp_id = #{empId,jdbcType=INTEGER}    </select>.........

    5.添加 Msg 类引入链式编程

    以Msg作为Controller层方法的返回值,返回状态码及前端请求的数据,方便前端处理

    / * @author 沐 * @Description:通用的返回类 * @create 2022-03-16 14:14 */public class Msg {//  状态码    private int code;//  提示信息    private String msg;//  用户要返回给浏览器的数据   private Map<String,Object> extend=new HashMap<>();//  成功返回信息    public static Msg success(){ Msg result=new Msg(); result.setCode(100); result.setMsg("处理成功"); return result;    }    //  失败返回信息    public static Msg fail(){ Msg result=new Msg(); result.setCode(200); result.setMsg("处理失败"); return result;    }    public Msg add(String key,Object value){ this.getExtend().put(key,value); return this;    }    public int getCode() { return code;    }    public void setCode(int code) { this.code = code;    }    public String getMsg() { return msg;    }    public void setMsg(String msg) { this.msg = msg;    }    public Map<String, Object> getExtend() { return extend;    }    public void setExtend(Map<String, Object> extend) { this.extend = extend;    }}

    5.编写service层的方法

    @Servicepublic class EmpService {    @Autowired    EmpMapper empMapper;    /     *@author 沐    *@Description:查询所有员工    *@Date 2022/3/15 14:11    *@Param     *@Return     */    public List<Emp> getAll(){ return empMapper.selectByExampleWithDept(null);    }    }

    6.编写Controller层的方法

    @Controllerpublic class EmpController {    @Autowired    EmpService empService;    /     * 导入jackson包     *     * @param pn     * @return     */    @RequestMapping("/emps")    @ResponseBody    public Msg getEmpWithJson(     @RequestParam(value = "pn", defaultValue = "1") Integer pn    ) { //      引入PageHelper分页插件//在查询之前只需要调用,传入页码,以及每页的大小 PageHelper.startPage(pn, 5);//      startPage后面紧跟的这个查询就是一个分页查询 List<Emp> emps = empService.getAll();//      使用pageInfo包装查询后的结果,只需要将pageinfo交给页面就可以了//      pageInfo封装了详细的信息,包括有我们查询出来的数据 navigatePages:导航分页的页码数 PageInfo pageInfo = new PageInfo(emps, 5); return Msg.success().add("pageInfo", pageInfo);    }}

    效果图:

    在这里插入图片描述

    四、新增功能的实现

    1.需要实现的功能

    • 在 index.html 页面点击“新增”弹出对话框

    • 去数据库中查询部门列表,显示在对话框内

    • 对用户输入的数据进行校验

      • jQuery 前端校验格式
      • Ajax 校验用户名是否重复
      • 后端校验(JSR 303)
    • 保存用户数据

    URI 设计

    • /emp/{id}GET 请求,查询员工数据
    • /empPOST 请求,保存员工数据
    • /emp/{empId}PUT 请求,修改员工数据
    • /emp/{id}DELETE 请求,删除员工数据

    2.编写service层的方法

    @Servicepublic class EmpService {    .........    @Autowired    EmpMapper empMapper;    /     *@author 沐    *@Description:查询所有员工    *@Date 2022/3/15 14:11    *@Param     *@Return     */    public List<Emp> getAll(){ return empMapper.selectByExampleWithDept(null);    }    /     * 添加员工     * @param emp     */    public void saveEmp(Emp emp){ empMapper.insertSelective(emp);    }    /     * 检查是否存在empName的员工     * @param empName     * @return     */    public boolean checkEmp(String empName){ EmpExample example = new EmpExample(); example.createCriteria().andEmpNameEqualTo(empName); return empMapper.countByExample(example)==0;    }    /    *@author 沐    *@Description:按照员工id查询员工    *@Date 2022/3/17 15:43    *@Param    *@Return    */    public Emp getEmp(Integer id){ Emp emp = empMapper.selectByPrimaryKey(id); return emp;    }    .........}

    3.编写Controller层的方法

    实现后端校验(JSR 303)

    @Controllerpublic class EmpController {..........    @Autowired    EmpService empService;    /     * 导入jackson包     *     * @param pn     * @return     */    @RequestMapping("/emps")    @ResponseBody    public Msg getEmpWithJson(     @RequestParam(value = "pn", defaultValue = "1") Integer pn    ) { //      引入PageHelper分页插件//在查询之前只需要调用,传入页码,以及每页的大小 PageHelper.startPage(pn, 5);//      startPage后面紧跟的这个查询就是一个分页查询 List<Emp> emps = empService.getAll();//      使用pageInfo包装查询后的结果,只需要将pageinfo交给页面就可以了//      pageInfo封装了详细的信息,包括有我们查询出来的数据 navigatePages:导航分页的页码数 PageInfo pageInfo = new PageInfo(emps, 5); return Msg.success().add("pageInfo", pageInfo);    }    /     * 检查用用户名是否可用     *     * @param empName     * @return true:代表当前姓名可用 false: 代表代表当前姓名不可用     */    @RequestMapping("/checkemp")    @ResponseBody    public Msg checkEmp(@RequestParam("empName") String empName) {//     1.1 先判断用户名是否是合法的表达式 String regx = "(^[a-zA_Z0-9_-]{6,16}$)|(^[\\u2E80-\\u9FFF]{2,5})";//  判断此字符串是否与给定的正则表达式匹配。以str .matches( regex )形式调用此方法会产生与表达式完全相同的结果 if (!empName.matches(regx)) {     return Msg.fail().add("va_msg", "用户名必须是2-5位中文或6-16英文和数字的组合"); }//    1.2    数据库用户名校验 boolean checkEmp = empService.checkEmp(empName); if (checkEmp) {     return Msg.success(); } return Msg.fail().add("va_msg", "用户名已存在");    }    /     * 添加并保存员工请求     * 1.支持JSR303校验     * 2.     *     * @return     */    @RequestMapping(value = "/emp", method = RequestMethod.POST)    @ResponseBody    public Msg saveEmp(@Valid Emp emp, BindingResult result) { //@Valid 标识封装的数据进行正则校验 if (result.hasErrors()) {//     校验失败,在模态框中显示校验失败的错误信息     Map<String,Object> map=new HashMap<>();     List<FieldError> errors = result.getFieldErrors();     for (FieldError fieldError : errors) {  System.out.println("错误的字段名为:"+fieldError.getField());  System.out.println("错误信息:"+fieldError.getDefaultMessage());  map.put(fieldError.getField(),fieldError.getDefaultMessage());     }     return Msg.fail().add("errorFields",map); } empService.saveEmp(emp); return Msg.success();    }    /    *@author 沐    *@Description:根据id查询员工    *@Date 2022/3/17 17:14    *@Param    *@Return    */    @RequestMapping(value = "/emp/{id}",method = RequestMethod.GET)    @ResponseBody    public Msg getEmp(@PathVariable("id") Integer id){ Emp emp = empService.getEmp(id); return Msg.success().add("emp",emp);    }    ........}

    4.index.html界面(部分)

    <div class="modal fade" id="empAddModel">    <div class="modal-dialog"> <div class="modal-content">     <div class="modal-header">  <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">关闭</span></button>  <h4 class="modal-title">员工添加</h4>     </div>     <div class="modal-body">  <form class="form-horizontal">      <div class="form-group">   <label for="empName_add_input" class="col-sm-2">empName</label>   <div class="col-md-6 col-sm-10"><input type="text" name="empName" class="form-control" id="empName_add_input" placeholder="empName"><div class="help-block"></div>   </div>      </div>      <div class="form-group">   <label for="email_add_input" class="col-sm-2">email</label>   <div class="col-md-6 col-sm-10"><input type="text" name="email" class="form-control" id="email_add_input" placeholder="email@999.com"><div class="help-block"></div>   </div>      </div>      <div class="form-group">   <label  class="col-sm-2">gender</label>   <div class="col-md-6 col-sm-10"><label class="radio-inline">    <input type="radio" id="gender1_add_input" name="gender" value="M" checked></label><label class="radio-inline">    <input type="radio" id="gender2_add_input" name="gender" value="F"></label>   </div>      </div>      <div class="form-group">   <label for="dept_add_select" class="col-sm-2">deptName</label>   <div class="col-sm-3"><select class="form-control" name="dId" id="dept_add_select"></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="emp_save_btn">保存</button>     </div> </div>    </div></div>

    效果图:

    在这里插入图片描述

    五、修改数据的实现

    1.需要实现的功能

    • 点击编辑按钮,弹出用户修改的模态框。
    • 模态框可以回显用户的信息。
    • 点击更新,完成修改操作。

    2.编写Service层的方法

    @Servicepublic class EmpService {    ......./     * 更新员工     * @param emp     */    public void updateEmp(Emp emp){ empMapper.updateByPrimaryKeySelective(emp);    }    ....}   

    3.编写Controller层的方法

    @Controllerpublic class EmpController {    ......./    *@author 沐    *@Description:更新并保存员工数据    *@Date 2022/3/17 17:14    *@Param    *@Return    * 如果直接发送ajax=put形式的请求存在问题    *     * 请求体中有数据;但是employee对象封装不上     * 我们要能支持发送PUT之类的请求还要封装请求体中的数据     * 配置上FormContentFilter     * 作用:能够处理PUT和DELETE请求 将请求体中的数据包装成一个map     */    @ResponseBody    @RequestMapping(value = "/emp/{empId}",method = RequestMethod.PUT)    public Msg saveEmp(Emp emp){ empService.updateEmp(emp); return Msg.success();    }    .......}

    4.index.html界面(部分)

    全部index.html界面见上;

    <div class="modal fade" id="empUpdateModel">    <div class="modal-dialog"> <div class="modal-content">     <div class="modal-header">  <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">关闭</span></button>  <h4 class="modal-title">员工修改</h4>     </div>     <div class="modal-body">  <form class="form-horizontal">      <div class="form-group">   <label for="empName_update_static" class="col-sm-2">empName</label>   <div class="col-md-6 col-sm-10"><p type="text" name="empName" class="form-control-static" id="empName_update_static" placeholder="empName"></p><div class="help-block"></div>   </div>      </div>      <div class="form-group">   <label for="email_update_input" class="col-sm-2">email</label>   <div class="col-md-6 col-sm-10"><input type="text" name="email" class="form-control" id="email_update_input" placeholder="email@999.com"><div class="help-block"></div>   </div>      </div>      <div class="form-group">   <label  class="col-sm-2">gender</label>   <div class="col-md-6 col-sm-10"><label class="radio-inline">    <input type="radio" id="gender1_update_input" name="gender" value="M" checked></label><label class="radio-inline">    <input type="radio" id="gender2_update_input" name="gender" value="F"></label>   </div>      </div>      <div class="form-group">   <label for="dept_update_select" class="col-sm-2">deptName</label>   <div class="col-sm-3"><select class="form-control" name="dId" id="dept_update_select"></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="emp_update_btn">更新</button>     </div> </div>    </div></div>

    效果图

    在这里插入图片描述

    六、删除数据的实现

    1.需要实现的功能

    • 单个删除,批量删除二合一,点击某条用户的删除按钮,弹出提示框,点击确定即可删除,也可以点击前面的复选框进行批量删除

      • URI:/emp/{ids}DELETE 请求

    2.编写Service层的方法

    @Servicepublic class EmpService {    ....... /    *@author 沐    *@Description:根据员工id删除员工    *@Date 2022/3/17 19:01    *@Param    *@Return    */    public void deleteEmp(Integer id){ empMapper.deleteByPrimaryKey(id);    }    /    *@author 沐    *@Description:批量删除    *@Date 2022/3/17 21:11    *@Param    *@Return    */    public void deleteBatch(List<Integer> ids){ EmpExample example = new EmpExample(); example.createCriteria().andEmpIdIn(ids); empMapper.deleteByExample(example);    }    ....} 

    3.编写Controller层的方法

     @Controllerpublic class EmpController {    ......./     * 单个批量二合一     * 批量:1-2-3     * 单个:1     * @param ids     * @return     */    @ResponseBody    @RequestMapping(value="/emp/{ids}",method = RequestMethod.DELETE)    public Msg deleteEmpById(@PathVariable("ids")String ids){ if (ids.contains("-")){     List<Integer> del_ids=new ArrayList<>();     String[] str_ids = ids.split("-");//组装id的数组集合     for(String str :str_ids){  del_ids.add(Integer.parseInt(str));     }     empService.deleteBatch(del_ids); }else {     empService.deleteEmp(Integer.parseInt(ids)); } return Msg.success();    }    .......}

    4.index.html界面(部分)

    <script type="text/javascript">    ............//绑定点击删除事件 单个删除    $(document).on("click",".delete_btn",function (){    //    1.弹出是否确认删除对话 var empName= $(this).parents("tr").find("td:eq(2)").text(); var empId = $(this).attr("del-id"); if (confirm("确认删除【"+empName+"】吗?")){ //    点击确认,发送ajax请求删除即可     $.ajax({  url:"emp/"+empId,  type:"DELETE",  success:function (resulet){      alert(resulet.msg);      to_page(currentPage);  }     }); }    });    //    完成点击全选/全不选功能 $("#check_all").click(function(){     //attr获取checked是undefined     //我们这些dom原生的属性;attr获取自定义属性的值     // prop修改和读取dom原生的属性     $(".check_item").prop("checked",$(this).prop("checked")); });//     check_item 当手动全选的时候自动全选也要选中 $(document).on("click",".check_item",function (){     //判断当前选中的元素是不是所有元素     //checked匹配所有选中的被选中的元素    var  flag=$(".check_item:checked").length==$(".check_item").length     $("#check_all").prop("checked",flag) })//     点击全部删除,就批量删除 $("#emp_delete_all_btn").click(function (){     var empNames="";     var del_idstr="";     $.each($(".check_item:checked"),function (){ // this  empNames+=$(this).parents("tr").find("td:eq(2)").text()+",";  del_idstr+=$(this).parents("tr").find("td:eq(1)").text()+"-";     });     //取出empNames中多余的逗号     empNames=empNames.substring(0,empNames.length-1)     del_idstr=del_idstr.substring(0,del_idstr.length-1)     if (confirm("确认删除【"+empNames+"】吗?")){     //    发送ajax请求删除  $.ajax({      url:"emp/"+del_idstr,      type:"DELETE",      success:function (result){   alert(result.msg);   //回到当前页面   to_page(currentPage)   $("#check_all").prop("checked",false)      }  });     } });</script>

    效果图:

    在这里插入图片描述

    项目总结

    在这里插入图片描述