SSM项目------员工管理系统(一)

前言

SSM学了这么长时间了,终于到了整合做项目的时候了,但是没想到实际遇到的问题比当时做JSP+Servlet的时候还要多,虽然都是跟着视频做(摊手),因为遇到的问题太多了,不得不写下这个文档(苦笑),说实话,我真的不想写这个文档,感觉太浪费时间了,但是为了自己以后的开发,更为了加深对这个SSM的印象,我还是写了,希望能有丶帮助吧!

开发环境

JDK1.8+Tomcat8.0+MySQL5.6+Maven

技术点

  • 基础框架-SSM(Spring+SpringMVC+MyBatis)
  • 前端框架-Bootstrap
  • 分页-pagehelper
  • 逆向工程-MyBatis Generator

实现功能

  • 分页
  • 数据校验 jquery前端校验+JSR303后端校验
  • ajax
  • Rest风格的URI;使用HTTP协议请求方式的动词,来表示对资源的操作(GET(查询),POST(新增),PUT(修改),DELETE(删除))

项目地址

GitHub:https://github.com/UnityAlvin/ssmbuild

项目搭建

基础配置

1.新建一个空的Maven项目
2.右键项目名添加Web支持
在这里插入图片描述
3.将web文件夹移动到src/main路径下
4.修改web文件夹的路径配置
在这里插入图片描述

后端底层配置

pom.xml

导入依赖的jar包

<?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.indi</groupId>
	<artifactId>ssmcrud</artifactId>
	<version>1.0-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>

		<!--pagehelper分页插件-->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>5.0.0</version>
		</dependency>

		<!--mysql-->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.44</version>
		</dependency>

		<!--mybatis-->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.4.6</version>
		</dependency>

		<!--mybatis逆向生成dao、xml、bean-->
		<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>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.2</version>
		</dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.5.2</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>2.0.2</version>
		</dependency>
		<!--Spring-->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>5.1.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>5.1.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>5.1.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.9.4</version>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.10</version>
		</dependency>

		<!--jackson插件返回json字符串的支持-->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.9.8</version>
		</dependency>

		<!--JSR303数据校验支持-->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>5.4.1.Final</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<!--指定jdk版本-->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>8</source>
					<target>8</target>
				</configuration>
			</plugin>
		</plugins>

		<resources>
			<resource>
				<directory>src/main/java</directory>
				<includes>
					<include>**/*.properties</include>
					<include>**/*.xml</include>
				</includes>
				<filtering>false</filtering>
			</resource>
			<resource>
				<directory>src/main/resources</directory>
				<includes>
					<include>**/*.properties</include>
					<include>**/*.xml</include>
				</includes>
				<filtering>false</filtering>
			</resource>
		</resources>
	</build>
</project>

database.properties

数据库配置文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456

mybatis-config.xml

<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE configuration
		PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
		"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<settings>
<!--		<setting name="logImpl" value="STDOUT_LOGGING"/>-->
		<setting name="mapUnderscoreToCamelCase" value="true"/>
	</settings>
	<typeAliases>
		<package name="com.indi.pojo"/>
	</typeAliases>


	<plugins>
		<!--配置拦截器插件-->
		<plugin interceptor="com.github.pagehelper.PageInterceptor">
			<!--分页参数合理化,避免出现小于第一页,大于最后一页的情况-->
			<property name="reasonable" value="true"/>
		</plugin>
	</plugins>
</configuration>

spring-service.xml

<?xml version="1.0" encoding="GBK"?>
<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
	   	http://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">

	<!-- 扫描service相关的bean -->
	<context:component-scan base-package="com.indi.service" />

	<!-- 配置事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<!-- 注入数据库连接池 -->
		<property name="dataSource" ref="dataSource" />
	</bean>

	<!-- aop事务支持-->
	<!--配置声明式事务-->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<!--给哪些方法配置事务-->
		<!--
			配置事务的传播特性:
			propagation-REQUIRED为spring的默认事务
		-->
		<tx:attributes>
			<tx:method name="*" propagation="REQUIRED"/>
		</tx:attributes>
	</tx:advice>

	<aop:config>
		<aop:pointcut id="txPointcut" expression="execution(* com.indi.dao.*.*(..))"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
	</aop:config>
