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的更多相关文章

  1. mybatis拦截器 修改mybatis返回结果集中的字段的值

    项目中使用了shardingJDBC,业务库做了分库,公共库没在一起,所以导致做码值转换的时候,需要在实现类里面做转码,重复的代码量大,故考虑用mybatis拦截器,将码值转换后再做返回给实现类.   ...

  2. 数据权限管理中心 - 基于mybatis拦截器实现

    数据权限管理中心 由于公司大部分项目都是使用mybatis,也是使用mybatis的拦截器进行分页处理,所以技术上也直接选择从拦截器入手 需求场景 第一种场景:行级数据处理 原sql: select ...

  3. Mybatis拦截器实现分页

    本文介绍使用Mybatis拦截器,实现分页:并且在dao层,直接返回自定义的分页对象. 最终dao层结果: public interface ModelMapper { Page<Model&g ...

  4. 玩转SpringBoot之整合Mybatis拦截器对数据库水平分表

    利用Mybatis拦截器对数据库水平分表 需求描述 当数据量比较多时,放在一个表中的时候会影响查询效率:或者数据的时效性只是当月有效的时候:这时我们就会涉及到数据库的分表操作了.当然,你也可以使用比较 ...

  5. Mybatis拦截器实现原理深度分析

    1.拦截器简介 拦截器可以说使我们平时开发经常用到的技术了,Spring AOP.Mybatis自定义插件原理都是基于拦截器实现的,而拦截器又是以动态代理为基础实现的,每个框架对拦截器的实现不完全相同 ...

  6. MyBatis拦截器原理探究

    MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis 允 ...

  7. 基于Spring和Mybatis拦截器实现数据库操作读写分离

    首先需要配置好数据库的主从同步: 上一篇文章中有写到:https://www.cnblogs.com/xuyiqing/p/10647133.html 为什么要进行读写分离呢? 通常的Web应用大多数 ...

  8. 通过spring抽象路由数据源+MyBatis拦截器实现数据库自动读写分离

    前言 之前使用的读写分离的方案是在mybatis中配置两个数据源,然后生成两个不同的SqlSessionTemplate然后手动去识别执行sql语句是操作主库还是从库.如下图所示: 好处是,你可以人为 ...

  9. 【公众号转载】MyBatis拦截器原理探究

    MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能.那么拦截器拦截MyBatis中的哪些内容呢? 我们进入官网看一看: MyBatis 允 ...

  10. 详解Mybatis拦截器(从使用到源码)

    详解Mybatis拦截器(从使用到源码) MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能. 本文从配置到源码进行分析. 一.拦截器介绍 MyBatis 允许你在 ...

随机推荐

  1. LOJ3075 「2019 集训队互测 Day 3」组合数求和

    题意: 令 \(f(j)=\sum\limits_{i=0}^{n-1}\dbinom{id}{j}\) ,对于 \(0\le j <m\) ,分别求出 \(f(j)\) .答案对 \(M\) ...

  2. 区块链leveldb数据库安装

    一.首先,需要在电脑上安装boost库. 下载地址在这里,下载压缩包之后解压,Index of main/release/1.79.0/source. 解压完成后在解压好的文件夹里面进入cmd,之后运 ...

  3. mybatis_pagehelper_selectOne的SQL语句被莫名的增加分页相关设置,暂定解决办法

    在使用mybatis.以及其分页插件pagehelper时,原本的一个selectOne的sql语句被莫名(原因未知)的加上了分页相关,引起如下异常: exception is org.apache. ...

  4. golang运算符

    1.算术运算符 算术运算符有:+,-,*,/,%,++,-- 1.1 加号(+) 表示正数 数字相加 字符串拼接 package main import ( "fmt" ) fun ...

  5. GitHub访问缓慢

    参考:https://www.cnblogs.com/liuchao888/p/11733996.html

  6. Less 1-3

    LESS-1 首先确认一下是否存在注入,加上?id=1,能够显示数据,然后加一个',出现报错,这样就说明存在注入点.接下来进行报错注入. 输入 ' and updatexml(1,concat(0x7 ...

  7. ETCD 实现服务发现讲解

    租约:具有时间有效期,键绑定到租约后,当租约到期失效,绑定到的租约的键也会被删除. 创建租约 etcdctl lease grant 600 lease 694d81f509b7940a grante ...

  8. windows文件夹被占用的解除办法

    1.第一步,按下快捷键组合 ctrl alt del,打开任务管理器窗口,点击上方菜单栏中的性能选项. 2. 第二步,在性能页面下找到打开资源监视器按钮并点击. 3. 第三步,进入资源监视器页面,点击 ...

  9. go 编程基础学习笔记

    dos 命令 2023-01-26 1.切换盘符 只要输入 c: d: e: 等即可 2.显示目录详细内容 dir 3.切换目录 cd 留意 一个点 . 代表当前目录, 两个点.. 代表上一级目录 4 ...

  10. Win10在线升级Win11

    下载微软官方在线升级工具,直接一键在线升级 https://www.microsoft.com/zh-cn/software-download/windows11/ 右键菜单一键恢复win10风格,管 ...