OA项目知识总结2

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OA项目知识总结2相关的知识,希望对你有一定的参考价值。

 

BaseAction的抽取

项目中的每个实体类都对应一个action  每个action都都要继承ActionSupport类 已以及实现ModelDriver接口  并且需要注入service 虽然每个action注入的service不同

但是也有可能另外一个action需要使用到其他action中的service  那么就存在大量的重复注入代码  尽管service是单例的不影响性能  但是我们需要做的是尽量少些重复代码

例如

技术分享

 技术分享

此时BaseAction诞生了 

package org.base;
import java.lang.reflect.ParameterizedType;
import javax.annotation.Resource;
import org.service.DepartmentService;
import org.service.RoleService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public abstract class BaseAction<T> extends ActionSupport implements ModelDriven<T>{

    //通过反射获得T的真实类型  然后 实例化model对象
    public BaseAction(){
        //得到泛型的父类
        ParameterizedType pz=(ParameterizedType) this.getClass().getGenericSuperclass();
//得到第一个类型参数的真实类型
        Class<T> clazz=(Class<T>) pz.getActualTypeArguments()[0];
//创建实例对象  异常  抛出
        try {
            model=clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    protected T model;
    public T getModel() {
        return model;
    }
    
    //因为子类(继承该action)action已经在spring容器中  所以 baseAction不需要注入进容器  
    //就可以注入容器中的对象  否则 注入容器中的对象  必须自己先注入进容器
    @Resource
    protected RoleService roleService;
    @Resource
    protected DepartmentService departmentService;
}

上边的代码蓝色阴影中

protected设置为受保护的  子类可以继承并访问

abstract的作用:BaseAction不需要实例  所以声明为抽象的

<T> 泛型:每个子类action在实现modelDriver时都需要指定对应的model类型  子类action在实例化自己的时候 先调用父类的构造方法  实例化model  然后才能在自己的类中得到该model (访问权限为propected) 所以在继承BaseAction的时候 给该父类传递明确的类型T(例如 Department  或者Role)

技术分享

----

技术分享

如此  子类action中就可以只写具体操作service的代码了 其他代码全部又BaseAction来完成  

-----------------------------------------------------------------------

项目简单,serivce业务层没有业务代码  只是纯粹的调用dao时   删除dao层  采用两层架构 

service中不在使用dao进行调用  而是service中直接继承数据库操作的类  在action中调用serivce时  直接调用了数据库操作的类

传统结构:

action调用service  serivce调用dao

技术分享

dao继承了baseDao   所以最终service调用的其实是basedao中的方法

技术分享

现在进行两层设计   删去dao以及daoimpl实现类  service直接继承basedao

技术分享

技术分享

 

 技术分享

最终的代码实现还是在basedaoimpl中  不过需要注意的是 需要在basedaoimpl上加入事务管理   只要存在对数据的增删改查  都加入事务处理  因为事务提交之后 才会对数据做更改

之前service中加入了事务 是因为在service中是先调用了dao   现在如果直接继承basedaoimpl  那么action在调用service的时候  父类是daosupportImpl 对其无效  没有经过事务管理

技术分享

所以当子类继承父类中的方法后 ,调用父类中的方法执行增删改查的时候,即使子类service上标记的有事务注解   也不管用,需要在父类的上边开启事务注解

技术分享

-------------------------------------------------------

模型封装时

前端页面XX.id 提交给 自动封装进某个对象的XX属性(对象属性)的id属性中

在action中也不用进行关联操作(前提是id不能为null 如果为空 查到的对象自然也是nul 所以直接给该对象中的这个对象属性关联null) 直接保存或修改就行

--------------------------

action中执行添加之前model.getId()没有值,这个值是在添加记录之后,由数据库自动生成的,不过需要注意的是,当调用方法保存之后,在action的model模型中  再通过model.getId()是可以得到刚才保存的那条记录的id的

技术分享

-------------------------------------------------

方法返回值为集合的时候,如果查找之后的内容为空  返回空集合

技术分享

---------------------------------------------------------

多对多关系  拆分为两个一对多关系

用户和角色是多对多关系,一个用户可以有多个角色(岗位) 

一个岗位可一个存在多个用户

用户:user表

技术分享

角色:role表

技术分享

中间表:user_role

技术分享

 

他们对应的映射文件我这里就不在截图了  关于他们的配置在之前的ssh整合总结中有详细的配置说明

这里做总结的原因是  当时在做添加的时候  有点小迷惑  不知道怎么去完成添加(当时是这样想的  用户提交给后台action的属性中  id是在插入数据库后自动创建的

但是这里的中间表需要的是user对象  以及role对象啊   没有id属性值  我怎么做关联  或者说没有id的对象  关联之后 能够进行级联添加吗  即在做用户添加的时候 关联之后 只保存用户对象 相关联的数据 会保存吗(中间表的数据能否添加成功))

所以我最早采用的是 :先不关联role  然后保存model对象  保存之后 数据库可以返回刚插入的记录对应的id 然后有了用户id  role对象  创建中间表对象  设置中间表对象的值  另外写了中间表操作类  然后遍历保存(有几个role对象  就遍历几次  保存几次  完成了向中间表插入数据的效果  最后也完成了项目的需求   这种方式不推荐使用  )

不推荐方式对应代码:

技术分享

下面说说  我看了看之前写的博客总结(hibernate一对多总结  hibernate多对多总结  ssh总结一 二) 迷惑散去之后   改进之后的代码吧

前台页面:

技术分享

action中可以得到用户选择的所有岗位对应的id值

技术分享

然后重点来了

技术分享

这样就完成了级联保存操作(前提 :1.配置级联保存操作 save-update  2.上面红线前边的代码不可以缺少  两者缺一不可  少其中任何一个  中间表数据都不会保存  造成只向用户表插入记录  )

另外需要思考的是:配置级联是在哪方配置的?是一方还是多方  答案:一方配置  我们通常情况下都是通过保存一的同时来级联保存中间表的数据  所以级联操作是保存在一方的配置文件set表签内的

但是 会不会出现通过保存中间表的数据 来级联保存一方表的数据呢 答案我这里可以肯定的告诉你不会   说说原因吧 ,这里我举一个前边做过的项目的例子:

技术分享

还记得这个项目吗(不记得 去前边的 ssh项目总结中找)  这个项目中 客户customer  用户user 就是多对多的关系  然后拆分 引出中间表(拜访表)visit

这个项目中操作的对象就正好是我上边说的那种情况  直接保存中间表对象(所以一方表对应的配置文件中当然就不用配置级联属性)    没有级联保存一方表(customer,user)  所以在多方visit映射配置文件中也没有配置级联属性

 为啥呢 ?  说到这里大家看图也应该明白了吧  一方数据已经在页面上显示了   等于说一方数据已经存在于数据库中了  那还保存个毛线啊   这里只是让用户选择   然后 提交给后台   最终做的操作只是向中间表中插入数据  表示某个用户拜访了某个客户  当然后台对应的有中间表操作类  提交给的action也是中间表对应的action  这种方式只能单独写一个中间表操作类  因为不可能在通过一方表来进行关联  配置级联  然后通过保存一方 级联保存中间表数据   那样不就转了一大圈 然后又转回来了  何不直接使用我刚才在最上边 迷惑之后使用的那种改进的代码呢。

看下面截图:

技术分享

提交给action 调用的操作类也是中间表的操作类

技术分享

技术分享

所以说到这里大家都对这两种方式清楚了吧 

第一种方式:配置级联  通过保存一方  级联保存多方

第二种:直接操作的就是中间表对象  不用配置级联属性  直接提交给中间表action 调用中间表操作类 直接对中间表进行插入数据

----------------------------------------------------------

 技术分享

----------------------------------------

 

以上是关于OA项目知识总结2的主要内容,如果未能解决你的问题,请参考以下文章

OA项目系统二次开发需要哪些知识能力?大家帮忙看看吧!

OA项目总结3

线程学习知识点总结

回归 | js实用代码片段的封装与总结(持续更新中...)

软件维护工作经验总结

通达OA 小飞鱼OA实施法:以项目管理的方式来推进工作流设计项目实施