</beans>

spring-dao.xml

<?xml version="1.0" encoding="GBK"?>
<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"
	   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">

	<!-- 配置整合mybatis -->
	<!-- 1.关联数据库文件 -->
	<context:property-placeholder location="classpath:database.properties"/>

	<!-- 2.数据库连接池 -->
	<!--数据库连接池
		dbcp 半自动化操作 不能自动连接
		c3p0 自动化操作(自动的加载配置文件 并且设置到对象里面)
	-->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<!-- 配置连接池属性 -->
		<property name="driverClass" value="${jdbc.driver}"/>
		<property name="jdbcUrl" value="${jdbc.url}"/>
		<property name="user" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>

		<!-- c3p0连接池的私有属性 -->
		<property name="maxPoolSize" value="30"/>
		<property name="minPoolSize" value="10"/>
		<!-- 关闭连接后不自动commit -->
		<property name="autoCommitOnClose" value="false"/>
		<!-- 获取连接超时时间 -->
		<property name="checkoutTimeout" value="10000"/>
		<!-- 当获取连接失败重试次数 -->
		<property name="acquireRetryAttempts" value="2"/>
	</bean>

	<!-- 3.配置SqlSessionFactory对象 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- 注入数据库连接池 -->
		<property name="dataSource" ref="dataSource"/>
		<!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
		<property name="configLocation" value="classpath:mybatis-config.xml"/>
		<!-- 如果-->
		<property name="mapperLocations" value="classpath*:/mapper/*.xml"/>
	</bean>

	<!-- 4.配置扫描Dao接口包,动态实现Dao接口注入到spring容器中 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<!-- 注入sqlSessionFactory -->
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
		<!-- 给出需要扫描Dao接口包 -->
		<property name="basePackage" value="com.indi.dao"/>
	</bean>

	<!--配置一个可以批量插入的sqlSession-->
	<bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSession">
		<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
		<constructor-arg name="executorType" value="BATCH"></constructor-arg>
	</bean>
</beans>

spring-mvc.xml

<?xml version="1.0" encoding="GBK"?>
<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
   https://www.springframework.org/schema/mvc/spring-mvc.xsd">

	<!-- 配置SpringMVC -->
	<!-- 1.开启SpringMVC注解驱动,以支持SpringMVC更高级的功能 -->
	<mvc:annotation-driven />
	<!-- 2.将springmvc不能处理的请求交给tomcat,以实现静态动态资源都可以访问-->
	<mvc:default-servlet-handler/>

	<!-- 3.配置jsp 显示ViewResolver视图解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>

	<!-- 4.扫描web相关的bean -->
	<context:component-scan base-package="com.indi.controller" />
</beans>

applicationContext.xml

整合了Spring的三个文件

<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

	<import resource="classpath:spring-dao.xml"/>
	<import resource="classpath:spring-service.xml"/>
	<import resource="classpath:spring-mvc.xml"/>

</beans>

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">
	<!--DispatcherServlet-->
	<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:applicationContext.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>

	<!--过滤器encodingFilter-->
	<filter>
		<filter-name>encodingFilter</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>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!--使用restful风格URI,将页面普通的post请求转为指定的delete或者put请求-->
	<filter>
		<filter-name>HiddenHttpMethodFilter</filter-name>
		<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>HiddenHttpMethodFilter</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>
	<!--Session过期时间-->
	<session-config>
		<session-timeout>15</session-timeout>
	</session-config>


</web-app>

mybatis逆向工程

可以自动生成对应的bean以及mapper文件

