八:使用泛型化的BaseAction产生的问题
import java.lang.reflect.ParameterizedType; import cn.survey.exception.ActionException; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.Preparable; /** * 模型驱动只在进入action的时候注入一次,返回去的时候不再注入进去 * 而且模型驱动注入的是对象引用,如果在action中将model属性的对象引用地址改变了,也就是重新给model赋值, * 但是modelDriven中的属性并没有发生改变,还是对原来对象的引用, * 所以,想要改变modelDriven中注入的模型驱动的值,那么只有在modelDriven拦截器之前就将model的值改变 * 每次访问action的时候,在获取到对应的action的代理对象的时候,首先会先将该action实例化,实例化的时候,会将action中的泛型参数也实例化 实例化的泛型参数是当前action传入的实体对象,,实例化以后,medol中默认值,根据实体的属性来是否有默认值来生成 解决上面问题的方法: * 实现拦截器Preparable是为了让程序员在struts使用模型驱动之前做一些事情,必须更改默认的拦截器栈,选择prepare拦截器,在modelDriven之前,而且属性驱动params得在prepare之前将属性值赋给action中的属性 * 可以查看struts-default.xml文档 使用paramsPrepareParamsStack(参数预定义参数栈) 实现了prepareable接口的action,可以在当前action中定义prepare**()这些方法表示在执行action中的**()之前,执行 哪个先执行主要是看使用的拦截器栈中拦截器的顺序 */ public abstract class BaseAction<T> extends ActionSupport implements ModelDriven<T> ,Preparable{ private static final long serialVersionUID = 8740558859244194183L; @SuppressWarnings("rawtypes") public Class clazz; //如果model属性在这里声明为了私有的,又没有给modelset方法,那么在子类中没有办法给模型赋值 public T model; @SuppressWarnings({ "rawtypes", "unchecked" }) public BaseAction(){ try { ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); clazz = (Class) pt.getActualTypeArguments()[0]; //在访问action的时候,会在实例化action的时候就把传入的泛型参数给实例化了 model = ((T) clazz.newInstance()); } catch (Exception e) { throw new ActionException("初始化实例异常",e); } } public void prepare() throws Exception { } public T getModel() { return model; } }
九: params拦截器中的属性赋值,只是给栈中栈顶的属性赋值,
请求过action,在没有执行modelDriven的时候只是把当前的action放到了栈顶,如果想操作非栈顶的元素,
比如action的对象的属性,那么在页面上声明的名字是:对象名(该对象是action中的一个属性).属性,这里使用的是属性驱动的链式赋值
使用参数预定义拦截器栈
使用paramsPrepareParamsStack(参数预定义参数栈),利用的是struts2的默认的压栈功能,
也可以手动方式的进行压栈,这样就不需要更改默认拦截器栈
优化struts的程序的时候,我们也可以自己定义拦截器栈,我们只用,对我们有用的拦截栈,这样可以省略很多的验证
十:
有时候为了性能,我们会将数据库设计成不符合教案的(不应该出现冗余字段)
为了性能出现的字段,如果和其他的表有关联关系,我们可以不在映射的时候加上关联关系
* 这样的表在数据库中出现的时候,没有主外建的关系,不指明,和其他的表没有一点关系
这个时候我们操作数据库的时候,只需要直接按照常规字段操作就可以的,
这些冗余的字段,在这里就是一个标记性的字段,我们操作这些关系的时候,就是用这些标记性的字段去操作(标记字段包含了业务逻辑关系)
十一:
hibernate删除的时候外连接是有限制的,属性链只能到当前对象的属性中,再往里走就不能了
比如: p.page.survey.id,删除是不能这么使用,可以达到p.page.id这一层
在查询的时候hibernate的属性链可以多级链接()
十二: 可以直接在sql语句中使用!取反(针对boolean类型)
在hql中不可以,可以先查出来,然后将值取反当成参数传入进去
十三:
查询的时候如果字段为空(null),由于survey中增加的是基本类型(int,long),无法将null值赋值给基本类型,
则不能在前台显示,会报ProperyAccessException属性访问异常,()
十四:高内聚,低耦合
在一个模块内部,联系越紧越好
A a b c B a b
c想实现a,先在模块内部找,如果模块内部没有的话,再去B模块中
在不同的模块中,联系越松散越好
十五:ognl表达式可以调后台的方法
当前栈中的action中的方法,可以调用 直接value="aa()"
可以调用的方法:实例方法,静态方法
十六:struts2中关注对象*Aware对象的使用(面向切面的编程思想)
每个对象的关注对象,都是由该对象的拦截器去将该关注,注入到实现关注对象的action中的
1,使用关注对象可以使代码变得更优雅
2,使用关注对象脱离了action中各个方法的限制(否则在对应的方法中使用该对象的时候,必须手动的去实现,而且各个方法还是分离的)
3,使用关注对象,当经过拦截器进入action的时候,关注所属的拦截器已经将该关注需要的对象注入了进去
注:如果使用静态代码块生成的话也是可以的,但是不优雅,还得专门开辟出来一块内存空间呢
文章评论