JDBC与连接池
一、什么是 JDBC?
1、定義:
一套JDBC接口代碼能同時操作所有的關系型數據庫,真正執行的是驅動jar包。
Javadatabaseconnectivity 即java數據庫連接,可以理解為java語言操作數據庫,對數據庫進行增刪改查。
數據庫有多種,如mysql、oracle、DB2、SQLServer,我們期望實現一套java代碼能同時操作所有的關系型數據庫。
sun公司定義接口,數據庫廠商提供實現類(數據庫驅動)。
JDBC的本質:官方定義的一套操作所有關系型數據庫的規則(即接口),各個數據庫廠商去實現這套接口,提供數據庫驅動jar包,我們可以使用這套JDBC接口編程,真正執行的代碼是驅動jar包中的實現類中的實現方法。(類似于多態)
這一套接口就可以操作不同的數據庫,sun公司僅僅定義了接口,如果你想用java語言操作mysql,mysql數據庫廠商寫一個實現類,即每一個數據庫廠商都寫一個不同的實現類來操作不同的數據庫。每一個實現類都實現了相同的JDBC接口,將來我們在寫代碼的時候,只需要調用接口,具體的實現類由不同的公司實現的,不用我們寫實現類。我們給實現類起名為數據庫驅動。
2、使用 JDBC 的好處
1) 程序員如果要開發訪問數據庫的程序,只需要會調用 JDBC 接口中的方法即可,不用關注類是如何實現的。
2) 使用同一套 Java 代碼,進行少量的修改就可以訪問其他 JDBC 支持的數據庫
二、JDBC 訪問數據庫的步驟
1) 注冊和加載驅動(可以省略)
2) 獲取連接
3) Connection 獲取 Statement 對象
4) 使用 Statement 對象執行 SQL 語句后得到結果集
5) 返回結果集
6) 釋放資源
JDBC快速入門:
步驟:
1、導入驅動jar包:復制mysql-connector-java-5.1.37-bin.jar(jar包中放的是class文件)到項目的libs目錄下,libs目錄右鍵,選擇Addas library,這樣jar包才會真正加入到項目中。
2、將實現類(Driver)加載進內存,Driver類中的靜態代碼塊自動執行,從而實現注冊驅動,真正注冊驅動的是DriverManager。
Class.forName(“全類名”)方法將字節碼文件加載進內存,返回類對象
在mysql-connector-java5之后的jar包,加載Driver類進內存的代碼Class.forName()可以省略不寫,即沒有間接注冊驅動,程序也能正常運行,因為mysql-connector-java-5.1.37-bin.jar包下的META-INF目錄下的services目錄下的java.sql.Driver文件中把Driver的全類名寫進來了,這樣如果你沒有注冊驅動,可以自動注冊驅動
建議將來寫代碼的時候不要省略,因為mysql-connector-java5之前的驅動包就不能使用這些代碼了,即不能向下兼容。
3、獲取數據庫連接對象Connection。(這個對象是java代碼與數據庫間的橋梁對象)
jdbc:mysql://ip地址或域名:端口/數據庫名稱
如果連接的是本機的mysql服務器,并且mysql服務的默認端口是3306,則url可以簡寫為:jdbc:mysql:///數據庫名稱
4、定義sql語句,然后把sql發送給數據庫,數據庫就會執行sql語句,從而達到java代碼操作數據庫的要求求。
5、Connection對象創建執行sql語句的對象statement
6、statement執行sql,接收返回的結果集
7、處理結果集
8、釋放資源,否則會造成內存的泄露。
三、數據庫連接池
1、為什么使用連接池?
之前每一個類都需要獲取一個連接,用完之后就釋放了,每一次都這樣。但是獲取連接的操作是向操作系統申請資源,而申請資源是非常耗時的操作,如果連接用完就釋放,導致我們的程序會比較慢,下面學習連接池來解決性能比較低,資源浪費的情況。
現在,用戶在訪問數據庫時,在系統初始化之后和用戶訪問之前,創建了一個容器,并在容器中申請了很多的連接對象裝在容器中,當程序訪問數據庫的時候,不會向系統底層申請連接了,而是從容器中獲取一個連接對象,從而去訪問數據庫,訪問完了之后,不會把連接釋放掉,而是把連接對象歸還給容器。這樣做的好處是:節約了系統資源,訪問的速度快了,連接對象被復用,
數據庫連接池:其實就是一個存放數據庫連接的容器(集合)。
2、數據庫連接池_實現介紹
Javax.sql.DataSource接口就是連接池,DataSource對象是獲取連接的首選方法,由驅動程序供應商實現DataSource接口,即誰提供數據庫的驅動誰去實現DataSource。
數據庫連接池的實現類:
C3P0框架的DataSource實現類是com.mchange.v2.c3p0.ComboPooledDataSource
MyBatis框架的DataSource類是org.apache.ibatis.datasource.pooled.PooledDataSource
Druid框架的DataSource類是com.alibaba.druid.pool.DruidDataSource
Druid由阿里巴巴提供,號稱全球最好的數據庫連接池技術
類ComboPooledDataSource和類DruidDataSource都實現了DataSource接口,
獲取連接:DataSource接口有ConnectiongetConnection()方法
歸還連接:Connection.close()。如果連接對象Connection是從連接池中獲取的,那么調用Connection.close()方法,則不會關閉連接了,而是歸還連接。連接池把close()方法給增強了。
3、druid連接池
導入依賴
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--數據庫連接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
數據庫配置:
#數據庫 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.url=jdbc:mysql://ip:3306/zwh?serverTimezone=Hongkong&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true spring.datasource.username=root spring.datasource.password=root
4、Mybatis連接池的分類
Mybatis內部分別定義了實現java.sql.DataSource接口的UnpooledDataSource、PooledDataSource類來分別表示UNPOOLED、POOLED類型的數據源。
1)、POOLED:采用傳統的javax.sql.DataSource規范中的連接池,mybatis中有針對規范的實現。每次都是從連接池中獲取連接
如果空閑連接idleConnections(是一個ArrayList集合)不為空,表示還有空閑連接,就從集合中拿出一個連接來用;如果沒有空閑連接,并且活躍的連接activeConnection(是一個ArrayList集合)數小于連接池的最大活躍連接數poolMaximumActiveConnection,則創建一個連接,如果沒有空閑連接,并且活躍的連接activeConnections數大于等于連接池的最大活躍連接數,則從活躍的連接集合activeConnections中取出第一個連接(最先進入activeConnections的連接)oldestActiveConnection來給我們用。
2)、UNPOOLED:采用傳統的獲取連接的方式,雖然也實現了Javax.sql.DataSource接口,但是并沒有使用池的思想。每次使用都是重新獲取連接。
3)、JNDI:采用服務器提供的JNDI技術實現,來獲取DataSource對象,不同的服務器所能拿到的DataSource是不一樣的,注意,如果不是web或maven的war工程是不能使用的。我們使用的是tomcat服務器,采用的連接池就是DBCP連接池。
實際開發中用POOLED,即用池的思想來管理連接。
5、springboot2.0默認連接池
Springboot2.0以后默認數據庫連接池選擇了Hikari(性能高)
項目啟動時,如果控制臺打印如下:
說明使用了springboot默認的連接池。
性能方面hikariCP>druid>tomcat-jdbc>dbcp>c3p0,hikariCP的高性能得益于最大限度的避免鎖競爭。
配置默認數據庫連接池(Hikari)
步驟一:起步依賴
<!--jdbc起步依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mysql數據庫驅動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
步驟二:數據庫連接信息配置
# jdbc_config datasource spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/datebook?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull spring.datasource.username=root spring.datasource.password=root # Hikari will use the above plus the following to setup connection pooling spring.datasource.type=com.zaxxer.hikari.HikariDataSource spring.datasource.hikari.minimum-idle=5 spring.datasource.hikari.maximum-pool-size=15 spring.datasource.hikari.auto-commit=true spring.datasource.hikari.idle-timeout=30000 spring.datasource.hikari.pool-name=DatebookHikariCP spring.datasource.hikari.max-lifetime=1800000 spring.datasource.hikari.connection-timeout=30000 spring.datasource.hikari.connection-test-query=SELECT 1
hikariCP連接池常用配置:
5、autoCommit
此屬性控制從池返回的連接的默認自動提交行為。它是一個布爾值。 默認值:true
6、connectionTimeout
此屬性控制客戶端(即您)將等待來自池的連接的最大毫秒數。如果在沒有可用連接的情況下超過此時間,則會拋出SQLException。最低可接受的連接超時時間為250 ms。 默認值:30000(30秒)
7、idleTimeout
此屬性控制允許連接在池中閑置的最長時間。 此設置僅適用于minimumIdle定義為小于maximumPoolSize。一旦池達到連接,空閑連接將不會退出minimumIdle。連接是否因閑置而退出,最大變化量為+30秒,平均變化量為+15秒。在超時之前,連接永遠不會退出。值為0意味著空閑連接永遠不會從池中刪除。允許的最小值是10000ms(10秒)。 默認值:600000(10分鐘)
8、maxLifetime
此屬性控制池中連接的最大生存期。正在使用的連接永遠不會退休,只有在關閉后才會被刪除。在逐個連接的基礎上,應用較小的負面衰減來避免池中的大量消失。 我們強烈建議設置此值,并且應該比任何數據庫或基礎設施規定的連接時間限制短幾秒。 值為0表示沒有最大壽命(無限壽命),當然是idleTimeout設定的主題。 默認值:1800000(30分鐘)
9、connectionTestQuery
如果您的驅動程序支持JDBC4,我們強烈建議您不要設置此屬性。這是針對不支持JDBC4的“傳統”驅動程序Connection.isValid() API。這是在連接從池中獲得連接以確認與數據庫的連接仍然存在之前將要執行的查詢。再一次,嘗試運行沒有此屬性的池,如果您的驅動程序不符合JDBC4的要求,HikariCP將記錄一個錯誤以告知您。 默認值:無
10、minimumIdle
該屬性控制HikariCP嘗試在池中維護的最小空閑連接數。如果空閑連接低于此值并且連接池中的總連接數少于此值maximumPoolSize,則HikariCP將盡最大努力快速高效地添加其他連接。但是,為了獲得最佳性能和響應尖峰需求,我們建議不要設置此值,而是允許HikariCP充當固定大小的連接池。 默認值:與maximumPoolSize相同
11、maximumPoolSize
此屬性控制池允許達到的最大大小,包括空閑和正在使用的連接?;旧线@個值將決定到數據庫后端的最大實際連接數。對此的合理價值最好由您的執行環境決定。當池達到此大小并且沒有空閑連接可用時,對getConnection()的調用將connectionTimeout在超時前阻塞達幾毫秒。請閱讀關于游泳池尺寸。 默認值:10
12、metricRegistry
該屬性僅通過編程配置或IoC容器可用。該屬性允許您指定池使用的Codahale / Dropwizard 實例MetricRegistry來記錄各種指標。有關 詳細信息,請參閱Metrics維基頁面。 默認值:無
13、healthCheckRegistry
該屬性僅通過編程配置或IoC容器可用。該屬性允許您指定池使用的Codahale / Dropwizard 的實例HealthCheckRegistry來報告當前的健康信息。有關 詳細信息,請參閱健康檢查 wiki頁面。 默認值:無
14、poolName
此屬性表示連接池的用戶定義名稱,主要出現在日志記錄和JMX管理控制臺中以識別池和池配置。 默認:自動生成
15、initializationFailTimeout
如果池無法成功初始化連接,則此屬性控制池是否將“快速失敗”。任何正數都取為嘗試獲取初始連接的毫秒數; 應用程序線程將在此期間被阻止。如果在超時發生之前無法獲取連接,則會引發異常。此超時被應用后的connectionTimeout 期。如果值為零(0),HikariCP將嘗試獲取并驗證連接。如果獲得連接但未通過驗證,將拋出異常并且池未啟動。但是,如果無法獲得連接,則會啟動該池,但后續獲取連接的操作可能會失敗。小于零的值將繞過任何初始連接嘗試,并且在嘗試獲取后臺連接時,池將立即啟動。因此,以后努力獲得連接可能會失敗。 默認值:1
16、isolateInternalQueries
此屬性確定HikariCP是否在其自己的事務中隔離內部池查詢,例如連接活動測試。由于這些通常是只讀查詢,因此很少有必要將它們封裝在自己的事務中。該屬性僅適用于autoCommit禁用的情況。 默認值:false
17、allowPoolSuspension
該屬性控制池是否可以通過JMX暫停和恢復。這對于某些故障轉移自動化方案很有用。當池被暫停時,呼叫 getConnection()將不會超時,并將一直保持到池恢復為止。 默認值:false
18、readOnly
此屬性控制默認情況下從池中獲取的連接是否處于只讀模式。注意某些數據庫不支持只讀模式的概念,而其他數據庫則在Connection設置為只讀時提供查詢優化。無論您是否需要此屬性,都將主要取決于您的應用程序和數據庫。 默認值:false
19、registerMbeans
該屬性控制是否注冊JMX管理Bean(“MBeans”)。 默認值:false
20、catalog
該屬性設置默認目錄為支持目錄的概念數據庫。如果未指定此屬性,則使用由JDBC驅動程序定義的默認目錄。 默認:驅動程序默認
21、connectionInitSql
該屬性設置一個SQL語句,在將每個新連接創建后,將其添加到池中之前執行該語句。如果這個SQL無效或引發異常,它將被視為連接失敗并且將遵循標準重試邏輯。 默認值:無
22、driverClassName
HikariCP將嘗試通過DriverManager僅基于驅動程序來解析驅動程序jdbcUrl,但對于一些較舊的驅動程序,driverClassName還必須指定它。除非您收到明顯的錯誤消息,指出找不到驅動程序,否則請忽略此屬性。 默認值:無
23、transactionIsolation
此屬性控制從池返回的連接的默認事務隔離級別。如果未指定此屬性,則使用由JDBC驅動程序定義的默認事務隔離級別。如果您有針對所有查詢通用的特定隔離要求,請僅使用此屬性。此屬性的值是從不斷的名稱Connection 類,如TRANSACTION_READ_COMMITTED,TRANSACTION_REPEATABLE_READ等 默認值:驅動程序默認
24、validationTimeout
此屬性控制連接測試活動的最長時間。這個值必須小于connectionTimeout。最低可接受的驗證超時時間為250 ms。 默認值:5000
25、leakDetectionThreshold
此屬性控制在記錄消息之前連接可能離開池的時間量,表明可能存在連接泄漏。值為0意味著泄漏檢測被禁用。啟用泄漏檢測的最低可接受值為2000(2秒)。 默認值:0
26、dataSource
此屬性僅通過編程配置或IoC容器可用。這個屬性允許你直接設置DataSource池的實例,而不是讓HikariCP通過反射來構造它。這在一些依賴注入框架中可能很有用。當指定此屬性時,dataSourceClassName屬性和所有DataSource特定的屬性將被忽略。 默認值:無
27、schema
該屬性設置的默認模式為支持模式的概念數據庫。如果未指定此屬性,則使用由JDBC驅動程序定義的默認模式。 默認:驅動程序默認
28、threadFactory
此屬性僅通過編程配置或IoC容器可用。該屬性允許您設置java.util.concurrent.ThreadFactory將用于創建池使用的所有線程的實例。在一些只能通過ThreadFactory應用程序容器提供的線程創建線程的有限執行環境中需要它。 默認值:無
29、scheduledExecutor
此屬性僅通過編程配置或IoC容器可用。該屬性允許您設置java.util.concurrent.ScheduledExecutorService將用于各種內部計劃任務的實例。如果為ScheduledThreadPoolExecutor 實例提供HikariCP,建議setRemoveOnCancelPolicy(true)使用它。 默認值:無
總結
- 上一篇: iOS8软件推送消息关闭方法
- 下一篇: iOS8越狱后白苹果及无法开机解决方法