pom.xml

		<!--mybatis逆向生成dao、xml、bean-->
		<dependency>
			<groupId>org.mybatis.generator</groupId>
			<artifactId>mybatis-generator-core</artifactId>
			<version>1.3.5</version>
		</dependency>

mbg.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/ssmbuild"
						userId="root"
						password="123456">
		</jdbcConnection>

		<javaTypeResolver>
			<property name="forceBigDecimals" value="false"/>
		</javaTypeResolver>

		<!--指定JavaBean生成的位置-->
		<javaModelGenerator targetPackage="com.indi.pojo" 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接口生成位置-->
		<javaClientGenerator type="XMLMAPPER" targetPackage="com.indi.dao" targetProject=".\src\main\java">
			<property name="enableSubPackages" value="true"/>
		</javaClientGenerator>

		<!--指定每个表的生成策略-->
<!--		<table tableName="t_emp" domainObjectName="Employee"></table>
		<table tableName="t_dept" domainObjectName="Department"></table>-->
		<table tableName="t_user" domainObjectName="User"></table>
	</context>
</generatorConfiguration>

MBGTest.java

package com.indi.test;

/**
 * mybatis生成dao、bean、mapper文件
 */
public class MBGTest {
    public static void main(String[] args) throws Exception {
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        File configFile = new File("mbg.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);
    }
}

修改Mapper文件

这里是因为查询员工信息的同时,还需要查询部门信息,用到了连表查询,所以修改了Mapper文件

EmployeeMapper.xml

  <!--新增Map-->
  <resultMap id="WithDeptResultMap" type="com.indi.pojo.Employee">
    <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="department" javaType="com.indi.pojo.Department">
      <id column="dept_id" property="deptId"/>
      <id column="dept_name" property="deptName"/>
    </association>
  </resultMap>
  
  <!--新增查询部门信息的字段-->
  <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="WithDeptResultMap">
    select
    <if test="distinct">
      distinct
    </if>
    <include refid="WithDept_Column_List"/>
    from t_emp e
    left join t_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 e.emp_id
    </if>
  </select>
  
  <!--按主键查询-->
  <select id="selectByPrimaryKeyWithDept" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select
    <include refid="WithDept_Column_List"/>
    from t_emp e
    left join t_dept d on e.d_id = d.dept_id
    where emp_id = #{empId,jdbcType=INTEGER}
  </select>

简化实体类

Department.java

package com.indi.pojo;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Department {

    private Integer deptId;

    private String deptName;

}

Employee.java

package com.indi.pojo;

@Data
@NoArgsConstructor
public class Employee {

    private Integer empId;

    private String empName;

    private String gender;

    private String email;

    private Integer dId;

    //查询员工的同时查询部门信息
    private Department department;

    public Employee(Integer empId, String empName, String gender, String email, Integer dId) {
        this.empId = empId;
        this.empName = empName;
        this.gender = gender;
        this.email = email;
        this.dId = dId;
    }
}

User.java

package com.indi.pojo;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id;

    private String username;

    private String password;
}

搭建Spring测试环境

使用Spring的测试模块测试数据

pom.xml

		<!--Spring的测试模块-->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>5.1.9.RELEASE</version>
		</dependency>

MapperTest.java

package com.indi.test;

