企业人事管理系统

550 阅读12分钟

tags: SSH整合与阅读项目


前言

前面我们已经学习了怎么整合SSH框架了。是时候拿一个小项目来练练手了....我们现在要设计一个企业人事管理系统...

需求:

  • **要求对员工信息进行维护; **
  • 后台系统先登陆,才能操作员工: 添加/修改/删除
  • 没有登陆,只能查看列表,不能操作!

功能分类:

  • 【管理员模块】
    • 注册/登陆
  • 【员工模块】
      1. 添加一个员工, 指定添加的部门
      1. 对指定的员工信息修改
      1. 删除选择员工
      1. 列表展示

数据库设计

  • 管理员表: t_admin
  • 员工表: t_user
  • 部门: t_dept

搭建配置环境

关于搭建配置环境可参考上一篇博文:blog.csdn.net/hon_3y/arti…

编写JavaBean 和映射文件#

JavaBean编写##

Admin.java


public class Admin {

    private int id;
    private String username;
    private String password;


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

User.java


public class User {

    private int id;
    private String username;
    private Dept dept;


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }
}

Dept.java


public class Dept {

    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

映射文件##

Dept.hbm.xml


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="zhongfucheng.entity">

	<class name="Dept" table="t_dept">
		<id name="id" >
			<generator class="native"></generator>
		</id>
		<property name="name" column="name"></property>
	</class>

</hibernate-mapping>


User.hbm.xml


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="zhongfucheng.entity">

	<class name="User" table="t_user">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<property name="username" column="userName"></property>

		<many-to-one name="dept" class="Dept" column="dept_id"/>
	</class>

</hibernate-mapping>


Admin.hbm.xml


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="zhongfucheng.entity">

	<class name="Admin" table="t_admin">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<property name="username" column="userName"></property>
		<property name="password" column="password"></property>
	</class>

</hibernate-mapping>


编写Dao

编写BaseDao

为什么要写baseDao??可以参考我这篇博文:blog.csdn.net/hon_3y/arti…


package zhongfucheng.dao;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * Created by ozc on 2017/5/16.
 */
public abstract class BaseDao<T> {

    // 容器注入sessionFactory
    @Autowired
    private SessionFactory sessionFactory;

    //子类的类型
    private Class<T> clazz;
    
    //子类的名称
    private String clazzName;
    
    public BaseDao(){
        clazz = (Class<T>) this.getClass();  //拿到的是子类
        ParameterizedType pt = (ParameterizedType) clazz.getGenericSuperclass();

        //拿到子类的真实类型
        clazz = (Class) pt.getActualTypeArguments()[0];
        //拿到子类的名称【HQL都是通过类名来查询的】
        clazzName = clazz.getSimpleName();
    }
    public void add(T t){
        sessionFactory.getCurrentSession().save(t);
    }

    public T find(String id){
        return (T) sessionFactory.getCurrentSession().get(clazz, id);
    }

    public void update(T t){
        sessionFactory.getCurrentSession().update(t);
    }

    public void delete(String id){
        T t = (T) sessionFactory.getCurrentSession().get(clazz, id);
        sessionFactory.getCurrentSession().delete(t);
    }

    public List<T> getAll() {
        return sessionFactory.getCurrentSession().createQuery("from" + clazzName).list();
    }
}

编写UserDao

此时的UserDao已经有了baseDao的所有功能


/**
 * 1.添加员工--->add()
 * 2.修改员工--->find()
 * 3.删除员工--->delete()
 * 4.得到所有员工-->getAll()
 * 5.根据id得到员工-->find()
 * */
@Repository
public class UserDao extends BaseDao<User>{

}

编写AdminDao


/**
 *
 * 1.保存管理员【注册】--->add()
 * 2.查找管理员【登陆】--->login()
 *
 *
 * */

@Repository
public class AdminDao extends BaseDao<Admin> {

    @Autowired
    private SessionFactory sessionFactory;

    public Admin login(Admin admin) {
        return (Admin) sessionFactory.
                getCurrentSession().
                createQuery("FROM Admin WHERE username=? AND password=?")
                .setParameter(0, admin.getUsername())
                .setParameter(1, admin.getPassword())
                .uniqueResult();
    }

}


编写DeptDao


import org.springframework.stereotype.Repository;
import zhongfucheng.entity.Dept;

/**
 * 1.查找所有的部门【在添加员工、修改员工时需要用】-->getAll()
 * 2.通过id查找所在的部门信息--->find()
 *
 * */

@Repository
public class DeptDao extends BaseDao<Dept> {


}


编写Service

UserService

@Transactional
@Service
public class UserService {

    @Autowired
    private UserDao userDao;


