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

 

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/414603.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Service与IntentService区别

相同点&#xff1a; 1、首先Service与IntentService都是Android的基本组件service 2、使用时都是一样需要创建&#xff0c;配置&#xff1b;和调用启动方式都是一样的 不同点&#xff1a; 1、IntentService是继承自Service的service 类&#xff0c;创建了自己的特有方法onH…

前端学习(2743):重读vue电商网站53之项目上线

通过 node 创建 web 服务器。开启 gzip 配置。配置 https 服务。使用 pm2 管理应用。 通过 node 创建 web 服务器 创建 node 项目&#xff0c;并安装 express&#xff0c;通过 express 快速创建 web 服务器&#xff0c;将 vue 打包生成的 dist 文件夹&#xff0c;托管为静态资…

关于五个问题的思考

关于当初&#xff1a; 博客A[1]的作者认为&#xff1a;“大学的确提供了非常丰富的能力培养机会和广阔的个人发展空间&#xff0c;但归根结底&#xff0c;学习和进步才是大学的主题&#xff0c;荒废其中任何一个都不能让大学生活过得充实而完整。”我对此有着很深的同感。大学是…

记录请求的耗时(拦截器、过滤器、aspect)

记录请求的耗时&#xff08;拦截器、过滤器、aspect&#xff09; 文章前言 记录控制器请求的耗时处理通常有三种实现方式&#xff0c;分别是&#xff1a;过滤器、拦截器、aspect&#xff1b;下文将逐一实现。 1、Filter 过滤器 1.1、方法说明 需要实现 Filter 类&#xff0c;主…

activity与service 使用Handler Messenger数据传递

service 中创建handler /*** 用于接收从客户端传递过来的数据*/ class IncomingHandler extends Handler {Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 6:Log.i("map", "thanks,Service had receiver message from client!"…

前端学习(2744):重读vue电商网站54之配置 HTTPS 服务

为什么要启用 HTTPS 服务&#xff1f; 传统的 HTTP 协议传输的数据都是明文&#xff0c;不安全采用 HTTPS 协议对传输的数据进行了加密处理&#xff0c;可以防止数据被中间人窃取&#xff0c;使用更安全 申请 SSL 证书&#xff08;https://freessl.org&#xff09; 进入 http…

A1078. 逆序对个数

问题描述 在一个数列(a1, a2, a3, …, an)中&#xff0c;对于1<i<j<n&#xff0c;如果ai>aj&#xff0c;则称(i,j)是一个逆序对。如在数列(3, 1, 5, 2)中&#xff0c;有(1,2), (1,4), (3,4)共3个逆序对。给定一个数列&#xff0c;求数列中的逆序对的个数。输入格式…

7、Flutter banner_view 轮播图的使用

7、Flutter banner_view 轮播图的使用 1、前言 实现轮播图&#xff0c;效果如下&#xff1a; 2、实现 将采用 banner_view 实现&#xff1a;资源库地址 2.1、yaml 引入依赖 在 pubspec.yaml 声明需要引用的库&#xff0c;执行命令 flutter packages get 进行拉取即可使用。 ba…

Android 人脸实名验证demo——腾讯人脸核身·云智慧眼

可以说比较容易实现&#xff1a;只需要获取BizToken&#xff0c;再起调腾讯SDK即可 1、首先登录腾讯云平台&#xff0c;申请权限&#xff0c;创建应用 腾讯云&#xff1a; https://cloud.tencent.com/ 2、配置应用信息及实名验证流程设置&#xff0c;下载SDK 不过&#xff0c;…

前端学习(2745):重读vue电商网站55之使用 pm2 管理应用

① 在服务器中安装 pm2&#xff1a;npm i pm2 -g ② 启动项目&#xff1a;pm2 start 脚本 --name 自定义名称 ③ 查看运行项目&#xff1a;pm2 ls ④ 重启项目&#xff1a;pm2 restart 自定义名称 ⑤ 停止项目&#xff1a;pm2 stop 自定义名称 ⑥ 删除项目&#xff1a;pm2 dele…

[JSOI 2015] 子集选取

4475: [Jsoi2015]子集选取 Time Limit: 1 Sec Memory Limit: 512 MBSubmit: 363 Solved: 255[Submit][Status][Discuss]Description Input 输入包含一行两个整数N和K&#xff0c;1<N,K<10^9 Output 一行一个整数&#xff0c;表示不同方案数目模1,000,000,007的值。 Sam…

8、D8: Default interface methods are only supported starting with Android N (--min-api 24): void

8、D8: Default interface methods are only supported starting with Android N (--min-api 24): void 1、错误信息 升级完 Android N 后&#xff0c;有些项目运行起来报错信息大致如下&#xff1a; Default interface methods are only supported starting with Android N (…

No field gDefault in class Landroid/app/ActivityManagerNative

启动未注册activity。8.0系统报错如下&#xff1a; 05-06 10:25:31.312 13973-13973/com.bolex.androidhookstartactivity W/System.err: java.lang.NoSuchFieldException: No field gDefault in class Landroid/app/ActivityManagerNative; (declaration of android.app.Acti…

工作242:关于第二个git仓库提交代码

其实第二个仓库 建立的时候直接取进行 push操作就可以完成 原理一样 可以直接对代码地址进行提交

第0周作业2:博客阅读和思考

第0周作业2&#xff1a;博客阅读和思考 拿到题目的第一眼我是抗拒的&#xff0c;因为从大一开始就一直在回答各种关于“你为什么选择这个专业&#xff1f;”&#xff0c;“毕业后有怎样的打算&#xff1f;”&#xff0c;“想找怎样的工作&#xff1f;”这样的问题。可能在自己还…

11、jeecg 笔记之 界面常用整理 - 方便复制粘贴

11、jeecg 笔记之 界面常用整理 - 方便复制粘贴 1、datagrid 操作按钮&#xff08;按钮样式&#xff09; 操作按钮的显示主要依赖于 <t:dgCol title"操作" field"opt" ></t:dgCol> 标签&#xff0c;如果没有该标签&#xff0c;下方即使加入也…

工作243:name报错

name报错就是name的数值报错

Android 图片压缩,Bitmap旋转,bitmap与byte[]之间相互转换,Bitmap与String互转

频繁setImageBitmap引起oom问题解决方法 Glide.with(gsewmimg).load(getCodeBitmap(response.data.skip, R.mipmap.zhifuicon)).into(gsewmimg);压缩前后。图片大小 2.22MB——>200KB 1、图片压缩方法&#xff1a; Bitmap bitmap; byte[] buff; buff Bitmap2Bytes(bitmap…

第八届蓝桥杯-日期问题

标题&#xff1a;日期问题小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是&#xff0c;这些日期采用的格式非常不统一&#xff0c;有采用年/月/日的&#xff0c;有采用月/日/年的&#xff0c;还有…

9、Flutter 实现 生成二维码

9、Flutter 实现 生成二维码 1、加入依赖 在 pubspec.yaml 中 dependencies 节点下添加&#xff1a; dependencies: qr_flutter: ^1.1.6 2、引入代码 在需要细线二维码的 dart 类中引入依赖代码包&#xff1a; import package:qr_flutter/qr_flutter.dart; 代码部分 import p…