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年专科毕业后,期间一度迷茫,最近我创建了一个公众号用来记录自己的成长。

  • 相关阅读:
    部署 AppGlobalResources 到 SharePoint 2010
    还原一个已删除的网站集
    使用仪表板设计器配置级联筛选器 (SharePoint Server 2010 SP1)
    File or arguments not valid for site template
    Pex and Moles Documentation
    Content Query Webpart匿名访问
    Running Moles using NUnit Console from Visual Studio
    Calling a WCF Service using jQuery in SharePoint the correct way
    Updating Content Types and Site Columns That Were Deployed as a Feature
    asp.net中判断传过来的字符串不为空的代码
  • 原文地址:https://www.cnblogs.com/niceyoo/p/10146274.html
Copyright © 2011-2022 走看看