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

posted @ 2018-12-19 21:37 niceyoo 阅读(...) 评论(...) 编辑 收藏

10、jeecg 默认为空的字段值是如何被填充的?相关推荐

  1. Laravel 校验规则之字段值唯一性校验

    版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] laravel validator unique 'name' => 'required|unique:test,disp ...

  2. mybatisPlus更新字段值为null

    mybatisPlus更新字段值为null 问题描述 TableField源码 FieldStrategy 源码 设置为null的方案 使用UpdateWrapper更新 设置全局的field-str ...

  3. 【SpringBoot整合Mybatis】数据库某字段值为空时,接口未返回该字段 解决办法

    [SpringBoot整合Mybatis]数据库字段为空时,接口不返回该字段 解决办法 问题描述: 排查问题: 解决问题: 测试: 参考资料: 今天整合项目的时候,发现了SpringBoot整合Myb ...

  4. C#三种判断数据库中取出的字段值是否为空(NULL) 的方法

    操作数据库,需要判断返回的字段值是否为空,大致有以下三种方法: 1 通过System.DBNull判断,网上大部分都使用这个方法. DataTable dt;         //假设字段为name, ...

  5. Qt中SQL语句update同时更新多字段及设置字段值为空的方法

    Qt中往往需要对数据库进行操作,常出现根据某变量更改相关字段的内容.一般地,可以采用名称绑定和位置绑定两种方法. Qt与MySQL连接方法:https://blog.csdn.net/ckzhb/ar ...

  6. 获取的字段值是空值或者为null,而你自己的需求就是想要获取的字段为一个 * 默认的值

    一.业务阐述 在开发中查询的数据库结果集,既要连接数据库.执行数据库操作.关闭数据库,还要把结果集的记录人为的设置到自己封装的DAO中等一系列的重复代码. 本文主要是想解决:用户只需要得到数据库连接, ...

  7. 泰斗破坏神中对象一直为空,但对象的字段值却不为空

    泰斗破坏神中对象一直为空,但对象的字段值却不为空 错误原因: 按照规范,继承自monobehaviour的类都是组件,组件都要unity负责创建,我们是不能自己去new的 解决方法: 不继承monob ...

  8. cxf webservice接收date类型字段值为空导致异常问题解决方案

    cxf webservice接收date类型字段值为空时,后台会报错.原因是cxf没有很好处理空值的情况. 解决方案 自定义date字段的转换方式.以springboot cxf 为例.涉及以下三点改 ...

  9. mysql 默认插入值_MySQL插入默认字段值方法大全

    在数据库表设计的时候,经常需要设定字段的默认值,在插入数据时会出现以下的情况:如果该字段为NULL类型,那么直接将NULL插入到该字段,字段值就是设定的默认值NULL: 如果该字段为NOT NULL类 ...

最新文章

  1. openwrt监控linux,OpenWRT上判断客户端在线个数
  2. SQLite编译(How To Compile SQLite)
  3. G_PERIOD_GET
  4. 数据库原理与应用(SQL Server)笔记 第九章 存储过程和触发器
  5. 一文带你学C语言,详细知识点思维导图!
  6. 一个15岁少年写的汇编代码
  7. 【EF学习笔记07】----------加载关联表的数据 贪婪加载
  8. 剑指offer面试题[31]-连续数组的最大和
  9. 纯div+css制作的弹出菜单
  10. Microsoft SQL Server数据库学习(一)
  11. Android之AIDL跨进程通讯
  12. Lidar Studio点云处理与分析软件V1.1
  13. 【STM32H7的DSP教程】第8章 DSP定点数和浮点数(重要)
  14. Twaver-HTML5基础学习(11)形状节点(ShapeNode)
  15. 一周极客热文:看马云李彦宏马明哲等大佬手绘未来图
  16. 有符号数的二进制表示方式
  17. py使用pie绘制饼图或圆环图
  18. Qt Design Studio 1.4正式发布
  19. ellipse函数用法
  20. cad用计算机怎么计算坐标,CAD坐标里能输入公式吗?

热门文章

  1. [css] 请说说在什么时候用transition?什么时候使用animation?
  2. [css] 用css怎么实现两端对齐?
  3. [css] 使用css实现蒙版的效果
  4. 前端学习(1670):前端系列实战课程之核心运动原理
  5. 前端学习(1261):接口调用fetch方法
  6. 前端学习(219):css伪类选择器
  7. mybatis学习(36):动态sql-set
  8. 70 include指令
  9. 花卉网页html,花卉管理系统(数据库+源码)
  10. java 在数组末尾添加元素_Java快问快答:用 ArrayList 还是 LinkedList?