    /**
     * 1.添加员工--->add()
     * 2.修改员工--->find()
     * 3.删除员工--->delete()
     * 4.得到所有员工-->getAll()
     * 5.根据id得到员工-->find()
     */
    public void addUser(User user) {
        userDao.add(user);
    }

    public void updateUser(User user) {
        userDao.update(user);
    }

    public void deleteUser(String id) {
        userDao.delete(id);
    }

    public List<User> getAllUsers() {
        return userDao.getAll();
    }

    public User findUserById(String id) {
        return userDao.find(id);
    }
    
}

编写AdminService


@Transactional
@Service
public class AdminService {


    @Autowired
    private AdminDao adminDao;

    /**
     * 1.保存管理员【注册】--->save()
     * 2.查找管理员【登陆】--->login()
     */
    public void register(Admin admin) {

        adminDao.add(admin);
    }
    public Admin login(Admin admin) {

        return adminDao.login(admin);
    }
}	

编写DeptService


@Transactional
@Service
public class DeptService {


    @Autowired
    private DeptDao deptDao;

    /**
     * 1.查找所有的部门【在添加员工、修改员工时需要用】-->getAll()
     * 2.通过id查找所在的部门信息--->find()
     */
    public List<Dept> getAllDept() {
        return deptDao.getAll();
    }

    public Dept findDeptById(String id) {
        return deptDao.find(id);
    }
}

员工模块

到目前为止,我们已经把后台的逻辑已经写完了,接下来就是写Action和前台的页面数据了。首先来写员工模块吧。

    1. 添加一个员工, 指定添加的部门
    1. 对指定的员工信息修改
    1. 删除选择员工
    1. 列表展示

列表展示

  • UserAction

package zhongfucheng.action;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.interceptor.RequestAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import zhongfucheng.entity.User;
import zhongfucheng.service.UserService;

import java.util.List;
import java.util.Map;

/**
 * Created by ozc on 2017/5/15.
 */

@Controller
@Scope("prototype")

public class UserAction extends ActionSupport implements RequestAware{

    @Autowired
    private UserService userService;

    //因为多处用到request对象,那就直接实现接口,来得到request对象就行了
    private Map<String, Object> request;
    @Override
    public void setRequest(Map<String, Object> map) {
        this.request = map;
    }

    /*列表展示*/
    public String list() {

        List<User> list = userService.getAllUsers();

        System.out.println(list);
        //把数据封装到request对象上
        request.put("list", list);

        return "list";
    }


}

Struts配置文件


        <action name="user_*" class="userAction" method="{1}">

            <!--列表展示-->
            <result name="list">/list.jsp</result>
        </action>

list.jsp页面


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>列表展示</title>
</head>
<body>
<s:if test="#request.list != null">
    <table align="center" border="1">
        <tr>
            <td>员工编号</td>
            <td>员工姓名</td>
            <td>员工部门编号</td>
            <td>操作</td>
        </tr>

        <s:iterator var="user" value="#request.list" status="st">
            <tr>
                <td><s:property value="#user.id"/></td>
                <td><s:property value="#user.username"/></td>
                <td><s:property value="#user.dept.id"/> </td>
                <td><s:a href="#"> 修改,删除</s:a></td>
            </tr>
        </s:iterator>
    </table>
</s:if>

<s:else>对不起,还没有员工的信息,请录入</s:else>
</body>
</html>

效果:

这里写图片描述


添加员工

添加员工,指定添加部门,跳转到添加员工显示页面...


    @Autowired
    private DeptService deptService;

    /*添加员工...给出添加的JSP页面*/
    public String viewAdd() {

        //在添加员工的时候需要得到所有的部门信息
        List<Dept> deptList = deptService.getAllDept();

        //封装到request域对象中
        request.put("deptList", deptList);

        return "viewAdd";
    }

            <!--给出添加员工的界面-->
            <result name="viewAdd">/viewAdd.jsp</result>

显示添加员工界面:


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="s" uri="/struts-tags" %>

<html>
<head>
    <title>添加员工界面</title>
</head>
<body>

<s:form method="POST" action="user_addUser.action" theme="simple">

    <table align="center" border="1">
        <tr>
            <td>员工名称</td>
            <td><s:textfield name="username" id="username" value=""/></td>
        </tr>

        <tr>
            <td>员工部门</td>
            <!--
        Struts下拉列表标签:
            name="deptId"  下拉列表标签的名称(服务器根据这个名称获取选择的项的实际的值value值)
            headerKey   默认选择项的实际的值
            headerValue  默认下拉列表显示的内容
            list      下拉列表显示数据的集合
            listKey    集合对象的哪个属性作为下拉列表的实例的值,即value值
            listValue  集合对象的哪个属性作为下拉列表显示的值
            value      默认选择的项的设置
        -->
            <td><s:select list="#request.deptList" headerKey="-1" headerValue="请选择" listKey="id" listValue="name" name="deptId"/></td>
        </tr>
        <tr>
            <td colspan="2"><s:submit value="添加员工"/></td>
        </tr>
    </table>
</s:form>


</body>
</html>
  • 在Action中使用模型驱动和数据自动封装来获取JSP页面带过来的数据:

