本文共 7554 字,大约阅读时间需要 25 分钟。
JDK版本1.8
maven依赖
mysql mysql-connector-java 6.0.5
数据库版本mysql 5.5+
//1.获取一个Connection //参数info中至少包含user,password这两个参数//参数url中可以使用 ?key=value& 增加参数,如果key与info中重复,由JDBC的实现决定优先级//如果给定的url不符合此驱动,则返回nullConnection connect(String url, java.util.Properties info)//2.是否是此驱动可接受的URLboolean acceptsURL(String url)
第三方的JDBC Driver必须实现java.sql.Driver接口,Driver实现类的静态代码块static{}
中应该初始化它本身,并注册到java.sql.DriverManager中。
mysql中的Driver6.0.5的实现类 位于package com.mysql.cj.jdbc
。为:
//NonRegisteringDriver中包含所有驱动的可执行方法,但没有包含`static{}`public class NonRegisteringDriver implements java.sql.Driver//包含`static{}`,会自动注册到DriverManagerpublic class Driver extends NonRegisteringDriver implements java.sql.Driver
仅比NonRegisteringDriver 多了一个静态代码块,在类加载后执行,从而自动注册到DriverManager
static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } }
这个接口实现了java.sql.Driver的所有方法,测试用例如下
public class DriverTest { public static void main(String[] args) throws SQLException { String mysqlUrl="jdbc:mysql://localhost/apple"; String otherUrl="jdbc:postgres://localhost/apple"; Properties properties=new Properties(); properties.put("user","pig"); properties.put("password","123456"); properties.put("serverTimezone","UTC");//serverTimezone是mysql-jdbc6+ 必须的参数 properties.put("useSSL","false");//MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL attr java.sql.Driver driver = new com.mysql.cj.jdbc.NonRegisteringDriver(); Connection connect = driver.connect(mysqlUrl, properties); System.out.println("conn : "+connect); boolean isAccepts1 = driver.acceptsURL(mysqlUrl); System.out.println("isAccepts1: "+isAccepts1); boolean isAccepts2 = driver.acceptsURL(otherUrl); System.out.println("isAccepts2: "+isAccepts2); DriverPropertyInfo[] propertyInfo = driver.getPropertyInfo(mysqlUrl, properties); System.out.println(propertyInfo.length);//mysql-driver中所有可用属性 System.out.println("MajorVersion:"+driver.getMajorVersion()); System.out.println("MinorVersion:"+driver.getMinorVersion()); //是否合乎jdbc规范-驱动需要完整地支持SQL92规范 System.out.println("jdbcCompliant:"+driver.jdbcCompliant()); //since JDBC 4.1, JDK 1.7 //System.out.println("Logger:"+driver.getParentLogger()); }}
输出结果如下
conn : com.mysql.cj.jdbc.ConnectionImpl@53bd815bisAccepts1: trueisAccepts2: false189MajorVersion:6MinorVersion:0jdbcCompliant:false
从JDBC4开始(jdk1.6+),DriverManager加载时可以自动加载类路径中的驱动,静态代码块
static { loadInitialDrivers();//加载路径中的驱动 println("JDBC DriverManager initialized"); }
加载过程如下
//根据url,user,password获取连接public static Connection getConnection(String url, String user, String password) //根据url获取驱动public static Driver getDriver(String url)//注册一个驱动public static synchronized void registerDriver(java.sql.Driver driver)//反注册一个驱动public static synchronized void deregisterDriver(Driver driver)//获取所有驱动的Enumerationpublic static java.util.EnumerationgetDrivers()//*加载路径下的所有驱动private static void loadInitialDrivers()
测试用例如下:
public class ManagerTest { public static void main(String[] args) throws SQLException { String mysqlUrl = "jdbc:mysql://localhost/apple?serverTimezone=UTC&useSSL=false"; Connection connection = DriverManager.getConnection(mysqlUrl, "pig", "123456"); System.out.println("-------get Connection by url-----"); System.out.println(connection); Driver driver = DriverManager.getDriver(mysqlUrl); System.out.println("-------get Driver by url-----"); System.out.println(driver); EnumerationdriverEnumeration = DriverManager.getDrivers(); System.out.println("-------All Drivers-----"); while (driverEnumeration.hasMoreElements()) { System.out.println(driverEnumeration.nextElement()); } }}
输出结果
-------get Connection by url-----com.mysql.cj.jdbc.ConnectionImpl@48cf768c-------get Driver by url-----com.mysql.cj.jdbc.Driver@49476842-------All Drivers-----com.mysql.cj.jdbc.Driver@49476842org.postgresql.Driver@4f023edb
源码如下
private static void loadInitialDrivers() { String drivers; //1.获取环境变量中jdbc.drivers的列表 try { drivers = AccessController.doPrivileged(new PrivilegedAction() { public String run() { return System.getProperty("jdbc.drivers"); } }); } catch (Exception ex) { drivers = null; } //使用java.util.ServiceLoader#load获取META-INFI/services/文件夹下文件中包含的类 AccessController.doPrivileged(new PrivilegedAction () { public Void run() { ServiceLoader loadedDrivers = ServiceLoader.load(Driver.class); Iterator driversIterator = loadedDrivers.iterator(); try{ //依次加载所有驱动 while(driversIterator.hasNext()) { driversIterator.next(); } } catch(Throwable t) { // Do nothing } return null; } }); println("DriverManager.initialize: jdbc.drivers = " + drivers); if (drivers == null || drivers.equals("")) { return; } String[] driversList = drivers.split(":"); println("number of Drivers:" + driversList.length); //依次加载环境变量中的驱动 for (String aDriver : driversList) { try { println("DriverManager.Initialize: loading " + aDriver); Class.forName(aDriver, true, ClassLoader.getSystemClassLoader()); } catch (Exception ex) { println("DriverManager.Initialize: load failed: " + ex); } }}
使用java.util.ServiceLoader#load获取META-INFI/services/xxxxx文件中包含的类,xxx为接口的全名
示例代码:
com.mysql.cj.jdbc.MysqlDataSource dataSource=new com.mysql.cj.jdbc.MysqlDataSource();dataSource.setUrl("jdbc:mysql://localhost/apple?serverTimezone=UTC&useSSL=false");dataSource.setUser("pig");dataSource.setPassword("123456");System.out.println(dataSource.getConnection());System.out.println(dataSource.getDatabaseName());//.....其他方法
详见我的另一篇博客
Connection表示于数据库的一个连接。
Connection可以通过Driver,DriverManager,DataSource获取,也可以直接使用new来生成。 下图是mysql-connector-java6.05的部分实现ConnectionImpl是一个基本的Connection实现。
LoadBalancedMySQLConnection具有负载均衡的功能。com.mysql.cj.jdbc.ConnectionImpl有一个构造器ConnectionImpl(HostInfo hostInfo)
是public的。
转载地址:http://vshgi.baihongyu.com/