Mybatis拦截器,修改Date类型数据。设置毫秒为0
1:背景
Mysql自动将datetime类型的毫秒数四舍五入,比如代码中传入的Date类型的数据值为 2021.03.31 23:59:59.700 到数据库 2021.04.01 00:00:00.0。
对数据准确性造成影响。
2:解决方案
存入数据库之前去除毫秒数,终极方案使用mybatis拦截器,对insert和update类型的操作修改Date类型的参数值,去除毫秒数。
3:源代码
package com.hyx.study.commom.aop.interceptor; import com.hyx.study.commom.util.JacksonUtils;
import com.xkzhangsan.time.calculator.DateTimeCalculatorUtil;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.stereotype.Component; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.Statement;
import java.util.*; /**
* @author huangyaxiong
* @version 1.0
* @description: 利用mybatis拦截器,修改所有得Date类型得参数省略毫秒数
* @date 2022-09-06 9:59
*/
@Intercepts({
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
})
@Component
public class MybatisDateInterceptor implements Interceptor { private static Logger logger = LoggerFactory.getLogger(MybatisDateInterceptor.class);
/**
* 获取sql语句
* @param invocation
* @return
*/
public static String getSqlByInvocation(Invocation invocation) {
final Object[] args = invocation.getArgs();
MappedStatement ms = (MappedStatement) args[0];
Object parameterObject = args[1];
BoundSql boundSql = ms.getBoundSql(parameterObject);
return boundSql.getSql();
}
@Override
public Object intercept(Invocation invocation) throws InvocationTargetException, IllegalAccessException {
String processSql = getSqlByInvocation(invocation);
logger.info("原始sql==>{}",processSql);
Object[] args = invocation.getArgs();
for(Object arg:args){
if(arg instanceof MappedStatement){
MappedStatement mappedStatement = (MappedStatement) arg;
SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
logger.info("操作类型==>{}",sqlCommandType);
if(sqlCommandType == SqlCommandType.INSERT || sqlCommandType == SqlCommandType.UPDATE){
continue;
}else{
break;
}
}else if(arg instanceof Map){
//如果是map,有两种情况:(1)使用@Param多参数传入,由Mybatis包装成map。(2)原始传入Map
logger.info("这是一个包装过的类型!");
Map map=(Map)arg;
for (Object obj : map.values()){
tranDateProperty(obj);
}
}else {
tranDateProperty(arg);
}
}
return invocation.proceed ();
} /**
* @description: 修改对象中对的Date类型并且舍弃毫秒数
* @param arg
* @author 'huangyaxiong'
* @date: 2022-09-06 11:16
*/
private static void tranDateProperty(Object arg){
try{
Field[] declaredFields = arg.getClass().getDeclaredFields();
for(Field field:declaredFields){
Class<?> type = field.getType();
if(Date.class == field.getType()){
field.setAccessible(true);
System.out.println(type);
String name = field.getName();
Object temp = field.get(arg);
if(temp != null){
Date value = (Date) field.get(arg);
System.out.println(value.getTime());
Date date = DateTimeCalculatorUtil.reduceAccuracyToSecond(value);
System.out.println(date.getTime());
field.set(arg,date);
// BeanUtils.setProperty(arg,name,date);
}
}
}
}catch (Exception e){
logger.error("日期数据转换出现了异常==>data:{}==>e:{}", JacksonUtils.object2Json(arg),e);
}
} @Override
public Object plugin(Object target) {
// 当目标类是StatementHandler类型时,才包装目标类,否者直接返回目标本身,减少目标被代理的次数
return Plugin.wrap(target, this);
// return null;
} @Override
public void setProperties(Properties properties) { }
}
Mybatis拦截器,修改Date类型数据。设置毫秒为0的更多相关文章
- mybatis拦截器 修改mybatis返回结果集中的字段的值
项目中使用了shardingJDBC,业务库做了分库,公共库没在一起,所以导致做码值转换的时候,需要在实现类里面做转码,重复的代码量大,故考虑用mybatis拦截器,将码值转换后再做返回给实现类. ...
- 数据权限管理中心 - 基于mybatis拦截器实现
数据权限管理中心 由于公司大部分项目都是使用mybatis,也是使用mybatis的拦截器进行分页处理,所以技术上也直接选择从拦截器入手 需求场景 第一种场景:行级数据处理 原sql: select ...
- Mybatis拦截器实现分页
本文介绍使用Mybatis拦截器,实现分页:并且在dao层,直接返回自定义的分页对象. 最终dao层结果: public interface ModelMapper { Page<Model&g ...
- 玩转SpringBoot之整合Mybatis拦截器对数据库水平分表
利用Mybatis拦截器对数据库水平分表 需求描述 当数据量比较多时,放在一个表中的时候会影响查询效率:或者数据的时效性只是当月有效的时候:这时我们就会涉及到数据库的分表操作了.当然,你也可以使用比较 ...
- Mybatis拦截器实现原理深度分析
1.拦截器简介 拦截器可以说使我们平时开发经常用到的技术了,Spring AOP.Mybatis自定义插件原理都是基于拦截器实现的,而拦截器又是以动态代理为基础实现的,每个框架对拦截器的实现不完全相同 ...
- MyBatis拦截器原理探究
MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis 允 ...
- 基于Spring和Mybatis拦截器实现数据库操作读写分离
首先需要配置好数据库的主从同步: 上一篇文章中有写到:https://www.cnblogs.com/xuyiqing/p/10647133.html 为什么要进行读写分离呢? 通常的Web应用大多数 ...
- 通过spring抽象路由数据源+MyBatis拦截器实现数据库自动读写分离
前言 之前使用的读写分离的方案是在mybatis中配置两个数据源,然后生成两个不同的SqlSessionTemplate然后手动去识别执行sql语句是操作主库还是从库.如下图所示: 好处是,你可以人为 ...
- 【公众号转载】MyBatis拦截器原理探究
MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis 允 ...
- 详解Mybatis拦截器(从使用到源码)
详解Mybatis拦截器(从使用到源码) MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能. 本文从配置到源码进行分析. 一.拦截器介绍 MyBatis 允许你在 ...
随机推荐
- 09 安装虚拟机:Ubuntu Server 20.04
09 安装虚拟机:Ubuntu Server 20.04 9.1 取得安装映像档 9.2 建立虚拟机客体 请至Proxmox VE管理界面点选右上方的[建立VM],来到建立虚拟机客体的引导程序.引导程 ...
- Spring的注入方式
Spring的注入方式 目录 Spring的注入方式 一.前言 二.常见的三种注入方式 2.1.Field注入 2.2 构造器注入 2.3 setter注入 三.构造器注入的好处 四.答疑 一.前言 ...
- Vue2安装less版本过高问题,需要降级
安装指定less版本解决: -D: 本地安装 -g: 全局安装 npm install less@3.9.0 less-loader@5.0.0 -D
- 零基础小白速成python?有了这本书你还在担心什么?
<Python编程快速上手>书籍PDF高清版免费下载地址 提取码:bc9h 内容简介 · · · · · · 如今,人们面临的大多数任务都可以通过编写计算机软件来完成.Python是一种 ...
- 启动项目报错org.yaml.snakeyaml.scanner.ScannerException: while scanning for the next token found character ‘@‘
报错信息:org.yaml.snakeyaml.scanner.ScannerException: while scanning for the next token found character ...
- FMC子卡设计资料原理图:FMC177-基于AD9361的双收双发射频FMC子卡
FMC177-基于AD9361的双收双发射频FMC子卡 一.板卡介绍 FMC177射频模块分别包含两个接收通道与发射通道,其频率可覆盖达到70MHz~6GHz,AD9361芯片提供具有成本效益的实验平 ...
- 225-基于XCVU440T的多核处理器多输入芯片验证板卡
225-基于XCVU440T的多核处理器多输入芯片验证板卡 基于XCVU440T的多核处理器多输入芯片验证板卡 一.板卡概述 本板卡系我司自主研发的基于6U CPCI处理板,适用于多核处理器多输入 ...
- java链接pg数据库remaining connection slots are reserved for non-replication superuser connections问题
最近遇到链接pg数据库报错:remaining connection slots are reserved for non-replication superuser connections.百度说, ...
- node版本和用的包不兼容问题,头疼
经常遇到node版本和包不兼容的问题,在茫茫大海中学习的时候发现一个nvm,可以随时切换node版本,简直不要太开心,附上流程 环境windows 首先:下载一个nvm包https://github. ...
- 076_Master Detail 与Lookup