zoukankan      html  css  js  c++  java
  • 10、jeecg 默认为空的字段值是如何被填充的?

    1、前言

    用过 jeecg 的小伙伴,在 jeecg 实体中常见下面几个字段:

    /**创建人名称*/
    private java.lang.String createName;
    /**创建人登录名称*/
    private java.lang.String createBy;
    /**创建日期*/
    private java.util.Date createDate;
    /**更新人名称*/
    private java.lang.String updateName;
    /**更新人登录名称*/
    private java.lang.String updateBy;
    /**更新日期*/
    private java.util.Date updateDate;

    而我们在使用过程中,并没有给其赋,但是存入数据库后却突然冒出值了?
    其实不然,在这用到了 [拦截器],下面详看一下 jeecg 中的实现代码。

    2、代码分析

    在 org.jeecgframework.core.aop 包下有个 HiberAspect.java,这就是今天的主角,拦截器;

    也许你会有疑问,为何要把拦截器放在 aop 这个目录下呀?sorry i don't know...  

    2.1、为何要使用?

    其实,这种需求很常见,比如创建一笔数据,每次创建一笔数据都要去给 createBy createDate.. 赋值,岂不是很麻烦?

    而恰好 Hibernate 提供的拦截器就能帮我们实现这样繁琐的问题。

    当 session 执行 save()、update()、saveOrUpdate()、delete()以及 flush() 方法时,就会调用拦截器的相关方法,然后在这些方法中实现赋值的逻辑。 

    2.2、了解如何用

    对于用户定义的拦截器必须要实现 org.hibernate.Interceptor 这个接口,在这个接口中主要定义了以下方法。

    onDelete(): 删除时调用. 
    onFlushDirty():更新数据时调用,但数据还没有更新到数据库
    onSave():保存数据的时候调用,数据还没有保存到数据库.
    preFlush(): 保存,删除,更新 在提交之前调用 (通常在 postFlush 之前).
    postFlush():提交之后调用(commit之后)

    而在 org.hibernate 包中还提供了 Intercepto 接口的一个实现类 EmptyInterceptor,这个类中的所有方法实际上什么也不做,用户自定义的拦截器类也可以扩展此类。 

    类继承该接口是官方推荐,并且 jeecg 也是这样用的。

    jeecg  onSave() 方法实现赋值:

    /* 拦截hibernate save方法(即保存对象之前回调此方法),添加审计信息
     * entity - POJO Instance
     * id - POJO OID
     * state - POJO Instance中每一个属性的值所组成的集合(OID属性除外)
     * propertyNames - POJO Instance中每一个属性的属性名组成的集合(OID属性除外)
     * types - POJO Instance中每一个属性所属类型所对应的Hibernate类型组成的集合(OID属性除外)
     */

    public boolean onSave(Object entity, Serializable id, Object[] state,

            String[] propertyNames, Type[] types) {
        TSUser currentUser = null;
        try {
            currentUser = ResourceUtil.getSessionUser(); // session 中获取用户信息
        } catch (RuntimeException e) {
            //logger.warn("当前session为空,无法获取用户");
        }
        if(currentUser==null){
            return true;
        }
        try {
            //添加数据
             for (int index=0;index<propertyNames.length;index++)
             {
                 /*找到名为"创建时间"的属性*/
                 if (DataBaseConstant.CREATE_DATE.equals(propertyNames[index])
                         ||DataBaseConstant.CREATE_TIME.equals(propertyNames[index]))
                 {
                     /*使用拦截器将对象的"创建时间"属性赋上值*/
                     if(oConvertUtils.isEmpty(state[index])){
                         state[index] = new Date();
                     }
                     continue;
                 }
                 /*找到名为"创建人"的属性*/
                 else if (DataBaseConstant.CREATE_BY.equals(propertyNames[index]))
                 {
                     /*使用拦截器将对象的"创建人"属性赋上值*/
                     if(oConvertUtils.isEmpty(state[index])){
                          state[index] = ResourceUtil.getUserSystemData(DataBaseConstant.SYS_USER_CODE);
                     }
                     continue;
                 }
                 /*找到名为"创建人名称"的属性*/
                 else if (DataBaseConstant.CREATE_NAME.equals(propertyNames[index]))
                 {
                     /*使用拦截器将对象的"创建人名称"属性赋上值*/
                     if(oConvertUtils.isEmpty(state[index])){
                         state[index] = ResourceUtil.getUserSystemData(DataBaseConstant.SYS_USER_NAME);
                     }
                     continue;
                 }
                 /*找到名为"创建人名称"的属性*/
                 else if (DataBaseConstant.SYS_USER_CODE.equals(propertyNames[index]))
                 {
                     /*使用拦截器将对象的"创建人名称"属性赋上值*/
                     if(oConvertUtils.isEmpty(state[index])){
                         state[index] = ResourceUtil.getUserSystemData(DataBaseConstant.SYS_USER_CODE);
                     }
                     continue;
                 }
                 /*找到名为"创建人部门"的属性*/
                 else if (DataBaseConstant.SYS_ORG_CODE.equals(propertyNames[index]))
                 {
                     /*使用拦截器将对象的"创建人部门"属性赋上值*/
                     if(oConvertUtils.isEmpty(state[index])){
                         state[index] = ResourceUtil.getUserSystemData(DataBaseConstant.SYS_ORG_CODE);
                     }
                     continue;
                 }
                 /*找到名为"创建人部门"的属性*/
                 else if (DataBaseConstant.SYS_COMPANY_CODE.equals(propertyNames[index]))
                 {
                     /*使用拦截器将对象的"创建人部门"属性赋上值*/
                     if(oConvertUtils.isEmpty(state[index])){
                         state[index] = ResourceUtil.getUserSystemData(DataBaseConstant.SYS_COMPANY_CODE);
                     }
                     continue;
                 }
                 /*找到名为"流程状态"的属性*/
                 else if (DataBaseConstant.BPM_STATUS.equals(propertyNames[index]))
                 {
                     /*使用拦截器将对象的"流程状态"属性赋上值*/
                     if(oConvertUtils.isEmpty(state[index])){
                         state[index] = String.valueOf(1);//1:未提交
                     }
                     continue;
                 }
             }
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
         return true;
    }

    jeecg  onFlushDirty() 方法脏数据回调:

       /**
         *  拦截hibernate flush方法(即检查到脏对象时回调此方法),添加审计信息
         *  entity - POJO Instance
         *  id - POJO OID
         *  state - POJO Instance中每一个属性的值所组成的集合(OID属性除外)      
         *  propertyNames - POJO Instance中每一个属性的属性名组成的集合(OID属性除外)     
         *  types - POJO Instance中每一个属性所属类型所对应的Hibernate类型组成的集合(OID属性除外)
         */  
        public boolean onFlushDirty(Object entity, Serializable id, Object[] state, Object[] previousState,  
                String[] propertyNames, Type[] types) {  
    
            ....
    
    }

    2.3、xml配置

    首先补充一点,Hibernate 的拦截器有两种设置方式:

    一种是使用sessionFactory.openSession(Interceptor interceptor),这样的拦截器只会针对该session有效,又叫做局部拦截器。
    另一种是使用Configuration的setInterceptor(Interceptor interceptor)方法设置,这样的拦截器对每一个session都有效,又称之为全局拦截器,全局拦截器

    spring-mvc-hibernate 配置:

    <!-- sessionFactory -->  
    <bean id="sessionFactory"  
      class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">  
      <property name="dataSource" ref="dataSource" />  
      ......  
      <property name="entityInterceptor" ref="hiberAspect"></property>  
      ......  
    </bean>  

    将审计拦截器作为 sessionFactory 的属性进行配置,即表示此拦截器可以被所有 Session 实例共享;

    等同的代码表示方式为:Configuration.setInterceptor(Interceptor inter)。 

    也就是上方补充拦截器设置方式二。

    3、最后

    jeecg 提供的不一定是唯一实现方式,通过 aop 也可实现,如有想去自定查询。

    博客地址:http://www.cnblogs.com/niceyoo

    18年专科毕业后,期间一度迷茫,最近我创建了一个公众号用来记录自己的成长。

  • 相关阅读:
    JSON数据格式
    段寄存器
    进程 PCB 进程挂起
    python3:文件读写+with open as语句(转)
    Python 中 'unicodeescape' codec can't decode bytes in position XXX: trun错误解决方案
    intelx86为何从0xFFFF0处执行
    Linux内核调度分析(转,侵删)
    调度器简介,以及Linux的调度策略(转)
    nm命令
    Vim文本编辑器中常用的一些命令
  • 原文地址:https://www.cnblogs.com/niceyoo/p/10146274.html
Copyright © 2011-2022 走看看