【JDBC4.2】二、获取Connection

2017-01-13 15:05:44来源:csdn作者:u011179993人点击

JDK版本

1.8

使用的依赖

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.5</version>
</dependency>

数据库版本

mysql 5.5+1 Driver接口1.1 java.sql.Driver接口主要方法 ://1.获取一个Connection
//参数info中至少包含user,password这两个参数
//参数url中可以使用 ?key=value& 增加参数,如果key与info中重复,由JDBC的实现决定优先级
//如果给定的url不符合此驱动,则返回null
Connection connect(String url, java.util.Properties info)//2.是否是此驱动可接受的URL
boolean acceptsURL(String url)

第三方的JDBC Driver必须实现java.sql.Driver接口,Driver实现类的静态代码块static{}中应该初始化它本身,并注册到java.sql.DriverManager中。

1.2 mysql中的实现

mysql中的Driver6.0.5的实现类 位于package com.mysql.cj.jdbc。为:

//NonRegisteringDriver中包含所有驱动的可执行方法,但没有包含`static{}`
public class NonRegisteringDriver implements java.sql.Driver
//包含`static{}`,会自动注册到DriverManager
public class Driver extends NonRegisteringDriver implements java.sql.Driver
1.3 com.mysql.cj.jdbc.Driver

仅比NonRegisteringDriver 多了一个静态代码块,在类加载后执行,从而自动注册到DriverManager

static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}1.4 com.mysql.cj.jdbc.NonRegisteringDriver

这个接口实现了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 attrjava.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@53bd815b
isAccepts1: true
isAccepts2: false
189
MajorVersion:6
MinorVersion:0
jdbcCompliant:false2DriverManager

从JDBC4开始(jdk1.6+),DriverManager加载时可以自动加载类路径中的驱动,静态代码块

static {
loadInitialDrivers();//加载路径中的驱动
println("JDBC DriverManager initialized");
}

加载过程如下

2.1DriverManager主要方法//根据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)//获取所有驱动的Enumeration
public static java.util.Enumeration<Driver> getDrivers()//*加载路径下的所有驱动
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);Enumeration<Driver> driverEnumeration = 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@49476842
org.postgresql.Driver@4f023edb2.2 loadInitialDrivers()分析

源码如下

private static void loadInitialDrivers() {
String drivers;
//1.获取环境变量中jdbc.drivers的列表
try {
drivers = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty("jdbc.drivers");
}
});
} catch (Exception ex) {
drivers = null;
}//使用java.util.ServiceLoader#load获取META-INFI/services/文件夹下文件中包含的类
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
Iterator<Driver> 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为接口的全名

3 DataSource

1. javax.sql.DataSource是一个比DriverManger更好的获取数据库连接的方式,它通常被注册到JNDI中。使用者通过JNDI获取javax.sql.DataSource实例。 2. javax.sql.CommonDataSource是javax.sql.DataSource的父接口,它的子接口还包括包含连接池ConnectionPoolDataSource和分布式事务的XADataSource。 3. javax.sql.DataSource仅用来给用户提供了数据库连接,没有setUrl(),setUse()r,setPassword()等方法,需要由实现提供。

3.1 mysql中的DataSource实现 com.mysql.cj.jdbc.MysqlDataSource 作为基本的实现,使用较多
com.mysql.cj.fabric.jdbc.FabricMySQLDataSource可以使用 mysql Fabric功能

MySQL Fabric是什么? MySQL Fabric能“组织”多个MySQL数据库,是应用系统将大于几TB的表分散到多个数据库,即数据分片(Data Shard)。在同一个分片内又可以含有多个>数据库,并且由Fabric自动挑选一个适合的作为主数据库,其他的数据库配置成从数据库,来做主从复制。在主数据库挂掉时,从各个从数据库中挑选一个提>升为主数据库。
com.mysql.cj.jdbc.MysqlDataSource

示例代码:

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());
//.....其他方法3.2 SpringJDBC中的DataSource实现

详见我的另一篇博客 《SpringJDBC中的DataSource的实现》

4 Connection接口

Connection表示于数据库的一个连接。 Connection可以通过Driver,DriverManager,DataSource获取,也可以直接使用new来生成。 下图是mysql-connector-java6.05的部分实现

ConnectionImpl是一个基本的Connection实现。 LoadBalancedMySQLConnection具有负载均衡的功能。

com.mysql.cj.jdbc.ConnectionImpl有一个构造器ConnectionImpl(HostInfo hostInfo) 是public的。


最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台