    //模型驱动
    User user = new User();
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    @Override
    public Object getModel() {
        return user;
    }

    //自动封装deptId
    private int deptId;
    public int getDeptId() {
        return deptId;
    }
    public void setDeptId(int deptId) {
        this.deptId = deptId;
    }
  • 找到要添加员工的部门,设置员工与部门的关系。添加到数据库中:

    /*添加员工*/
    public String addUser() {
        //根据部门id查找部门对象
        Dept dept = deptService.findDeptById(deptId);
        //设置部门与员工的关系
        user.setDept(dept);

        userService.addUser(user);
        //返回列表展示
        return "listPage";
    }
  • 返回到列表展示页面

            <!--返回列表展示页面-->
            <result name="listPage" type="redirectAction">user_list</result>
  • 效果:

这里写图片描述


修改员工

  • 修改与删除的超链接:指明要修改用户的id【不然服务器哪知道你点击了哪一个用户】
                <td>
                    <s:a href="user_viewUpdate?id=%{#user.id}">修改</s:a>
                    <s:a href="user_delete?id=%{#user.id}"> 删除</s:a>
                </td>

这里写图片描述

  • 提供修改界面【其实就是回显数据】

    /*为修改提供页面,其实就是回显数据*/
    public String viewUpdate() {

        //得到user
        User user = userService.findUserById(this.user.getId());
        //得到所有的部门
        List<Dept> deptList = deptService.getAllDept();
        request.put("deptList", deptList);

        //使用Struts2的回显技术
        ValueStack valueStack = ActionContext.getContext().getValueStack();
        valueStack.pop();
        valueStack.push(user);
        return "viewUpdate";
    }


            <!--提供修改页面-->
            <result name="viewUpdate">/viewUpdate.jsp</result>
  • 修改页面JSP

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="s" uri="/struts-tags" %>

<html>
<head>
    <title>修改员工界面</title>
</head>
<body>

<s:form method="POST" action="user_updateUser.action" theme="simple">

    <table align="center" border="1">

        <%--这里要把id通过隐藏域带过去--%>
        <s:hidden name="id" id="id" value="%{id}"/>
        <tr>
            <td>员工名称</td>
            <td><s:textfield name="username" id="username"/></td>
        </tr>

        <tr>
            <td>员工部门</td>
            <td>
                <s:select name="deptId"
                          list="#request.deptList"
                          listKey="id"
                          listValue="name"
                          value="dept.id"/>
            </td>
        </tr>
        <tr>
            <td colspan="2"><s:submit value="修改员工"/></td>
        </tr>
    </table>
</s:form>

</body>
</html>
  • 因为使用了模型驱动,那么Action会把JSP带过来的数据直接封装到user对象中,我们直接使用即可

    /*确认修改员工,模型驱动会把数据直接封装到user对象中*/
    public String updateUser() {
        //得到部门
        Dept dept = deptService.findDeptById(deptId);

        //设置员工与部门的关系
        user.setDept(dept);

        userService.updateUser(user);

        //修改完,返回展示列表
        return "listPage";
    }
  • 效果:

这里写图片描述


删除员工


    /*删除员工*/
    public String delete() {

        userService.deleteUser(user.getId());

        //修改完,返回展示列表
        return "listPage";
    }

  • 测试:

这里写图片描述


管理员模块

  • 注册
  • 登陆

注册

  • 提供注册的超链接
<s:a href="register.jsp">注册</s:a>
  • Admin.action

package zhongfucheng.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import zhongfucheng.entity.Admin;
import zhongfucheng.service.AdminService;

/**
 * Created by ozc on 2017/5/15.
 */

@Controller
@Scope("prototype")

public class AdminAction extends ActionSupport implements ModelDriven<Admin>{


    /**********调用service**************/
    @Autowired
    private AdminService adminService;


    /**************使用模型驱动******************/
    Admin admin = new Admin();
    public Admin getAdmin() {
        return admin;
    }
    public void setAdmin(Admin admin) {
        this.admin = admin;
    }
    @Override
    public Admin getModel() {
        return admin;
    }

}

  • 配置信息

        <!--############管理员模块#################-->
        <action name="admin_*" class="adminAction" method="{1}">

