1:在显示部门的下拉框中
|-财务部
|-审计处
|-报账处
这个功能的实现思路是:首先department类是有parent和childs【set集合】属性的,所以可以根据某个department得到它的父和子!那么就根据树的形式来递归得到所有的节点(department)吧!
设计两个方法,一个要得到所有的最高顶点(通过service实现),另一个方法打印顶点(传参数顶点)并且得到子节点然后再调用自己!
这个时候出现了两个问题,一个是在显示框中的|-符号防止保存到数据库中去,这个符号是在我们得到department对象的通过utils方法加上去的,好了逻辑是这样的,前面的service得到对象--utils加上符号然后显示,当我们不小心在utils后面又调用了一次service的方法后,这个符号就会保存到数据库中去,应为service的开启就对应着事务transactions的开始,service的关闭对于的事务的commit!
要解决这个符号不保存到数据库中去,需要知道,我们在herbinate懒加载那一篇博客中说过,延长了session的生命周期,我们的框架决定只有session管理的对象才能保存到数据库中,那么我们两种方法:
1 不使用session管理的对象
2 不再utils后面再打开事务也就是不再调用service方法
第二点是无法做到的,因为我们不能保证service方法日后不使用
用第一点解决:new copyDepartment 将它作为session中得到的对象的副本!这样完美解决!!
第二点是在显示审计处和报账处两个同级的部门时候,会出现顺序不固定,不信刷新试试!
由于我们在departments.hbm.xml中使用了
解决办法:
1 不用sets
2
使用2的时候,可以看到herbinate输出的sql语句是这样的:
2 session是一级缓存,sessionFactory是二级缓存???啥意思
翻阅自己的博客哦
3:很常见的反射技术得到泛型类
在DAO中药使用一次,DAO来得到这个这个T的具体类型,然后才能select * from T 或者将查找到的表列转换成真实的对象
继承者使用UserDAO extends DAO 来传入这个User,在DAO处得到使用的是:
注意这下面这段代码都写在父类的无参构造函数中的,且必须写在父类中,如果根本没有继承关系的话,比如说一个students类中的构造函数写下面的这段代码会出现:Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType错误,原因是无法得到自己的泛型
public BaseDaoImpl(){
//使用反射技术得到T的真实类型
//1:获取当前类的直接父类的类型type,强转成ParameterizedType
ParameterizedType pt=(ParameterizedType)this.getClass.getGenericSuperClass();
//返回表示此类型的实际类型参数的Type对象的数组
//Arguments?如果类型是map就是两个(0-K,1--v)咯,这里只是一个基本类型只有第0位
this.clazz=(Class)pt.getActualTypeArguments()[0];
}
点需要注意的是,在写子类继承父类的时候必须要将真实类型传送过去,比如“:
UserDAOImpl extends BaseDaoImpl<User> //不能写T了
#############################
3:整个项目开发中的模块化的思路:
模块化的地方有以下几处:当然还有jsp页面中的一些公共模块未显示在这里
这里可以看到实际上我们只分了两层,将DAO层去除掉了,因为在service层中就只是简单的调用dao中的方法(即数据库的增删改查),并未有很强的逻辑代码在环绕,所以还不如写成两层(实际上就是讲dao的代码写到了service中),所以现在的service层代码是这样的:
package cn.itcast.oa.base;
import java.util.List;
public interface DaoSupport {
void save(T entity);
void delete(Long id);
void update(T entity);
T getById(Long id);
List getByIds(Long[] ids);
List findAll();
}
*******************
package cn.itcast.oa.base;
import java.lang.reflect.ParameterizedType;
import java.util.Collections;
import java.util.List;
import javax.annotation.Resource;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;
// @Transactional注解可以被继承
// @Transactional注解对父类中声明的方法无效
@Transactional
@SuppressWarnings("unchecked")
public abstract class DaoSupportImpl implements DaoSupport {
@Resource
private SessionFactory sessionFactory;
private Class clazz;
public DaoSupportImpl() {
// 使用反射技术得到T的真实类型
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); // 获取当前new的对象的 泛型的父类 类型
this.clazz = (Class) pt.getActualTypeArguments()[0]; // 获取第一个类型参数的真实类型
System.out.println("clazz ---> " + clazz);
}
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
public void save(T entity) {
getSession().save(entity);
}
public void update(T entity) {
getSession().update(entity);
}
public void delete(Long id) {
Object obj = getById(id);
if (obj != null) {
getSession().delete(obj);
}
}
public T getById(Long id) {
if (id == null) {
return null;
} else {
return (T) getSession().get(clazz, id);
}
}
public List getByIds(Long[] ids) {
if (ids == null || ids.length == 0) {
return Collections.EMPTY_LIST;
} else {
return getSession().createQuery(//
"FROM " + clazz.getSimpleName() + " WHERE id IN (:ids)")//
.setParameterList("ids", ids)//
.list();
}
}
public List findAll() {
return getSession().createQuery(//
"FROM " + clazz.getSimpleName())//
.list();
}
}
看了上面的代码是不是以前都是写在dao中的,所以没有什么神秘的,也要注意到为什么要这样做!!!灵活运用,mvc不是必须的!!
************
接下来是BaseDao代码,原来我们常写的代码都是继承actionSupport,现在我们将BaseDao继承了actionSupport,然后让所有的action继承BaseDao,不仅不减少actionsupport的功能更扩展了功能:
package cn.itcast.oa.base;
import java.lang.reflect.ParameterizedType;
import javax.annotation.Resource;
import cn.itcast.oa.service.DepartmentService;
import cn.itcast.oa.service.PrivilegeService;
import cn.itcast.oa.service.RoleService;
import cn.itcast.oa.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public abstract class BaseAction extends ActionSupport implements ModelDriven {
// =============== ModelDriven的支持 ==================
protected T model;
public BaseAction() {
try {
// 通过反射获取model的真实类型
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
Class clazz = (Class) pt.getActualTypeArguments()[0];
// 通过反射创建model的实例
model = clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public T getModel() {
return model;
}
// =============== Service实例的声明 ==================
@Resource
protected RoleService roleService;
@Resource
protected DepartmentService departmentService;
@Resource
protected UserService userService;
@Resource
protected PrivilegeService privilegeService;
}
可以看到BaseDao也只是加了ModelDriven这个东西,主要目的是让我们传入一个实体对象进来,这样在页面中可以直接对此对象的属性进行添加了(不用写get/set,只写一个getModel就行了);
还有一个非常重要的地方:Service实例的声明 原来这个东西我是写在action中的,现在写到这个地方有什么好处???如果我们有两个action都需要用RoleService ,那么就不必写两次了嘛,在action中已经不需要写这个依赖注入了,直接拿来用就是了(protected是不同包中子类也可以访问),只要在action头上标志@Controller
@Scope("prototype")即可直接roleService.XX
那么上面的这个模板就写好了:
*****************
页面模块化:
作用
|
方法名
|
返回值
|
对应的
JSP
页面
|
列表
|
list()
|
list
|
list.jsp
|
删除
|
delete()
|
toList
|
|
添加页面
|
addUI()
|
addUI
|
addUI.jsp
|
添加
|
add()
|
toList
|
|
修改页面
|
editUI()
|
editUI
|
editUI.jsp
|
修改
|
edit()
|
toList
|
|
1.actionInvocation是什么
ActionInvocation就是Action的调用者。ActionInvocation在Action的执行过程中,负责Interceptor、Action和Result等一系列元素的调度。
理解ActionInvocation你需要对Action的调用过程有一个全面的了解:
http://tech.ddvip.com/2009-01/1232090919106049.html
讲的还是很清楚地!
2.ActionInvocation干什么
Interceptor通过ActionInvocation可以完全的改变Action行为:不让它执行、改变返回值、甚至可以细颗粒的操作Action的方法
查看ActionINvocation 的API,他有getActionProxy(),getResultCode();getActionContext();
ActionProxy在action中用来构建执行环境,ActionProxy提供Action执行的时候一切所需要的配置、参数等等,当然,也要有进行Action调用的入口。