入离职管理系统,是我入职这个公司开发的第一个完全参与的项目,现在拿出来做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(); }@Overridepublic void save(T t) {// TODO Auto-generated method stubgetSession().save(t);}@Overridepublic void update(T t) {// TODO Auto-generated method stubgetSession().update(t);}@Overridepublic void delete(int id) {// TODO Auto-generated method stubString hql = "delete " + clazz.getSimpleName() + " as c where c.id=:id";getSession().createQuery(hql).setInteger("id", id).executeUpdate();}@Overridepublic T get(int id) {// TODO Auto-generated method stubreturn (T) getSession().get(clazz, id);}@Overridepublic List<T> query(int page, int rows) {// TODO Auto-generated method stubString 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 {@Overridepublic void delete(String accountid) {// TODO Auto-generated method stubString hql = "delete UserVo u where u.accountid = :accountid";getSession().createQuery(hql).setString("accountid", accountid).executeUpdate();}@Overridepublic UserVo get(String accountid, String password) {// TODO Auto-generated method stubUserVo 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;}@Overridepublic void register(UserVo user) {// TODO Auto-generated method stubif(user != null){userDao.save(user);}}@Overridepublic UserVo login(String accountid, String password) {// TODO Auto-generated method stubif(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;@Overridepublic void setRequest(Map<String, Object> request) {// TODO Auto-generated method stubthis.request = request;}@Overridepublic void setApplication(Map<String, Object> application) {// TODO Auto-generated method stubthis.application = application;}@Overridepublic void setSession(Map<String, Object> session) {// TODO Auto-generated method stubthis.session = session;}protected T model;@Overridepublic T getModel() {// TODO Auto-generated method stubParameterizedType 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. java基础5:工厂模式、单例模式、File文件类、递归、IO流、Properties配置文件、网络编程、利用IO流模拟注册登录功能、关于反射、JDK动态代理

    1.工厂模式 23种java设计模式之一 1)提供抽象类(基类) 2)提供一些子类,完成方法重写 3)提供一个接口:完成具体子类的实例化对象的创建,不能直接new子类,构造函数私有化. 优点:具体的子 ...

  2. 手机短信验证码一键注册登录功能开发 2

    1. 上一篇我们开发好了 短信验证码的发送功能, 接下来开发 我们的 一键登录注册功能 2. 有前端的视图我们可以看到, 传入的参数为手机号和验证码,我们用BO对其进行统一的封装,同时使用valid ...

  3. 01: 实现注册登录功能

    目录:抽屉项目之js最佳实践 01: 实现注册登录功能 02: 实现发布帖子功能 03: 将帖子展示到页面.点赞 04: 层级评论 目录: 1.1 显示.隐藏 "登录/注册" 菜单 ...

  4. 一步步开发自己的博客 .NET版(3、注册登录功能)

    前言 这次开发的博客主要功能或特点:     第一:可以兼容各终端,特别是手机端.     第二:到时会用到大量html5,炫啊.     第三:导入博客园的精华文章,并做分类.(不要封我)     ...

  5. 8、ABPZero系列教程之拼多多卖家工具 添加手机注册登录功能

    现在网站基本都用手机注册,很少用邮箱注册,本篇内容比较多,代码我会尽量加备注,有些操作需要连续添加几个文件才不报错,如果VS显示错误,请继续后续步骤. 前面已经有一篇文章讲到集成短信发送模块:http ...

  6. JavaWeb实现注册登录功能并将用户数据写进数据库(商城系统第一部分)

    JavaWeb实现注册登录功能并将用户数据写进数据库(商城系统第一部分) 声明:本人并非项目原创,该商城系统原创来自撩课高新强老师:https://study.163.com/course/intro ...

  7. PHP+ mysql实现注册登录功能

    首先打开XAMPP的mysql,创建一个adatabase数据库,再创建一个user的数据表. login.html <!DOCTYPE html> <html lang=" ...

  8. 微信小程序-注册登录功能-本地数据保存-页面数据交替

    Title:微信小程序-注册登录功能-本地数据保存-页面数据交替 完美-小程序登录注册功能.rar-- 访问码:yqa5 1.主页面 主页面login.js代码 // pages/login/logi ...

  9. javaweb实现简单注册登录功能——(注册)

    这里实现的注册登录功能是在学习了javaweb课程之后做的一个大作业中的内容,没有涉及任何框架技术,都是基础知识凑成的✌.适合刚开始接触web的孩纸. --首页: 首页代码: <%@ page ...

最新文章

  1. 彻底搞透视觉三维重建:原理剖析、代码讲解、及优化改进
  2. 完整的url以及同源跨域处理
  3. easyUI下datagrid嵌套显示
  4. linux安装meb工具,linux-docker下安装禅道全部
  5. 前端学习(1043):回车把数据存储到本地存储里面
  6. 存储系统又慢又杂太难用?我们推荐这几本书帮你解决问题
  7. python输出所有素数_Python程序打印一个区间内所有质数
  8. 万字长文详解如何用 Python 玩转 OpenGL | CSDN 博文精选
  9. atitit 研发管理 要不要自己做引擎自己实现架构?.docx
  10. 微信小程序生成海报库
  11. Windows10清理C盘
  12. 谷歌Google搜索及谷歌Google学术搜索镜像网站汇总
  13. 支付宝 android 崩溃,支付宝App崩溃网友集体炸锅 官方紧急回应
  14. 网线传输速度测试_千兆网络的速度测试
  15. 英语背单词软件需求分析
  16. 随笔杂记(十二)——_pickle.UnpicklingError: unpickling stack underflow
  17. 计算机网络——第三章 数据链路层——课后习题答案
  18. 报名进行时!邀您一起海外社媒会话跨境直播,实地探访MCN机构
  19. 深度学习自学第四周:近几年的经典神经网络结构
  20. Lua string.split

热门文章

  1. 动物宠物领养网站的设计与实现(Vue+Spring Boot+Java)
  2. 解决labelimg闪退
  3. mysql能用localhost连接不能使用127.0.0.1连接的解决办法
  4. WPS批量设置及批量打印文档
  5. java中的saturn_saturn java 热加载(一)
  6. 个性404页面模板php,25个创意404页面,支持模板下载
  7. 函数调用function与function()的区别
  8. 6个漂亮的各类型网站源代码打包分享
  9. 如何彻底删除Mac中的文件
  10. 芭芭拉--金字塔原理——读后感