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

10、jeecg 默认为空的字段值是如何被填充的?的更多相关文章
- Laravel 校验规则之字段值唯一性校验
版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] laravel validator unique 'name' => 'required|unique:test,disp ...
- C#三种判断数据库中取出的字段值是否为空(NULL) 的方法
操作数据库,需要判断返回的字段值是否为空,收集了3种方法供参考 1 通过System.DBNull判断,网上大部分都使用这个方法. DataTable dt; ...
- Sitecore CMS中如何管理默认字段值
在Sitecore CMS中管理默认字段值. 在创建内容时,自定义默认值对内容编辑者特别有用.通过指定良好的默认值,新创建的项目可以预先填充数据,以便内容编辑者不必浪费时间一遍又一遍地填充相同的字段. ...
- 解决用 VB 中用 ADO 访问 数据库时 SQL 查询处理 Null 值的问题( 使用 iff(isNull(字段), 为空时的值,不为空时的值) 来处理)
程序的环境是 VB6 + ADO + Access,在用 SQL 语句查询时,希望把两个字段合并成一个字段,但其中一个字段 Null 值直接导致两个字段合并后也变成了 Null 值.之前只能用 VB ...
- [ArcGIS API for JavaScript 4.8] Sample Code-Popups-1-popupTemplate的概念和popup中属性字段值的多种表现形式
[官方文档:https://developers.arcgis.com/javascript/latest/sample-code/intro-popuptemplate/index.html] 一. ...
- SQL3120W 不能将xx的字段值转换成 INTEGER值
一次用DB2 Load/Import导入数据时,报错,提示SQL3120W 不能将xx的字段值转换成 INTEGER值,但目标列不可为空.未装入该行. 目标表: CREATE TABLE TEST( ...
- Calender类——字段值介绍
今天,看到有人这样编写代码,有点不明所以: Calendar calendar = Calendar.getInstance(); calendar.get(1): calendar.get(2)+1 ...
- GridView控件RowDataBound事件中获取列字段值的几种途径 !!!
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == ...
- Linux下统计出现次数最多的指定字段值
假设桌面上有一个叫“data.txt”的文本,内容如下: {id='xxx' info='xxx' kk='xxx' target='111111' dd='xxx'}{id='xxx' info=' ...
随机推荐
- Deformable Convolutional Network
Deformable conv赋予了CNN位置变换的能力,与普通卷积的对比如下.可以看到,在每个特征点上,会产生一个偏移,变成 不规则的卷积(感觉本质上,就是让CNN自己去学习感受野). 思想来源于S ...
- 最完整的dos命令字典,IIS服务命令,FTP命令
https://www.cnblogs.com/accumulater/p/10670051.html(优秀博文) 一.最完整的dos命令字典net use ipipc$ " " ...
- python 2.7 数据结构之列表list: 基础面试总结
python 列表函数及方法: 函数如下: 1 cmp(list1,list2) 比较两个列表中的元素 2 len(list) 列表元素个数 3 max(list) 返回列表元素最大值 4 min(l ...
- tensorflow结果可视化-【老鱼学tensorflow】
这次我们把上次的结果进行可视化显示,我们会把神经网络的优化过程以图像的方式展示出来,方便我们了解神经网络是如何进行优化的. 首先,我们把测试数据显示出来: # 显示测试数据 fig = plt.fig ...
- ionic2中使用videogular2实现m3u8文件播放
// 安装依赖 npm i videogular2 --save npm i hls.js --save // 在index.html中引入 <script src="assets/h ...
- Pop Star 1.2.5
原文链接https://www.cnblogs.com/zhouzhendong/p/Pop-Star.html 是VB写的. 年代久远,代码太丑,原码不公开. 下载链接 仅支持Windows,需要解 ...
- 毕向东—Java基础知识总结(超级经典)
Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...
- JS浅谈原始值与引用值操作
值的操作分为三大类:复制,传递,比较 一:复制 原始值 let a = 10; let b = a; 注释:2018-7-30 17:33:49 1 原始类型的值都是存放在栈内存当中,所以他们的赋值操 ...
- redis初步入门(1)
一.redis是一款高性能NOSQL系列的非关系型的数据库,其是用C语言开发的一个开源高性能键值对(key-value)数据库. 二.redis的应用场景 1.缓存(数据查询.短连接.新闻内容.商品内 ...
- Kali Linux常用服务配置教程启动DHCP服务
Kali Linux常用服务配置教程启动DHCP服务 通过前面的介绍,DHCP服务就配置好了.接下来,用户就可以使用该服务器来获取IP地址了.下面将对前面配置的服务进行测试. 1.启动DHCP服务 如 ...