什么是链接?java
链接,是咱们的编程语言与数据库交互的一种方式。咱们常常会听到这么一句话“数据库链接很昂贵“。mysql
有人接受这种说法,殊不知道它的真正含义。所以,下面我将解释它到底是什么。[若是你已经知道了,你能够跳到它的工做原理部分]sql
建立链接的代码片断:数据库
?编程
1数组 2dom 3编程语言 |
String connUrl = "jdbc:mysql://your.database.domain/yourDBname" ; ide Class.forName( "com.mysql.jdbc.Driver" ); url Connection con = DriverManager.getConnection (connUrl); |
当咱们建立了一个Connection对象,它在内部都执行了什么:
1.“DriverManager”检查并注册驱动程序,
2.“com.mysql.jdbc.Driver”就是咱们注册了的驱动程序,它会在驱动程序类中调用“connect(url…)”方法。
3.com.mysql.jdbc.Driver的connect方法根据咱们请求的“connUrl”,建立一个“Socket链接”,链接到IP为“your.database.domain”,默认端口3306的数据库。
4.建立的Socket链接将被用来查询咱们指定的数据库,并最终让程序返回获得一个结果。
为何昂贵?
如今让咱们谈谈为何说它“昂贵“。
若是建立Socket链接花费的时间比实际的执行查询的操做所花费的时间还要更长。
这就是咱们所说的“数据库链接很昂贵”,由于链接资源数是1,它须要每次建立一个Socket链接来访问DB。
所以,咱们将使用链接池。
链接池初始化时建立必定数量的链接,而后从链接池中重用链接,而不是每次建立一个新的。
怎样工做?
接下来咱们来看看它是如何工做,以及如何管理或重用现有的链接。
咱们使用的链接池供应者,它的内部有一个链接池管理器,当它被初始化:
1.它建立链接池的默认大小,好比指定建立5个链接对象,并把它存放在“可用”状态的任何集合或数组中。
例如,代码片断:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
... String connUrl = "jdbc:mysql://your.database.domain/yourDBname" ; String driver = "com.mysql.jdbc.Driver" ; private Map<java.sql.Connection, String> connectionPool = null ; private void initPool() { try { connectionPool = new HashMap<java.sql.Connection, String>(); Class.forName(driver); java.sql.Connection con = DriverManager.getConnection(dbUrl); for ( int poolInd = poolSize; poolInd < 0 ; poolInd++) { connectionPool.put(con, "AVAILABLE" ); } } ... |
2.当咱们调用connectionProvider.getConnection(),而后它会从集合中获取一个链接,固然状态也会更改成“不可用”。
例如,代码片断:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
... public java.sql.Connection getConnection() throws ClassNotFoundException, SQLException { boolean isConnectionAvailable = true ; for (Entry<java.sql.Connection, String> entry : connectionPool.entrySet()) { synchronized (entry) { if (entry.getValue()== "AVAILABLE" ) { entry.setValue( "NOTAVAILABLE" ); return (java.sql.Connection) entry.getKey(); } isConnectionAvailable = false ; } } if (!isConnectionAvailable) { Class.forName(driver); java.sql.Connection con = DriverManager.getConnection(connUrl); connectionPool.put(con, "NOTAVAILABLE" ); return con; } return null ; } ... |
3.当咱们关闭获得的链接,ConnectionProvider是不会真正关闭链接。相反,只是将状态更改成“AVAILABLE”。
例如,代码片断:
?
1 2 3 4 5 6 7 8 9 10 11 12 |
... public void closeConnection(java.sql.Connection connection) throws ClassNotFoundException, SQLException { for (Entry<java.sql.Connection, String> entry : connectionPool.entrySet()) { synchronized (entry) { if (entry.getKey().equals(connection)) { //Getting Back the conncetion to Pool entry.setValue( "AVAILABLE" ); } } } } ... |
基本上链接池的实际工做原理就是这样,但也有可能使用不一样的方式。
如今,你可能有一个问题,咱们是否能够创造咱们本身的链接池机制?
个人建议是使用已经存在的链接池机制,像C3P0,DBCP等。