用intellij idea 搭建第一个SSM应用

这里写图片描述

起名字

这里写图片描述

添加目录结构

这里写图片描述

更改设置

这里写图片描述

对应各个文件夹

这里写图片描述

接下来导入各种依赖包

搜索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">&laquo;</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">&raquo;</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">&times;</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">&times;</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("&laquo;"));
                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("&raquo;"));
                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>

最终的小项目结构图如下:

这里写图片描述

这里写图片描述

猜你喜欢

转载自blog.csdn.net/weixin_37540865/article/details/80498330