tags: SSH整合与阅读项目
前言
前面我们已经学习了怎么整合SSH框架了。是时候拿一个小项目来练练手了....我们现在要设计一个企业人事管理系统...
需求:
要求对员工信息进行维护;
后台系统先登陆,才能操作员工: 添加/修改/删除
没有登陆,只能查看列表,不能操作!
功能分类:
【管理员模块】
注册/登陆
【员工模块】
1) 添加一个员工, 指定添加的部门
2) 对指定的员工信息修改
3) 删除选择员工
4) 列表展示
数据库设计
管理员表: t_admin
员工表: t_user
部门: t_dept
搭建配置环境
编写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
/p>
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
User.hbm.xml
/p>
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
Admin.hbm.xml
/p>
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
编写Dao
编写BaseDao
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 {
// 容器注入sessionFactory
@Autowired
private SessionFactory sessionFactory;
//子类的类型
private Class clazz;
//子类的名称
private String clazzName;
public BaseDao(){
clazz = (Class) 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 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{
}
编写AdminDao
/**
*
* 1.保存管理员【注册】--->add()
* 2.查找管理员【登陆】--->login()
*
*
* */
@Repository
public class AdminDao extends BaseDao {
@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 {
}
编写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 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 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 request;
@Override
public void setRequest(Map map) {
this.request = map;
}
/*列表展示*/
public String list() {
List list = userService.getAllUsers();
System.out.println(list);
//把数据封装到request对象上
request.put("list", list);
return "list";
}
}
Struts配置文件
/list.jsp
list.jsp页面
列表展示员工编号 | 员工姓名 | 员工部门编号 | 操作 |
修改,删除 |
对不起,还没有员工的信息,请录入
效果:
添加员工
添加员工,指定添加部门,跳转到添加员工显示页面...
@Autowired
private DeptService deptService;
/*添加员工...给出添加的JSP页面*/
public String viewAdd() {
//在添加员工的时候需要得到所有的部门信息
List deptList = deptService.getAllDept();
//封装到request域对象中
request.put("deptList", deptList);
return "viewAdd";
}
/viewAdd.jsp
显示添加员工界面:
添加员工界面员工名称 | |
员工部门 | |
在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";
}
返回到列表展示页面
user_list
效果:
修改员工
修改与删除的超链接:指明要修改用户的id【不然服务器哪知道你点击了哪一个用户】
提供修改界面【其实就是回显数据】
/*为修改提供页面,其实就是回显数据*/
public String viewUpdate() {
//得到user
User user = userService.findUserById(this.user.getId());
//得到所有的部门
List deptList = deptService.getAllDept();
request.put("deptList", deptList);
//使用Struts2的回显技术
ValueStack valueStack = ActionContext.getContext().getValueStack();
valueStack.pop();
valueStack.push(user);
return "viewUpdate";
}
/viewUpdate.jsp
修改页面JSP
修改员工界面员工名称 | |
员工部门 | list="#request.deptList" listKey="id" listValue="name" value="dept.id"/> |
因为使用了模型驱动,那么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";
}
测试:
管理员模块
注册
登陆
注册
提供注册的超链接
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{
/**********调用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;
}
}
配置信息
JSP页面:
注册界面管理员账号: | |
管理员密码: | |
Action实现
/*得到JSP页面带过来的数据、完成注册*/
public String register() {
adminService.register(admin);
return "listPage";
}
效果:
登陆功能
提供登陆的超链接
登陆的JSP页面
登陆界面管理员账号: | |
管理员密码: | |
Action中处理登陆
/*完成登陆*/
public String login() {
adminService.login(admin);
//把用户保存在Sessiion中
ActionContext.getContext().getSession().put("admin", admin);
return "listPage";
}
在list页面给出相对应的提示,如果登陆了就给出欢迎的显示
欢迎您:
效果:
权限操作
后台系统先登陆,才能操作员工: 添加/修改/删除
没有登陆,只能查看列表,不能操作!
我们写一个拦截器,判断是否调用登陆或者列表展示的方法,如果不是就查看该用户有没有登陆。没有登陆就跳转到登陆界面
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配置文件中配置拦截器
拦截器返回的login需要配置全局视图
user_list
/login.jsp
效果:
总结
本篇主要使用SSH框架来开发一个比较简易的CRUD项目。让我们熟悉SSH框架开发的流程。
设计实体
编写每个实体的映射文件
把映射文件加载到Hibernate中管理起来
使用BaseDao来管理全部的Dao,使得每个Dao都有Curd的方法。这样就不用我们在每个Dao都写上Crud了
如果普通的CURD方法满足不了我们,就可以在特定的Dao中写上自己想要的功能
Service层调用Dao层的方法
Controller调用Service层的方法实现功能,如果页面上需要后天的数据的话,那么我们先调用service获取得到数据,然后通过域对象(值栈对象)把数据存储起来,在页面上做展示。
如果文章有错的地方欢迎指正,大家互相交流。