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,因此時間精度丟失了html

 

利用反射修改 JDBC4PreparedStatement 屬性java

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 不支持。mysql

在JDK的規範中運行期重定義一個類必須準循如下原則git

  1. 不容許新增、修改和刪除成員變量
  2. 不容許新增和刪除方法
  3. 不容許修改方法簽名

 

 

參考:github

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

相關文章
相關標籤/搜索