        </action>
  • JSP页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册界面</title>
</head>
<body>

<s:form action="admin_register" method="POST" theme="simple">
    <table border="1" align="center">
        <tr>
            <td>管理员账号:</td>
            <td><s:textfield name="username"/></td>
        </tr>
        <tr>
            <td>管理员密码:</td>
            <td><s:textfield name="password"/></td>
        </tr>

        <tr>
            <td colspan="2"><s:submit value="注册"/> </td>
        </tr>
    </table>
</s:form>

</body>
</html>
  • Action实现

    /*得到JSP页面带过来的数据、完成注册*/
    public String register() {

        adminService.register(admin);

        return "listPage";
    }

  • 效果:

这里写图片描述


登陆功能

  • 提供登陆的超链接

<s:a href="login.jsp">登陆</s:a>
  • 登陆的JSP页面

<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登陆界面</title>
</head>
<body>

<s:form action="admin_login" method="POST" theme="simple">
    <table border="1" align="center">
        <tr>
            <td>管理员账号:</td>
            <td><s:textfield name="username" value=""/></td>
        </tr>
        <tr>
            <td>管理员密码:</td>
            <td><s:textfield name="password" value=""/></td>
        </tr>

        <tr>
            <td colspan="2"><s:submit value="登陆"/> </td>
        </tr>
    </table>
</s:form>

</body>
</html>

  • Action中处理登陆


    /*完成登陆*/
    public String login() {

        adminService.login(admin);
        //把用户保存在Sessiion中
        ActionContext.getContext().getSession().put("admin", admin);
        return "listPage";
    }


  • 在list页面给出相对应的提示,如果登陆了就给出欢迎的显示

<s:if test="#session.admin !=null">
    欢迎您:<s:property value="%{#session.admin.username}"/>
</s:if>

  • 效果:

这里写图片描述


权限操作

  • 后台系统先登陆,才能操作员工: 添加/修改/删除
  • 没有登陆,只能查看列表,不能操作!

我们写一个拦截器,判断是否调用登陆或者列表展示的方法,如果不是就查看该用户有没有登陆。没有登陆就跳转到登陆界面


package zhongfucheng.action;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

/**
 * Created by ozc on 2017/5/17.
 */
public class PrivilegeInterceptor extends AbstractInterceptor {

    @Override
    public String intercept(ActionInvocation actionInvocation) throws Exception {

        //得到ActionContext
        ActionContext context = actionInvocation.getInvocationContext();

        //得到正在调用Action的方法名
        String methodName = actionInvocation.getProxy().getMethod();

        //获取session中管理员的对象
        Object o = context.getSession().get("admin");

        //判断正在调用什么方法
        if ("login".equals(methodName) || "list".equals(methodName)) {

            //调用了这两个方法,不用权限,直接调用把
            return actionInvocation.invoke();
        } else {
            //如果不是,那么检查

            // 没有登陆,就跳转到登陆界面呗
            if (o == null) {
                return "login";
            } else {
                // 有登陆,那么就可以执行呗
                return actionInvocation.invoke();
            }
        }
    }
}

  • 在Struts2配置文件中配置拦截器

		<!-- 拦截器配置 -->
		<interceptors>
			<interceptor name="userInterceptor" class="cn.itcast.action.UserInterceptor"></interceptor>
			<interceptor-stack name="myStack">
				<interceptor-ref name="defaultStack"></interceptor-ref>
				<interceptor-ref name="userInterceptor"></interceptor-ref>
			</interceptor-stack>
		</interceptors>
		<!-- 执行指定的拦截器 -->
		<default-interceptor-ref name="myStack"></default-interceptor-ref>
	
  • 拦截器返回的login需要配置全局视图

        <global-results>
            <!--回到展示列表页面-->
            <result name="listPage" type="redirectAction">user_list</result>


            <!--拦截器返回login-->
            <result name="login" type="redirect">/login.jsp</result>
        </global-results>
  • 效果:

这里写图片描述

总结

本篇主要使用SSH框架来开发一个比较简易的CRUD项目。让我们熟悉SSH框架开发的流程。

  • 设计实体
  • 编写每个实体的映射文件
  • 把映射文件加载到Hibernate中管理起来
  • 使用BaseDao来管理全部的Dao,使得每个Dao都有Curd的方法。这样就不用我们在每个Dao都写上Crud了
  • 如果普通的CURD方法满足不了我们,就可以在特定的Dao中写上自己想要的功能
  • Service层调用Dao层的方法
  • Controller调用Service层的方法实现功能,如果页面上需要后天的数据的话,那么我们先调用service获取得到数据,然后通过域对象(值栈对象)把数据存储起来,在页面上做展示。

如果您觉得这篇文章帮助到了您,可以给作者一点鼓励