zoukankan      html  css  js  c++  java
  • MyCat不支持毫秒 bug fix

    问题描述:
    mysql jdbc的驱动(mysql-connector-java-5.1.34.jar)设置的服务器的版本号最低是5.6.4才不会截取时间毫秒,但是现在取的是mycat 的版本号 5.5.8-mycat-1.5.3.0-RELEASE-20170927190645 ,而不是实际的服务器版本5.6.21-log,所以时间精度丢失了

    利用反射修改 JDBC4PreparedStatement 属性

    public class JDBC4PreparedStatementWrapper extends JDBC4PreparedStatement {
    
    
        public JDBC4PreparedStatementWrapper(MySQLConnection conn, String catalog) throws SQLException {
            super(conn, catalog);
        }
    
        public JDBC4PreparedStatementWrapper(MySQLConnection conn, String sql, String catalog) throws SQLException {
            super(conn, sql, catalog);
        }
    
        public JDBC4PreparedStatementWrapper(MySQLConnection conn, String sql, String catalog, PreparedStatement.ParseInfo cachedParseInfo) throws SQLException {
            super(conn, sql, catalog, cachedParseInfo);
        }
    
        protected void detectFractionalSecondsSupport() throws SQLException {
            this.serverSupportsFracSecs = this.connection != null;
            System.out.println("=======================>true");
        }
    
    }
    public class MyCatBugFixBean implements InitializingBean {
        private Logger logger = LoggerFactory.getLogger(getClass());
    
        @Override
        public void afterPropertiesSet() throws Exception {
            try {
                Field f1 = PreparedStatement.class.getDeclaredField("JDBC_4_PSTMT_2_ARG_CTOR");
                Field f2 = PreparedStatement.class.getDeclaredField("JDBC_4_PSTMT_3_ARG_CTOR");
                Field f3 = PreparedStatement.class.getDeclaredField("JDBC_4_PSTMT_4_ARG_CTOR");
                f1.setAccessible(true);
                f2.setAccessible(true);
                f3.setAccessible(true);
                Field modifiers1 = f1.getClass().getDeclaredField("modifiers");
                modifiers1.setAccessible(true);
                modifiers1.setInt(f1, f1.getModifiers() & ~Modifier.FINAL);
    
                Field modifiers2 = f2.getClass().getDeclaredField("modifiers");
                modifiers2.setAccessible(true);
                modifiers2.setInt(f2, f2.getModifiers() & ~Modifier.FINAL);
    
                Field modifiers3 = f3.getClass().getDeclaredField("modifiers");
                modifiers3.setAccessible(true);
                modifiers3.setInt(f3, f3.getModifiers() & ~Modifier.FINAL);
    
                f1.set(null, JDBC4PreparedStatementWrapper.class.getConstructor(new Class[]{MySQLConnection.class, String.class}));
                f2.set(null, JDBC4PreparedStatementWrapper.class.getConstructor(new Class[] { MySQLConnection.class, String.class, String.class }));
                f3.set(null, JDBC4PreparedStatementWrapper.class.getConstructor(new Class[] { MySQLConnection.class, String.class, String.class, PreparedStatement.ParseInfo.class }));
    
                modifiers1.setInt(f1, f1.getModifiers() & ~Modifier.FINAL);
                modifiers2.setInt(f2, f2.getModifiers() & ~Modifier.FINAL);
                modifiers3.setInt(f3, f3.getModifiers() & ~Modifier.FINAL);
            } catch (Exception e) {
                // fix bug 异常
                logger.error("fix mycat 不支持毫秒异常", e);
            }
    
        }
    }

     注:
    运行时动态替换类的方法行不通。
    PreparedStatement 拷贝后编译报错,所以运行时动态替换 PreparedStatement#detectFractionalSecondsSupport() 行不通。
    运行时动态替换 JDBC4PreparedStatement 会更改类的定义(重写 detectFractionalSecondsSupport() 方法), JDK 不支持。

    在JDK的规范中运行期重定义一个类必须准循以下原则

    1. 不允许新增、修改和删除成员变量
    2. 不允许新增和删除方法
    3. 不允许修改方法签名

    参考:

    Java反射-修改字段值, 反射修改static final修饰的字段:http://www.cnblogs.com/noKing/p/9038234.html

  • 相关阅读:
    实验6.1
    SOA
    python的镜像包安装
    中文分词:双向匹配最大算法(BI-MM)
    从github中获取代码
    解决文件冲突
    创建分支
    上传本地文件到github
    mysql事务
    查询练习2
  • 原文地址:https://www.cnblogs.com/kevin-yuan/p/10901132.html
Copyright © 2011-2022 走看看