入离职管理系统——类的抽取和注册登录功能

来源:互联网 发布:登录注册js特效 编辑:程序博客网 时间:2024/06/11 23:49

入离职管理系统,是我入职这个公司开发的第一个完全参与的项目,现在拿出来做Java的练习。入离职管理系统的功能如下:

  1. 管理员账号注册和登录;
  2. 录入新员工信息;
  3. 员工入职流程(简化流程,只设置一级审批);
  4. 员工离职流程(简化流程,只设置一级审批);
  5. 员工入职流程审批通过后,自动创建系统登录账号;
  6. 员工离职流程审批通过后,自动删除系统登录账号;
  7. 展示员工信息表(管理员可见所有员工的信息,普通员工只能看到自己的信息 )。

在搭建完开发环境后,开始着手做第一个功能:管理员账号的注册和登录。在做的过程中,发现dao层、action层的类可以进行抽取,减少冗余代码。

一、抽取Dao层

Dao层的作用是对数据库表进行操作,不涉及任何业务逻辑,而对数据库的操作最基本的是增、删、改、查,那么这部分功能可以抽取出来,因为每一个dao类都需要对数据库进行操作。另外,进行数据库的操作需要获取SessionFactory对象,所以最终抽取的内容为SessionFactory对象和数据库的增删改查方法。抽取后的BasicDao如下:

