在這裏所謂的數據庫鏈接是指經過網絡協議與數據庫服務之間創建的TCP鏈接。一般,與數據庫服務進行通訊的網絡協議無需由應用程序自己實現。html
緣由有三:java
正由於如此,因此現實的實現方式是:mysql
首先,定義網絡協議標準,這樣只要支持這個標準協議的數據庫就可使用相應的客戶端與之通訊。git
其次,將實現這個標準協議的客戶端獨立爲一個通訊庫,這樣只須要在應用程序中使用這個通訊組件庫就能夠方便地實現與數據庫進行交互。github
一般,咱們將實現了網絡協議的通訊庫稱之爲數據庫驅動程序。固然,對於不一樣的編程語言,須要對應編寫相應的數據庫驅動實現。以與關係型數據庫通訊爲例,在Java中實現的驅動程序爲JDBC,Python中的驅動程序爲MySQLdb。sql
因爲經過TCP與數據庫創建網絡鏈接的代價很是高昂,並且耗時(TCP創建鏈接須要「三次握手」,斷開鏈接須要「四次握手」)。因此在實踐中一般不直接單獨使用鏈接進行數據庫操做,而是使用鏈接池的方式,這主要是處於如下兩方面的考慮:數據庫
在Java中使用得比較流行的數據庫鏈接池主要有:DBCP,c3p0,druid。
另外,不論使用什麼鏈接池,低層都是使用JDBC鏈接,即:在應用程序中都須要加載JDBC驅動程序。
編程
Druid:服務器
概述:druid:阿里出品,淘寶和支付寶專用數據庫鏈接池,支持全部JDBC兼容的數據庫,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等。網絡
Druid是Java語言中最好的數據庫鏈接池,Druid可以提供強大的監控和擴展功能,是一個可用於大數據實時查詢和分析的高容錯、高性能的開源分佈式系統,尤爲是當發生代碼部署、機器故障以及其餘產品系統遇到宕機等狀況時,Druid仍可以保持100%正常運行。
主要特點:爲分析監控設計;快速的交互式查詢;高可用;可擴展;Druid是一個開源項目,源碼託管在github上。
Druid針對Oracle和MySql作了特別優化。
依賴Jar包:不分版本號
● druid-1.1.5.jar
● mysql-connector-java-8.0.14.jar
DruidDataSource dataSource = new DruidDataSource(); //獲取驅動 dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); //創建鏈接 dataSource.setUrl("jdbc:mysql://localhost:3306/class38?serverTimezone=Asia/Shanghai"); dataSource.setUsername("root"); dataSource.setPassword("123456"); try { //獲取鏈接 DruidPooledConnection conn = dataSource.getConnection(); PreparedStatement statement = conn.prepareStatement("insert into student values(?,?,?,?)"); statement.setInt(1, 13); statement.setString(2, "小明"); statement.setString(3, "數據庫"); statement.setInt(4, 150); int i = statement.executeUpdate(); System.out.println(i); } catch (SQLException e) { e.printStackTrace(); }
設置配置文件:druid.properties
driverClassName = com.mysql.cj.jdbc.Driver url = jdbc:mysql://localhost:3306/class38?serverTimezone=Asia/Shanghai username = root password = 123456
經過配置文件實現鏈接:
//創建工廠 DruidDataSourceFactory factory = new DruidDataSourceFactory(); Properties p = new Properties(); InputStream in = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties"); try { //讀取配置文件中的信息 p.load(in); DataSource dataSource = factory.createDataSource(p); Connection conn = dataSource.getConnection(); PreparedStatement statement = conn.prepareStatement("select * from student"); ResultSet result = statement.executeQuery(); while(result.next()){ System.out.println(result.getInt(1)+","+result.getString(2)+","+result.getString(3)+","+result.getInt(4)); } } catch (Exception e) { e.printStackTrace(); }
開源的JDBC鏈接池,實現了數據源和JNDI綁定,支持JDBC3規範和JDBC2的標準擴展。目前使用它的開源項目有Hibernate、Spring等。
數據庫鏈接池C3P0框架是個很是優異的開源jar,高性能的管理着數據源,c3p0有兩種數據源管理方式,一種是經過程序變自己來進行管理,還有一種是經過容器管理,
c3p0有自動回收空閒鏈接功能。單線程,性能較差,適用於小型系統,代碼600KB左右。
依賴Jar包:不分版本號
● mysql-connector-java-8.0.14.jar
● c3p0-0.9.5.2.jar
● mchange-commons-java-0.2.11.jar
① 鏈接使用C3P0
1.1 - 使用Java API方式配置c3p0
ComboPooledDataSource dataSource = new ComboPooledDataSource(); try { dataSource.setDriverClass("com.mysql.cj.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/class38?serverTimezone=Asia/Shanghai"); dataSource.setUser("root"); dataSource.setPassword("123456"); Connection conn = dataSource.getConnection(); PreparedStatement statement = conn.prepareStatement("delete from student where id=?"); statement.setInt(1, 11); int i = statement.executeUpdate(); System.out.println(i); } catch (Exception e) { e.printStackTrace(); } }
1.2 - 直接在鏈接池中獲取鏈接
DataSource ds = new ComboPooledDataSource();/ try { Connection connection = ds.getConnection(); String sql = "select * from goods"; PreparedStatement prepareStatement = connection.prepareStatement(sql);// 設置sql語句 ResultSet executeQuery = prepareStatement.executeQuery();// 運行 while (executeQuery.next()) { System.out.println("商品:" + executeQuery.getObject(2).toString()); } executeQuery.close(); prepareStatement.close(); connection.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }
★1.3 - 使用DBUtils工具鏈接:須要配置XML數據源,使用工具鏈接不須要close
//獲取數據源,讀取的是C3P0-config默認配置建立數據庫鏈接池對象 DataSource ds = new ComboPooledDataSource(); //建立QueryRunner帶參對象 QueryRunner queryRunner = new QueryRunner(ds); //SQL UPDATE語句 String sql = "DELETE FROM type WHERE id in(?,?)"; //執行UPDATE語句,返回一個int類型的結果 int update = queryRunner.update(sql,6,7); System.out.println(update);
② 使用c3p0.properties文件進行配置
數據源配置:c3p0.properties
須要在classpath路徑下添加配置文件:c3p0.properties,內容以下:
c3p0.driverClass=com.mysql.jdbc.Driver c3p0.jdbcUrl=jdbc:mysql://host:port/db c3p0.user=root c3p0.password= c3p0.minPoolSize=5 c3p0.maxPoolSize=20 c3p0.acquireIncrement=5
在應用程序中只須要直接建立ComboPooledDataSource對象便可(c3p0會自動從classpath加載c3p0.properties中的配置信息):
ComboPooledDataSource cpds = new ComboPooledDataSource(); Connection conn = cpds.getConnection(); query(conn); cpds.close();
注意: 使用c3p0.properties做爲配置文件時,每一個參數的name前綴必須是「c3p0」,如:「c3p0.driverClass=com.mysql.jdbc.Driver」。
★ ③ 使用c3p0-config.xml文件進行配置
數據源配置:c3p0-config.xml
使用這種方式會比使用c3p0.properties更加高級,支持配置多個數據源,一樣須要在classpath路徑下添加文件:c3p0-config.xml
<c3p0-config> <!-- 這是默認配置信息 --> <default-config> <!-- 鏈接四大參數配置 --> <property name="driverClass">com.mysql.cj.jdbc.Driver</property> <property name="jdbcUrl"><!--CDATA裏面的特殊符號都當字符串處理--> <![CDATA[jdbc:mysql://localhost:3306/cakeshop?useUnicode=true&character=UTF-8&serverTimezone=GMT%2B8&useSSL=true]]> </property> <property name="user">用戶名</property> <property name="password">密碼</property> <!-- 池參數配置 --> <property name="acquireIncrement">3</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">2</property> <property name="maxPoolSize">10</property> </default-config> </c3p0-config>
在應用程序中只須要直接建立ComboPooledDataSource對象便可(c3p0會自動從classpath加載c3p0-config.xml中的配置信息):
// 使用默認數據源 // ComboPooledDataSource cpds = new ComboPooledDataSource(); // 使用指定名稱的數據源 ComboPooledDataSource cpds = new ComboPooledDataSource("myDataSource"); Connection conn = cpds.getConnection(); query(conn); cpds.close();
DBCP:
由Apache開發的一個Java數據庫鏈接池項目, Jakarta commons-pool對象池機制,Tomcat使用的鏈接池組件就是DBCP。
單獨使用dbcp須要3個包,預先將數據庫鏈接放在內存中,應用程序須要創建數據庫鏈接時直接到鏈接池中申請一個就行,用完再放回。
單線程,併發量低,性能很差,適用於小型系統。
依賴Jar包:不分版本號
● mysql-connector-java-8.0.14.jar
● commons-dbcp2-2.4.0.jar
● commons-pool2-2.6.2.jar
● commons-logging-1.2.jar
//建立鏈接池對象 BasicDataSource dataSource = new BasicDataSource(); //設置參數 dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/class38?serverTimezone=Asia/Shanghai"); dataSource.setUsername("root"); dataSource.setPassword("123456"); try { //獲取鏈接對象 Connection conn = dataSource.getConnection(); //生成預編譯Statement對象 PreparedStatement statement = conn.prepareStatement("insert into student values(null,?,?,?)"); statement.setString(1, "帥帥"); statement.setString(2, "大數據"); statement.setInt(3, 100); //執行sql語句 int i = statement.executeUpdate(); System.out.println(i); } catch (Exception e) { e.printStackTrace(); }
配置文件內容:dbcp.properties
driverClassName = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:3306/class38?serverTimezone=Asia/Shanghai
username = root
password = 123456
經過Properties配置文件鏈接:
BasicDataSourceFactory factory = new BasicDataSourceFactory(); Properties p = new Properties(); try { InputStream in = DBCPDemo.class.getClassLoader().getResourceAsStream("dbcp.properties"); //加載配置文件 p.load(in); //建立一個對象並返回 DataSource dataSource = factory.createDataSource(p); Connection conn = dataSource.getConnection(); PreparedStatement statement = conn.prepareStatement("select * from student"); ResultSet result = statement.executeQuery(); while(result.next()){ System.out.println(result.getInt(1)+","+result.getString(2)+","+result.getString(3)+","+result.getInt(4)); } } catch (Exception e) { e.printStackTrace(); }
@ 轉載至網絡