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年專科畢業后,期間一度迷茫,最近我創建了一個公眾號用來記錄自己的成長。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM