【SSH测试整合Demo】企业人事管理系统

前言

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

需求:

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

功能分类:

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

数据库设计

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

搭建配置环境

关于搭建配置环境可参考上一篇博文:http://blog.csdn.net/hon_3y/article/details/72190638

编写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??可以参考我这篇博文:http://blog.csdn.net/hon_3y/article/details/70243918

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) 添加一个员工, 指定添加的部门
  • 2) 对指定的员工信息修改
  • 3) 删除选择员工
  • 4) 列表展示

列表展示

  • 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获取得到数据,然后通过域对象(值栈对象)把数据存储起来,在页面上做展示。

原文发布于微信公众号 - Java3y(gh_085b56c42174)

原文发表时间:2018-03-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏XAI

企业支付宝账号开发接口教程--JAVA-UTF-8(实际操作------SpringMVC+JSP)

关于即时到账的开发。审核通过。简单测试如下。 希望看的可以收藏或者赞一下哦。 1:拥有自己的支付宝企业账号。去产品商店选择适合自己的方案。并签约合同。 ? 2:...

1.4K90
来自专栏deepcc

linux中nodejs后台运行工具forever

32880
来自专栏GopherCoder

『No19: Gorm 上手指南』

如果你是做后端开发的,日常工作中,除了熟悉编程语言之外,数据库怕是最常用的技术了吧。

76410
来自专栏Java3y

Hibernate【映射】知识要点

前言 前面的我们使用的是一个表的操作,但我们实际的开发中不可能只使用一个表的…因此,本博文主要讲解关联映射 集合映射 需求分析:当用户购买商品,用户可能有多个地...

32170
来自专栏小樱的经验随笔

自己手动复现一个熊猫烧香病毒

最近逛了一下 bilibili ,偶然的一次机会,我在 bilibili 上看到了某个 up 主分享了一个他自己仿照熊猫病毒的原型制作的一个病毒的演示视频,虽然...

81320
来自专栏Java与Android技术栈

Android App安全防范措施的小结

关闭打印的日志,防止日志中的调试信息被看到。如果在网络框架中使用了日志,那就更加需要关闭了。

12020
来自专栏一个番茄说

Swift中防止ptrace依附

在移动开发中,安全是一个很重要的话题,当然安全是没有绝对的,只能说尽可能的提高安全性。在iOS的开发中,为了防止别人窥视我们的App,我们得采用一些手段来进行防...

13330
来自专栏坚毅的PHP

PHP码农在Golang压力下的生存之道-PHP性能优化实践

随着国内Golang的火爆,phper的生存压力越来越大,在一次内部技术讨论中,gopher甚至提出,要什么php,写php的全部开掉,唉,码农何苦为难码农。 ...

1.2K80
来自专栏noteless

springmvc 项目完整示例02 项目创建-eclipse创建动态web项目 配置文件 junit单元测试

spring原理案例-基本项目搭建 01 spring framework 下载 官网下载spring jar包

19620
来自专栏数据之美

修改 mysql/oracle/bash/vimrc/cmd 提示符格式与颜色

(1)修改mysql提示符: MySQL 客户端的默认提示符是 "mysql>",基本上没什么实际作用。其实可以修改这个提示符,让它显示一些有用的信息,例如当前...

276100

扫码关注云+社区

领取腾讯云代金券