package com.entry_exit.dao.impl;import java.lang.reflect.ParameterizedType;import java.util.List;import org.hibernate.Session;import org.hibernate.SessionFactory;import com.entry_exit.dao.BasicDao;public class BasicDaoImpl<T> implements BasicDao<T> {    private Class clazz; //clazz中存储了当前操作的类型,即泛型T      private SessionFactory sessionFactory;    public BasicDaoImpl(){        System.out.println("this代表的是当前调用构造方法的对象" + this);          System.out.println("获取当前this对象的父类信息" + this.getClass().getSuperclass());          System.out.println("获取当前this对象的父类信息(包括泛型信息)" + this.getClass().getGenericSuperclass());        ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();        clazz = (Class) type.getActualTypeArguments()[0];        System.out.println(clazz);        System.out.println(clazz.getSimpleName());    }    public void setSessionFactory(SessionFactory sessionFactory) {          this.sessionFactory = sessionFactory;      }      protected Session getSession() {          //从当前线程获取session,如果没有则创建一个新的session          return sessionFactory.getCurrentSession();     }    @Override    public void save(T t) {        // TODO Auto-generated method stub        getSession().save(t);    }    @Override    public void update(T t) {        // TODO Auto-generated method stub        getSession().update(t);    }    @Override    public void delete(int id) {        // TODO Auto-generated method stub        String hql = "delete " + clazz.getSimpleName() + " as c where c.id=:id";        getSession().createQuery(hql).setInteger("id", id).executeUpdate();    }    @Override    public T get(int id) {        // TODO Auto-generated method stub        return (T) getSession().get(clazz, id);    }    @Override    public List<T> query(int page, int rows) {        // TODO Auto-generated method stub        String hql = "from " + clazz.getSimpleName();          return getSession().createQuery(hql).setFirstResult((page-1)*rows).setMaxResults(rows).list();    }}

具体的Dao类继承BasicDao类即可,修改后的UserDaoImpl类得到了简化,如下:

package com.entry_exit.dao.impl;import java.util.Iterator;import java.util.List;import org.hibernate.Session;import org.hibernate.SessionFactory;import com.entry_exit.dao.UserDao;import com.entry_exit.vo.UserVo;public class UserDaoImpl extends BasicDaoImpl<UserVo> implements UserDao {    @Override    public void delete(String accountid) {        // TODO Auto-generated method stub        String hql = "delete UserVo u where u.accountid = :accountid";        getSession().createQuery(hql).setString("accountid", accountid).executeUpdate();    }    @Override    public UserVo get(String accountid, String password) {        // TODO Auto-generated method stub        UserVo user = null;        String hql = "from UserVo where accountid = :accountid and password = :password";        user = (UserVo) getSession().createQuery(hql).setString("accountid", accountid).setString("password", password).uniqueResult();        return user;    }}

上面的UserDaoImpl类中的方法是在BasicDaoImpl类中没有的方法,是需要实现业务逻辑而专门写的方法。其中,delete(String accountid)方法在注销账号时调用;get(String accountid, String password)方法在登录账号时调用。

二、Service层

Service层主要用于处理具体业务逻辑,而业务逻辑各不相同,基本没有抽取基本类的可能,这里列出登录和注册的方法代码:

package com.entry_exit.service.impl;import com.entry_exit.dao.UserDao;import com.entry_exit.service.UserService;import com.entry_exit.vo.UserVo;public class UserServiceImpl implements UserService {    private UserDao userDao;    public void setUserDao(UserDao userDao) {        this.userDao = userDao;    }    @Override    public void register(UserVo user) {        // TODO Auto-generated method stub        if(user != null){            userDao.save(user);        }    }    @Override    public UserVo login(String accountid, String password) {        // TODO Auto-generated method stub        if(accountid != null && password != null){            return userDao.get(accountid, password);        }        return null;    }}

抽取Action层

Action层用于和页面进行交互,根据页面的请求调用Service层的服务,并将服务返回的结果返回给页面。直接上代码:

package com.entry_exit.action;import java.lang.reflect.ParameterizedType;import java.util.Map;import org.apache.struts2.interceptor.ApplicationAware;import org.apache.struts2.interceptor.RequestAware;import org.apache.struts2.interceptor.SessionAware;import com.opensymphony.xwork2.ActionSupport;import com.opensymphony.xwork2.ModelDriven;public class BasicAction<T> extends ActionSupport implements SessionAware, ApplicationAware, RequestAware, ModelDriven<T> {    //域对象      protected Map<String, Object> request;      protected Map<String, Object> session;      protected Map<String, Object> application;    @Override    public void setRequest(Map<String, Object> request) {        // TODO Auto-generated method stub        this.request = request;    }    @Override    public void setApplication(Map<String, Object> application) {        // TODO Auto-generated method stub        this.application = application;    }    @Override    public void setSession(Map<String, Object> session) {        // TODO Auto-generated method stub        this.session = session;    }    protected T model;    @Override    public T getModel() {        // TODO Auto-generated method stub        ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();          Class clazz = (Class)type.getActualTypeArguments()[0];          try {              model = (T)clazz.newInstance();          } catch (Exception e) {              throw new RuntimeException(e);          }             return model;      }}

可以看到,BasicAction实现了四个接口,分别是SessionAware、 ApplicationAware、RequestAware、ModelDriven。其中,实现SessionAware、 ApplicationAware、RequestAware这三个接口,是为了方便将Service层服务穿回来的值返回到页面相应的域中;实现ModelDriven接口是为了方便的获取页面属性,并set进相应的实体类中。关于ModelDriven接口的知识,可以参考博文Struts2中的ModelDriven机制及其运用 。

四、注意事项

注意事项集中在配置文件中。

1、在抽取Dao层时,BasicDaoImpl是泛型类,所以不能在启动tomcat时直接注入,需要加入lazy-init=”true”属性,如下:

<!-- 因为basicDao是泛型类,所以必须加上lazy-init="true"属性 -->     <bean id="basicDao" class="com.entry_exit.dao.impl.BasicDaoImpl" lazy-init="true">        <property name="sessionFactory" ref="sessionFactory"></property>     </bean>

2、其余的Dao类需要指定parent属性,如下:

<bean id="userDao" class="com.entry_exit.dao.impl.UserDaoImpl" parent="basicDao"></bean>

3、在配置action类的bean时,需要加上scope=”prototype”属性,无论是BasicAction还是其他的Action,都需要加上这个属性,如下:

<!-- 装配action类的bean -->     <bean id="basicAction" class="com.entry_exit.action.BasicAction" scope="prototype">     </bean>     <bean name="userAction" class="com.entry_exit.action.UserAction" parent="basicAction" scope="prototype">        <property name="userService" ref="userService"></property>     </bean>

这样做的原因,是为了确保每一次请求都是一个新的action对象,解决了实现ModelDriven接口后造成的问题,详见博文sping+struts2中配置Action的bean中scope=”prototype”的作用。

4、因为实现了ModelDriven接口,struts.xml文件和jsp页面也变得简洁了很多。
(1)struts.xml文件:action的name属性和method属性需要修改如下

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC      "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"      "http://struts.apache.org/dtds/struts-2.3.dtd">  <struts>      <package name="default" extends="struts-default">          <action name="user_*" class="userAction" method="{1}">            <result name="home" type="redirect">/home.jsp</result>            <result name="login" type="redirect">/login.jsp</result>        </action>    </package>  </struts> 

(2)jsp页面变得简单了,以注册页面为例,name属性的值与vo类的属性名一致即可,不需写成UserVo.accountid这样的形式:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body>    <form action="user_register.action" method="post">        <div>            <table>                <tr>                    <td>Accountid:</td>                    <td><input type="text" name="accountid"></td>                </tr>                <tr>                    <td>Password:</td>                    <td><input type="password" name="password"></td>                </tr>                <tr>                    <td>FullName:</td>                    <td><input type="text" name="fullname"></td>                </tr>                <tr>                    <td>Role</td>                    <td>                        <select>                            <option value="fme" selected="selected">FME</option>                            <option value="manager">Manager</option>                        </select>                    </td>                </tr>            </table>            <input type="submit" value="Submit">        </div>    </form></body></html>
阅读全文
0 0
原创粉丝点击