程澈 2020-04-15 17:28 采纳率: 100%
浏览 1347
已采纳

springboot测试动态加载mysql不同版本驱动jar,总调用的是pom中的驱动jar版本

最近在测试用springboot的web项目,做个各个数据库(mysql、oracle,sqlserver,postgresql)的数据源管理,用URLClassLoader动态加载不同版本的驱动jar包,就mysql来说 每次conn.getMetaData().getDriverVersion()发现连接使用的驱动版本是pom中项目的版本,并没有使用我在URL中给的本地驱动,苦恼

package com.legends.ori.service.type;

import com.legends.ori.service.tool.JarLoader;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;

public class MycatMulitJdbcVersionTest {

  private static final String JDBC_URL = "jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai";
  private static final String USER = "root";
  private static final String PASSWORD = "root";
  private static final Map<String, String> jdbcVersionMap = new HashMap<String, String>();
  private static final Map<String, Driver> tmpDriverMap = new HashMap<String, Driver>();

  // 动态加载jdbc驱动
  private static void dynamicLoadJdbc(String mysqlJdbcFile) throws Exception {
    File jarPath = new File("D:\\Idea-Projects\\raytracing\\driver\\mysql\\" + mysqlJdbcFile);
    URL u = jarPath.toURI().toURL();
    String classname = jdbcVersionMap.get(mysqlJdbcFile);
    URLClassLoader ucl = new URLClassLoader(new URL[]{u},Thread.currentThread().getContextClassLoader());
    //ucl.loadClass(classname).newInstance();
    Driver d = (Driver) ucl.loadClass(classname).newInstance();
    DriverShim driver = new DriverShim(d);
    DriverManager.registerDriver(driver);
    tmpDriverMap.put(mysqlJdbcFile, driver);
  }

  // 每一次测试完卸载对应版本的jdbc驱动
  private static void dynamicUnLoadJdbc(String mysqlJdbcFile) throws SQLException {
    DriverManager.deregisterDriver(tmpDriverMap.get(mysqlJdbcFile));
  }

  // 进行一次测试
  private static void testOneVersion(String mysqlJdbcFile) {

    System.out.println("start test mysql jdbc version : " + mysqlJdbcFile);

    try {
      dynamicLoadJdbc(mysqlJdbcFile);
    } catch (Exception e1) {
      e1.printStackTrace();
    }

    Connection conn = null;
    try {
      conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);
      System.out.println(conn.getMetaData().getDriverVersion());
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
      if (conn != null) {
        try {
          conn.close();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }
    }

    try {
      dynamicUnLoadJdbc(mysqlJdbcFile);
    } catch (SQLException e) {
      e.printStackTrace();
    }

    System.out.println("end !!!");
    System.out.println();
  }

  public static void main(String[] args) {

    jdbcVersionMap.put("mysql-connector-java-5.1.48.jar", "com.mysql.jdbc.Driver");
    jdbcVersionMap.put("mysql-connector-java-8.0.17.jar", "com.mysql.cj.jdbc.Driver");

    for (String mysqlJdbcFile : jdbcVersionMap.keySet()) {
      testOneVersion(mysqlJdbcFile);
    }

  }

}

class DriverShim implements Driver {
  private Driver driver;

  DriverShim(Driver d) {
    this.driver = d;
  }

  public boolean acceptsURL(String u) throws SQLException {
    return this.driver.acceptsURL(u);
  }

  public Connection connect(String u, Properties p) throws SQLException {
    return this.driver.connect(u, p);
  }

  @Override
  public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
    return this.driver.getPropertyInfo(url, info);
  }

  @Override
  public int getMajorVersion() {
    return this.driver.getMajorVersion();
  }

  @Override
  public int getMinorVersion() {
    return this.driver.getMinorVersion();
  }

  @Override
  public boolean jdbcCompliant() {
    return this.driver.jdbcCompliant();
  }

  @Override
  public Logger getParentLogger() throws SQLFeatureNotSupportedException {
    return this.driver.getParentLogger();
  }
}

测试结果:
1.pom中不添加mysql-connector-java8.0.16的版本,测试OK
图片说明

2.pom中添加mysql-connector-java8.0.16的版本,测试使用的驱动版本就变成了8.0.16,我在URLClassLoader添加驱动的无效
图片说明

求求大神解救

  • 写回答

3条回答 默认 最新

  • 毕小宝 博客专家认证 2020-04-16 08:10
    关注

    我推测可能是 pom.xml 有自己的 jdbc jar 包的时候,没有执行过 DriverManager.deregisterDriver 这个操作。
    测试代码加上 pom.xml 依赖的版本试试,这样应该会卸载默认版本:

    jdbcVersionMap.put("mysql-connector-java-8.0.16.jar", "com.mysql.jdbc.Driver");
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥100 有人会搭建GPT-J-6B框架吗?有偿
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名