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

入离职管理系统,是我入职这个公司开发的第一个完全参与的项目,现在拿出来做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>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值