10、jeecg 默认为空的字段值是如何被填充的?
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
10、jeecg 默认为空的字段值是如何被填充的?相关推荐
- Laravel 校验规则之字段值唯一性校验
版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] laravel validator unique 'name' => 'required|unique:test,disp ...
- mybatisPlus更新字段值为null
mybatisPlus更新字段值为null 问题描述 TableField源码 FieldStrategy 源码 设置为null的方案 使用UpdateWrapper更新 设置全局的field-str ...
- 【SpringBoot整合Mybatis】数据库某字段值为空时,接口未返回该字段 解决办法
[SpringBoot整合Mybatis]数据库字段为空时,接口不返回该字段 解决办法 问题描述: 排查问题: 解决问题: 测试: 参考资料: 今天整合项目的时候,发现了SpringBoot整合Myb ...
- C#三种判断数据库中取出的字段值是否为空(NULL) 的方法
操作数据库,需要判断返回的字段值是否为空,大致有以下三种方法: 1 通过System.DBNull判断,网上大部分都使用这个方法. DataTable dt; //假设字段为name, ...
- Qt中SQL语句update同时更新多字段及设置字段值为空的方法
Qt中往往需要对数据库进行操作,常出现根据某变量更改相关字段的内容.一般地,可以采用名称绑定和位置绑定两种方法. Qt与MySQL连接方法:https://blog.csdn.net/ckzhb/ar ...
- 获取的字段值是空值或者为null,而你自己的需求就是想要获取的字段为一个 * 默认的值
一.业务阐述 在开发中查询的数据库结果集,既要连接数据库.执行数据库操作.关闭数据库,还要把结果集的记录人为的设置到自己封装的DAO中等一系列的重复代码. 本文主要是想解决:用户只需要得到数据库连接, ...
- 泰斗破坏神中对象一直为空,但对象的字段值却不为空
泰斗破坏神中对象一直为空,但对象的字段值却不为空 错误原因: 按照规范,继承自monobehaviour的类都是组件,组件都要unity负责创建,我们是不能自己去new的 解决方法: 不继承monob ...
- cxf webservice接收date类型字段值为空导致异常问题解决方案
cxf webservice接收date类型字段值为空时,后台会报错.原因是cxf没有很好处理空值的情况. 解决方案 自定义date字段的转换方式.以springboot cxf 为例.涉及以下三点改 ...
- mysql 默认插入值_MySQL插入默认字段值方法大全
在数据库表设计的时候,经常需要设定字段的默认值,在插入数据时会出现以下的情况:如果该字段为NULL类型,那么直接将NULL插入到该字段,字段值就是设定的默认值NULL: 如果该字段为NOT NULL类 ...
最新文章
- openwrt监控linux,OpenWRT上判断客户端在线个数
- SQLite编译(How To Compile SQLite)
- G_PERIOD_GET
- 数据库原理与应用(SQL Server)笔记 第九章 存储过程和触发器
- 一文带你学C语言,详细知识点思维导图!
- 一个15岁少年写的汇编代码
- 【EF学习笔记07】----------加载关联表的数据 贪婪加载
- 剑指offer面试题[31]-连续数组的最大和
- 纯div+css制作的弹出菜单
- Microsoft SQL Server数据库学习(一)
- Android之AIDL跨进程通讯
- Lidar Studio点云处理与分析软件V1.1
- 【STM32H7的DSP教程】第8章 DSP定点数和浮点数(重要)
- Twaver-HTML5基础学习(11)形状节点(ShapeNode)
- 一周极客热文:看马云李彦宏马明哲等大佬手绘未来图
- 有符号数的二进制表示方式
- py使用pie绘制饼图或圆环图
- Qt Design Studio 1.4正式发布
- ellipse函数用法
- cad用计算机怎么计算坐标,CAD坐标里能输入公式吗?
热门文章
- [css] 请说说在什么时候用transition?什么时候使用animation?
- [css] 用css怎么实现两端对齐?
- [css] 使用css实现蒙版的效果
- 前端学习(1670):前端系列实战课程之核心运动原理
- 前端学习(1261):接口调用fetch方法
- 前端学习(219):css伪类选择器
- mybatis学习(36):动态sql-set
- 70 include指令
- 花卉网页html,花卉管理系统(数据库+源码)
- java 在数组末尾添加元素_Java快问快答:用 ArrayList 还是 LinkedList?