/**
 * 测试dao层
 * 使用Spring的单元测试,可以自动注入需要的组件
 */

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class MapperTest {

    @Autowired
    DepartmentMapper departmentMapper;

    @Autowired
    EmployeeMapper employeeMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    SqlSession sqlSession;

    @Test
    /**
     * 测试添加数据
     */
    public void test() {
        //插入几个部门
//        departmentMapper.insertSelective(new Department(null,"d1部"));
//        departmentMapper.insertSelective(new Department(null,"d2部"));

        //生成员工数据
//        employeeMapper.insertSelective(new Employee(null,"Jerry3","M","Jerry3@qq.com",1));

        //批量插入多个员工
//        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
//        for (int i = 0; i < 10; i++) {
//            String uid = UUID.randomUUID().toString().substring(0, 5) + i;
//            mapper.insertSelective(new Employee(null, uid, "M", uid + "@qq.com", 1));
//        }
//        System.out.println("批量完成");
    }

登录

只有管理员账户可以登录
此处遇到了一点问题,因为我是直接从之前写完的项目往一个新项目里拷贝的,所以出现了一些莫名其妙的报错,后来发现在idea中移动几次位置,或者先创建出同名文件,再把代码复制粘贴上就没问题了。

web目录

在这里插入图片描述

前端

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<jsp:forward page="/login"></jsp:forward>

head.jsp

配置前端需要用的框架、样式、项目路径

<%--
    web路径:
        不以/开始的相对路径,是从当前目录为基准进行查找,经常出问题
        以/开始的路径,则是从服务器的路径为基准开始查找,但是需要加上项目名
--%>
<%
    pageContext.setAttribute("HTTP_PATH", request.getContextPath());
%>

<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">


<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>


<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    pageContext.setAttribute("HTTP_PATH", request.getContextPath());
%>
<html>
<head>
    <title>登录</title>
    <%@include file="common/head.jsp" %>
    <script type="text/javascript">
        if ("${msg}" != "") {
            alert("${msg}")
        }
    </script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="page-header">
            <h1>员工管理系统</h1>
        </div>
    </div>
    <div class="row">
        <form method="post" action="${HTTP_PATH}/goLogin" class="form-horizontal">
            <div class="form-group">
                <label for="exampleInputName3" class="col-sm-2 control-label">用户名</label>
                <div class="col-sm-5">
                    <input type="text" name="username" class="form-control" id="exampleInputName3" placeholder="用户名">
                </div>
            </div>
            <div class="form-group">
                <label for="inputPassword3" class="col-sm-2 control-label">密码</label>
                <div class="col-sm-5">
                    <input type="password" name="password" class="form-control" id="inputPassword3" placeholder="密码">
                </div>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <div class="checkbox">
                        <label>
                            <input type="checkbox"> 记住密码
                        </label>
                    </div>
                </div>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type="submit" class="btn btn-default">登录</button>
                </div>
            </div>
        </form>
    </div>
</div>


</body>
</html>

后端

UserMapper.xml

  <!--新增根据用户名、密码查询账户是否存在-->
  <select id="selectByUsernameAndPassword" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from t_user
    where username=#{username, jdbcType=INTEGER}
    and password=#{password,jdbcType=INTEGER}
  </select>

UserService.java

package com.indi.service;

@Service
public class UserService {

    @Autowired
    UserMapper userMapper;

    public User getUserByUsernameAndPassword(String username, String password) {
        return userMapper.selectByUsernameAndPassword(username, password);
    }
}

UserMapper.java

package com.indi.dao;

public interface UserMapper {

	//新增的查询方法
    User selectByUsernameAndPassword(@Param("username") String username, @Param("password") String password);

}

UserController.java

package com.indi.controller;

@Controller
public class UserController {

    @Autowired
    UserService userService;

    @RequestMapping("/login")
    public String login() {
        return "login";
    }
}

测试分页

使用Spring测试模块的测试请求功能

pom.xml

		<!--pagehelper分页插件-->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>5.0.0</version>
		</dependency>

mybatis-config.xml

放在<typeAliases>标签后面

	<plugins>
		<!--配置拦截器插件-->
		<plugin interceptor="com.github.pagehelper.PageInterceptor">
			<!--分页参数合理化,避免出现小于第一页,大于最后一页的情况-->
			<property name="reasonable" value="true"/>
		</plugin>
	</plugins>

EmployeeMapper.java

package com.indi.dao;

public interface EmployeeMapper {
    //新增
    List<Employee> selectByExampleWithDept(EmployeeExample example);

    //新增
    Employee selectByPrimaryKeyWithDept(Integer empId);
}

EmployeeService.java

package com.indi.service;

@Service
public class EmployeeService {

    /**
     * 查询所有员工
     */
    @Autowired
    EmployeeMapper employeeMapper;

    public List<Employee> getAll() {
        //引入分页插件PageHelper
        return employeeMapper.selectByExampleWithDept(null);
    }
}

EmployeeController.java

package com.indi.controller;

public class EmployeeController {

    @Autowired
    EmployeeService employeeService;

    /**
     * 查询员工数据
     * @return
     */
    @RequestMapping("/emps")
    public String getEmps(@RequestParam(value = "pn", defaultValue = "1") Integer pn, Model model){
        //在查询之前只需要调用此方法,传入页码,以及每页的个数即可
        PageHelper.startPage(pn,5);
        List<Employee> emps = employeeService.getAll();
        //使用pageInfo包装查询后的结果,只需要将pageInfo传回页面即可
        //封装了详细的分页信息,包括查询出来的数据,传入5表示连续显示的页数
        PageInfo page = new PageInfo(emps,5);
        model.addAttribute("pageInfo",page);
        return "list";
    }
}

MvcTest.java

package com.indi.test;

/**
 * 使用Spring测试模块的测试请求功能,测试CRUD请求的正确性
 */
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class MvcTest {

    //传入SpringMVC的ioc
    @Autowired
    WebApplicationContext context;
    //虚拟mvc请求,获取到处理结果
    MockMvc mockMvc;

    @Before
    public void initMockMvc() {
        mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
    }

    @Test
    public void testPage() throws Exception {
        //模拟请求拿到返回值
        MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/emps").param("pn", "5")).andReturn();

        //请求成功之后,请求域中会有pageinfo,可以去除pageinfo进行验证
        MockHttpServletRequest request = result.getRequest();
        PageInfo pi = (PageInfo) request.getAttribute("pageInfo");
        System.out.println(pi);
        System.out.println("当前页码:" + pi.getPageNum());
        System.out.println("总页码:" + pi.getPages());
        System.out.println("总记录数:" + pi.getTotal());
        System.out.println("在页面需要连续显示的页码");
        int[] nums = pi.getNavigatepageNums();
        for (int i : nums) {
            System.out.println(" " + i);
        }

        //获取员工数据
        List<Employee> list = pi.getList();
        for (Employee employee : list) {
            System.out.println("ID" + employee.getEmpId() + "Name" + employee.getEmpName());
        }
    }
}

显示分页数据

前端

list.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: New
  Date: 2020/6/1
  Time: 23:41
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>员工展示</title>
    <%@include file="common/head.jsp" %>
</head>

<body>
<div class="container">

    <%--清除浮动--%>
    <div class="row clearfix">
        <div class="col-md-12 column">
            <div class="page-header">
                <h1>员工列表</h1>
            </div>
        </div>

        <div class="row">
            <div class="col-md-4 column">
                <form action="" method="" class="form-inline">
                    <input type="text" placeholder="请输入要查询的员工名称" class="form-control" name="empName">
                    <button class="btn btn-primary">
                        <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
                        查询
                    </button>
                </form>
            </div>


            <div class="col-md-4 column">
            </div>

            <div class="col-md-4 column" align="right">
                <button class="btn btn-primary">
                    <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
                    新增
                </button>
                <button class="btn btn-danger">
                    <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
                    删除
                </button>
            </div>
        </div>

    </div>

    <div class="row">
        <div class="col-md-12">
            <table class="table table-striped">
                <thead>
                <tr>
                    <th>#</th>
                    <th>员工名称</th>
                    <th>性别</th>
                    <th>邮箱</th>
                    <th>部门</th>
                    <th>操作</th>
                </tr>
                </thead>

                <tbody>
                <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 class="btn btn-primary btn-sm">
                                <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
                                编辑
                            </button>
                            <button class="btn btn-danger btn-sm">
                                <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
                                删除
                            </button>
                        </td>
                    </tr>
                </c:forEach>

                </tbody>
            </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">
                    <%--设置首页、上一页按钮状态--%>
                    <c:if test="${pageInfo.hasPreviousPage}">
                        <li><a href="${HTTP_PATH}/emps?pn=1">首页</a></li>
                        <li>
                            <a href="${HTTP_PATH}/emps?pn=${pageInfo.pageNum-1}" aria-label="Previous">
                                <span aria-hidden="true">&laquo;</span>
                            </a>
                        </li>
                    </c:if>
                    <c:if test="${!pageInfo.hasPreviousPage}">
                        <li class="disabled"><span>首页</span></li>
                        <li class="disabled">
                            <span aria-hidden="true">&laquo;</span>
                        </li>
                    </c:if>

                    <%--设置当前页按钮的状态--%>
                    <c:forEach items="${pageInfo.navigatepageNums}" var="page_Num">
                        <c:if test="${page_Num == pageInfo.pageNum}">
                            <li class="active"><span>${page_Num}</span></li>
                        </c:if>
                        <c:if test="${page_Num != pageInfo.pageNum}">
                            <li><a href="${HTTP_PATH}/emps?pn=${page_Num}">${page_Num}</a></li>
                        </c:if>
                    </c:forEach>

                    <%--设置末页、下一页按钮状态--%>
                    <c:if test="${pageInfo.hasNextPage}">
                        <li>
                            <a href="${HTTP_PATH}/emps?pn=${pageInfo.pageNum + 1}" aria-label="Next">
                                <span aria-hidden="true">&raquo;</span>
                            </a>
                        </li>
                        <li><a href="${HTTP_PATH}/emps?pn=${pageInfo.pages}">末页</a></li>
                    </c:if>
                    <c:if test="${!pageInfo.hasNextPage}">
                        <li class="disabled">
                               <span aria-hidden="true">&raquo;</span>
                        </li>
                        <li class="disabled"><span>末页</span></li>
                    </c:if>
                </ul>
            </nav>
        </div>
    </div>
</div>

</body>
</html>

后端

UserController.java

添加登录之后页面跳转逻辑

package com.indi.controller;

@Controller
public class UserController {
    @RequestMapping("/goLogin")
    public String goLogin(HttpSession session, String username, String password, Model model) {
        User user = userService.getUserByUsernameAndPassword(username, password);
        if (user == null) {
            model.addAttribute("msg","用户名或密码错误");
            return "login";
        } else {
            session.setAttribute("user", user);
            return "redirect:/emps";
        }
    }
}
  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
随着信息化的发展,电子人力资源管理系统(e-hr)成为了企业信息化建设的重要组成部分。本文针对ssm框架(Spring + SpringMVC + MyBatis)下的e-hr管理系统进行了设计与实现。 系统采用了B/S(浏览器/服务器)模式,前端采用HTML、CSS、JavaScript等技术,后端采用Spring框架作为控制反转的容器和AOP(面向切面编程)的框架,SpringMVC框架作为请求的分发器,MyBatis框架作为持久化框架,实现了基于Web的电子人力资源管理。 系统主要功能包括: 1.用户管理:实现新建、删除、修改、查询用户信息的功能。 2.部门管理:实现部门的管理和查询功能。 3.员工管理:实现员工的管理和查询功能。 4.考勤管理:实现考勤记录的管理和查询功能。 5.薪酬管理:实现薪酬计算和统计功能。 6.培训管理:实现培训计划制定和实施情况的查询。 7.绩效管理:实现绩效考核的制定和绩效报告的查询。 在具体实现过程中,我采用了Maven作为项目管理工具,并使用Git作为版本控制工具,保证了项目组合作的高效性。此外,我还在代码编写阶段,注重使用了面向对象的编程思想,提高了代码的可扩展性和可维护性。 综上所述,该e-hr管理系统基于ssm框架,以其良好的组合、普遍的适用性和效率较高的特点,实现了基于Web的电子人力资源管理,为企业管理和人力资源管理提供了便利,同时提高了信息化运营的效率和质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值