我是靠谱客的博主 内向小天鹅,最近开发中收集的这篇文章主要介绍java创建mysql驱动_参考Mysql JDBC 驱动源码实现自定义驱动,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、分析Mysql JDBC

平常我们直接以JDBC连接数据库代码基本都如下:

Connection con = null; //创建用于连接数据库的Connection对象

try {

Class.forName("com.mysql.jdbc.Driver");// 加载Mysql数据驱动

con = DriverManager.getConnection(

"jdbc:mysql://localhost:3306/myuser", "root", "root");// 创建数据连接

} catch (Exception e) {

System.out.println("数据库连接失败" + e.getMessage());

}

return con; //返回所建立的数据库连接

1、我们使用Mysql JDBC的时候需要先注册加载驱动:

Class.forName("com.mysql.jdbc.Driver");

利用jdk反射机制的真实注册过程如下:

package com.mysql.jdbc;

import java.sql.SQLException;

public class Driver extends NonRegisteringDriver implements java.sql.Driver {

//执行这个静态代码块

static {

try {//注册mysql实现的驱动类

java.sql.DriverManager.registerDriver(new Driver());

} catch (SQLException E) {

throw new RuntimeException("Can't register driver!");

}

}

public Driver() throws SQLException {

// Required for Class.forName().newInstance()

}

}

接着我们进入java.sql.DriverManager.registerDirver(new Driver())源码:

/**

* Registers the given driver with the DriverManager.

* A newly-loaded driver class should call

* the method registerDriver to make itself

* known to the DriverManager.

*

* @param driver the new JDBC Driver that is to be registered with the

* DriverManager

* @exception SQLException if a database access error occurs

*/

public static synchronized void registerDriver(java.sql.Driver driver)

throws SQLException {

if (!initialized) {

initialize();//初始化

}

DriverInfo di = new DriverInfo();//存储驱动器信息

di.driver = driver;

di.driverClass = driver.getClass();

di.driverClassName = di.driverClass.getName();

drivers.addElement(di);//注册到驱动集合

println("registerDriver: " + di);

}

再进行一些细节的初始化工作驱动就注册加载完成了,有兴趣可自己看源码。接着我们如何创建连接。

2、创建数据连接

Drivermanager.getConnection(url,name,password)

我们进去看看这个方法的实际执行过程

public static synchronized Connection getConnection(String url,

String user, String password) throws SQLException {

java.util.Properties info = new java.util.Properties();

// Gets the classloader of the code that called this method, may

// be null.

ClassLoader callerCL = DriverManager.getCallerClassLoader();

if (user != null) {

info.put("user", user);//获取用户名

}

if (password != null) {

info.put("password", password);//获取密码

}

return (getConnection(url, info, callerCL));//①

}

接着我们再看①处的代码执行过程

// Worker method called by the public getConnection() methods.

private static synchronized Connection getConnection(

String url, java.util.Properties info, ClassLoader callerCL) throws SQLException {

/*

* When callerCl is null, we should check the application's

* (which is invoking this class indirectly)

* classloader, so that the JDBC driver class outside rt.jar

* can be loaded from here.

*/

if(callerCL == null) {

callerCL = Thread.currentThread().getContextClassLoader();

}

if(url == null) {

throw new SQLException("The url cannot be null", "08001");

}

println("DriverManager.getConnection("" + url + "")");

if (!initialized) {

initialize();

}

// Walk through the loaded drivers attempting to make a connection.

// Remember the first exception that gets raised so we can reraise it.

SQLException reason = null;

for (int i = 0; i < drivers.size(); i++) {//遍历驱动集合

DriverInfo di = (DriverInfo)drivers.elementAt(i);

// If the caller does not have permission to load the driver then

// skip it.

if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) {

println(" skipping: " + di);

continue;

}

try {

println(" trying " + di);

//在注册的驱动集合中得到相应的连接 ①

Connection result = di.driver.connect(url, info);

if (result != null) {

// Success!

println("getConnection returning " + di);

return (result);

}

} catch (SQLException ex) {

if (reason == null) {

reason = ex;

}

}

}

所以上面的①处的代码实际执行的就是com.mysql.jdbc.Driver的connect(url,info)方法

public java.sql.Connection connect(String url, Properties info)

throws SQLException {

if (url != null) {

if (StringUtils.startsWithIgnoreCase(url, LOADBALANCE_URL_PREFIX)) {//负载均衡的配置

return connectLoadBalanced(url, info);

} else if (StringUtils.startsWithIgnoreCase(url,

REPLICATION_URL_PREFIX)) {//复制

return connectReplicationConnection(url, info);

}

}

Properties props = null;

if ((props = parseURL(url, info)) == null) {

return null;

}

if (!"1".equals(props.getProperty(NUM_HOSTS_PROPERTY_KEY))) {

return connectFailover(url, info);

}

try {//初始化链接

Connection newConn = com.mysql.jdbc.ConnectionImpl.getInstance(

host(props), port(props), props, database(props), url);

return newConn;

} catch (SQLException sqlEx) {

// Don't wrap SQLExceptions, throw

// them un-changed.

throw sqlEx;

} catch (Exception ex) {

SQLException sqlEx = SQLError.createSQLException(Messages

.getString("NonRegisteringDriver.17") //$NON-NLS-1$

+ ex.toString()

+ Messages.getString("NonRegisteringDriver.18"), //$NON-NLS-1$

SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE, null);

sqlEx.initCause(ex);

throw sqlEx;

}

}

二、自定义驱动

Class.forName("org.tinygroup.dbrouterjdbc3.jdbc.TinyDriver");

conn = DriverManager.getConnection("jdbc:dbrouter://aggregate", "ljf",

"123456");

1、注册加载驱动

public class TinyDriver implements Driver {

private RouterManager manager;

private Logger logger = LoggerFactory.getLogger(TinyDriver.class);

static {

try {

DriverManager.registerDriver(new TinyDriver());//注册驱动

} catch (SQLException E) {

throw new RuntimeException("Can't register driver!");

}

}

public TinyDriver() {

manager = RouterManagerBeanFactory.getManager();

}

我们再来看看如何获得数据连接

public Connection connect(String url, Properties info) throws SQLException {

if (!acceptsURL(url)) {

return null;

}

String routerName = url.substring("jdbc:dbrouter://".length());

Router router = manager.getRouter(routerName);

String user = info.getProperty("user");

String password = info.getProperty("password");

if (!user.equals(router.getUserName())) {

logger.logMessage(LogLevel.ERROR,

"username {0} and {1} not equals", user,

router.getUserName());

throw new SQLException("username not equals");

}

if (!password.equals(router.getPassword())) {

logger.logMessage(LogLevel.ERROR,

"password {0} and {1} not equals", password,

router.getPassword());

throw new SQLException("password not equals");

}

return new TinyConnection(routerName);

}

通过以上的分析我们可以通过对JDBC进行包装就能做到多数据源,甚至可以在JDBC层上进行分库分表。这样做的好处是对于上层开发人员是透明的。

最后

以上就是内向小天鹅为你收集整理的java创建mysql驱动_参考Mysql JDBC 驱动源码实现自定义驱动的全部内容,希望文章能够帮你解决java创建mysql驱动_参考Mysql JDBC 驱动源码实现自定义驱动所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(66)

评论列表共有 0 条评论

立即
投稿
返回
顶部