概述
一、分析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 驱动源码实现自定义驱动所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复