連接池是優(yōu)化連接數(shù)據(jù)庫的吗蚌,驅(qū)動是連接數(shù)據(jù)庫的。JDBC是java封裝的對數(shù)據(jù)庫的操作
一:什么是JDBC?
1.JDBC(Java DataBase Connectivity,java數(shù)據(jù)庫連接)是一種用于執(zhí)行SQL語句的Java API纯出,可以為多種關(guān)系數(shù)據(jù)庫提供統(tǒng)一訪問蚯妇,它由一組用Java語言編寫的類和接口組成。JDBC提供了一種基準(zhǔn)暂筝,據(jù)此可以構(gòu)建更高級的工具和接口箩言,使數(shù)據(jù)庫開發(fā)人員能夠編寫數(shù)據(jù)庫應(yīng)用程序.
注:JDBC是java封裝的對數(shù)據(jù)庫的操作。
2.JDBC的 java api有哪些乖杠,四個常用的接口和一個類(Connection接口分扎、Statement接口澄成、PreparedStatement接口胧洒、ResultSet接口和DriverManager類),那我們怎么使用它墨状,下面我就貼出一個簡單的實例:
2.1JDBC原生開發(fā)步驟:
(1)注冊驅(qū)動(要引入驅(qū)動jar包)
(2)獲得連接
(3)創(chuàng)建執(zhí)行sql語句的對象
(4)執(zhí)行sql語句,處理結(jié)果
(5)關(guān)閉資源
public static void main(String[] args) throws SQLException {
//1.注冊驅(qū)動
DriverManager.registerDriver(new Driver());
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "123456";
//2.獲得連接
Connection connection = DriverManager.getConnection(url, user, password);
//3.創(chuàng)建執(zhí)行sql語句對象
Statement statement = connection.createStatement();
//4.執(zhí)行sql,處理結(jié)果
String sql = "select *from user";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
System.out.println(resultSet.getObject(1));
System.out.println(resultSet.getObject(2));
System.out.println(resultSet.getObject(3));
System.out.println(resultSet.getObject(4));
}
//5.關(guān)閉資源
if(resultSet != null){
resultSet.close();
}
if(statement != null){
statement .close();
}
if(connection != null){
connection.close();
}
}
2.2JDBC工具類的抽取及使用卫漫。
2.2.1創(chuàng)建配置文件,配置文件在src目錄下,擴展名是properties
配置文件:
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=123456
- 工具類抽取:讀取方式一
package com.xxxxx.utils;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
//1.提供連接(1,2)
//2.釋放資源(5)
public class JdbcUtils {
private static String driverClass;
private static String url;
private static String username;
private static String password;
//注冊驅(qū)動只需要注冊一次(靜態(tài)代碼塊)
//配置文件,只需要讀取一次
static{
// 注冊驅(qū)動
try {
//0 根據(jù)jdbc.properties創(chuàng)建輸入流
InputStream is = new FileInputStream("src/jdbc.properties");
//1\. 創(chuàng)建配置對象
Properties properties = new Properties();
//2.關(guān)聯(lián)jdbc.properties文件
properties.load(is);
//3.根據(jù)key獲得值
driverClass = properties.getProperty("driverClass");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
Class.forName(driverClass);
} catch (Exception e) {
e.printStackTrace();
}
}
// 提供連接
public static Connection getConnection() throws Exception {
// 2\. 獲得連接
Connection connection = DriverManager.getConnection(url, username, password);
return connection;
}
//釋放資源
public static void release(ResultSet resultSet,Statement statement,Connection connection){
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
- 讀取配置文件方式二:
public class JdbcUtils {
static String url;
static String user;
static String password;
static String driver;
//注冊驅(qū)動
static{
try {
//讀取配置文件
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
url = bundle.getString("url");
user = bundle.getString("user");
password = bundle.getString("password");
driver = bundle.getString("driver");
Class.forName(driver );
} catch (Exception e) {
e.printStackTrace();
}
}
//獲得連接
public static Connection getConnection() throws SQLException{
Connection connection = DriverManager.getConnection(url, user, password);
return connection;
}
//關(guān)閉資源
public static void release(ResultSet resultSet,Statement statement,Connection connection){
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
二:什么是數(shù)據(jù)庫驅(qū)動肾砂?
數(shù)據(jù)庫驅(qū)動是不同數(shù)據(jù)庫開發(fā)商(比如oracle mysql等)為了某一種開發(fā)語言環(huán)境(比如java)能夠?qū)崿F(xiàn)統(tǒng)一的數(shù)據(jù)庫調(diào)用而開發(fā)的一個程序列赎,他的作用相當(dāng)于一個翻譯人員,將Java語言中對數(shù)據(jù)庫的調(diào)用語言通過這個翻譯翻譯成各個種類的數(shù)據(jù)庫自己的數(shù)據(jù)庫語言镐确,當(dāng)然這個翻譯(數(shù)據(jù)庫驅(qū)動)是由各個開發(fā)商針對統(tǒng)一的接口自定義開發(fā)的包吝。
注:數(shù)據(jù)庫驅(qū)動饼煞,就是連接數(shù)據(jù)庫的,直接與數(shù)據(jù)庫交互的诗越。
三:為什么要使用jdbc來操作數(shù)據(jù)庫砖瞧?
因為市面上有多種數(shù)據(jù)庫,數(shù)據(jù)庫編寫的語言又不一樣嚷狞,所以連接各個數(shù)據(jù)庫的驅(qū)動編寫的語言也不一樣块促,這時要使用相關(guān)的數(shù)據(jù)庫,則必須學(xué)習(xí)相關(guān)數(shù)據(jù)庫的驅(qū)動床未,就會造成開發(fā)人員學(xué)習(xí)和使用成本竭翠。sun公司為了規(guī)范統(tǒng)一,則定義了JDBC這套接口薇搁,所有廠商的數(shù)據(jù)庫驅(qū)動只要遵循這套規(guī)范斋扰,則可以對數(shù)據(jù)庫操作。開發(fā)人員就不必再學(xué)習(xí)相關(guān)的數(shù)據(jù)庫驅(qū)動啃洋,只需要學(xué)習(xí)這套規(guī)范褥实,使用JDBC操作數(shù)據(jù)庫即可.(使用JDBC操作數(shù)據(jù)庫必須要有數(shù)據(jù)庫驅(qū)動包,JDBC是直接操作數(shù)據(jù)庫驅(qū)動包進(jìn)而操作數(shù)據(jù)庫的)裂允。
四:JDBC的原理损离,一張圖片,讓你明白JDBC與驅(qū)動的關(guān)系
注:接口(JDBC)與實現(xiàn)(驅(qū)動jar包)的關(guān)系绝编。
五:使用數(shù)據(jù)庫連接池僻澎。
1.什么是連接池?為什么使用連接池重寫JDBC工具類十饥?
連接池類比一個池子窟勃。
(1)Connection對象在JDBC使用的時候就會去創(chuàng)建一個對象,使用結(jié)束以后就會將這個對象給銷毀了(close).每次創(chuàng)建和銷毀對象都是耗時操作. 這樣做是特別銷毀資源的.
(2)需要使用連接池對其進(jìn)行優(yōu)化.程序初始化的時候,初始化多個連接,將多個連接放入到池(集合)中.每次獲取的時候,都可以直接從連接池中進(jìn)行獲取.使用結(jié)束以后,將連接歸還到池中.
[圖片上傳失敗...(image-e52bef-1564213471546)]
2.生活里面的連接池例子
老方式:
下了地鐵需要騎車, 跑去生產(chǎn)一個, 然后騎完之后,直接把車銷毀了.連接池: 膜拜單車
一開始就有一個公司創(chuàng)建了很多的自行車, 下了地鐵需要騎車, 直接掃描騎車, 然后騎完之后,放在原地
3.連接池原理【重點】
- 目的:解決建立數(shù)據(jù)庫連接耗費資源和時間很多的問題逗堵,提高性能秉氧。
4.數(shù)據(jù)庫連接池API
4.1數(shù)據(jù)源接口
4.2數(shù)據(jù)源接口中的方法
5.常用連接池
DataSource本身只是sun公司提供的一個接口,沒有具體的實現(xiàn)蜒秤,它的實現(xiàn)由連接池的數(shù)據(jù)庫廠商去實現(xiàn)汁咏。我們只需要學(xué)習(xí)這個工具如何使用即可。常用的連接池實現(xiàn)有這些:
DBCP(DataBase Connection Pool)數(shù)據(jù)庫連接池作媚,是Apache上的一個Java連接池項目攘滩,也是Tomcat使用的連接池組件。dbcp沒有自動回收空閑連接的功能纸泡。
C3P0是一個開源的JDBC連接池目前使用它的開源項目有Hibernate漂问,Spring等。C3P0有自動回收空閑連接功能
5.1dbcp連接池
5.1.1dbcp概念
- DBCP:Apache推出的Database Connection Pool
核心API:
- basicDatasource
- basicDatasourceFactory
以下代碼公用User實體類:
public class User {
/*id int primary key auto_increment,
username varchar(20),
password varchar(20),
nickname varchar(20)*/
private int id;
private String username;
private String password;
private String nickname;
public User() {
}
public User(int id, String username, String password, String nickname) {
this.id = id;
this.username = username;
this.password = password;
this.nickname = nickname;
}
//Alt+Shift+S
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + ", nickname=" + nickname + "]";
}
}
5.1.2dbcp的使用
-
方式一:通過硬編碼來編寫【了解】
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.junit.Test;
import com.xxxx.bean.User;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class DbcpDemo {
@Test
//查詢id=1的用戶
//使用Dbcp連接池方式一: 使用硬編碼(了解)
public void fun01() throws SQLException{
//1. 創(chuàng)建連接池(數(shù)據(jù)源) [先把dbcp的jar導(dǎo)入一下]
BasicDataSource basicDataSource = new BasicDataSource();
//設(shè)置四個基本參數(shù)(驅(qū)動,路徑,用戶名,密碼)
basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
basicDataSource.setUrl("jdbc:mysql://localhost:3306/web11");
basicDataSource.setUsername("root");
basicDataSource.setPassword("123456");
/*//設(shè)置初始化連接的數(shù)量(選配, 不配置是有默認(rèn)值)
basicDataSource.setInitialSize(5);
//設(shè)置等待時間(選配, 不配置是有默認(rèn)值)
basicDataSource.setMaxWait(2000);*/
//2. 直接從連接池里面獲得連接對象
Connection connection = basicDataSource.getConnection();
//3. 創(chuàng)建預(yù)編譯sql語句對象
String sql = "select * from user where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//4. 設(shè)置參數(shù), 執(zhí)行, 處理結(jié)果
preparedStatement.setInt(1, 1);
ResultSet resultSet = preparedStatement.executeQuery();
User user = null;
while(resultSet.next()){
user = new User(resultSet.getInt("id"), resultSet.getString("username"), resultSet.getString("password"),
resultSet.getString("nickname"));
}
System.out.println(user);
//5. 釋放資源(這個方法還是close,但是不是銷毀了,而是歸還; 因為這個connection是從連接池里面獲得的, 連接池內(nèi)部重寫了close)
connection.close();
}
}
-
方式二:通過配置文件來配置【重點】
添加配置文件到src目錄
配置文件:
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.junit.Test;
import com.xxxx.bean.User;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class DbcpDemo {
@Test
//查詢id=1的用戶
//使用Dbcp連接池方式二: 配置文件方式[掌握]
public void fun02() throws Exception{
//0 創(chuàng)建配置對象, 加載dbcpconfig.properties
Properties properties = new Properties();
//關(guān)聯(lián)dbcpconfig.properties配置文件
InputStream is = DbcpDemo.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
properties.load(is);
//1. 創(chuàng)建連接池(數(shù)據(jù)源) [先把dbcp的jar導(dǎo)入一下, 先把配置文件導(dǎo)入src目錄下]
BasicDataSource basicDataSource = (BasicDataSource) BasicDataSourceFactory.createDataSource(properties);
//2. 直接從連接池里面獲得連接對象
Connection connection = basicDataSource.getConnection();
//3. 創(chuàng)建預(yù)編譯sql語句對象
String sql = "select * from user where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//4. 設(shè)置參數(shù), 執(zhí)行, 處理結(jié)果
preparedStatement.setInt(1, 1);
ResultSet resultSet = preparedStatement.executeQuery();
User user = null;
while(resultSet.next()){
user = new User(resultSet.getInt("id"), resultSet.getString("username"), resultSet.getString("password"),
resultSet.getString("nickname"));
}
System.out.println(user);
//5. 釋放資源(這個方法還是close,但是不是銷毀了,而是歸還; 因為這個connection是從連接池里面獲得的, 連接池內(nèi)部重寫了close)
connection.close();
}
}
5.2 C3P0連接池
5.2.1 c3p0概念
- C3P0開源免費的連接池!目前使用它的開源項目有:Spring蚤假、Hibernate等栏饮。使用第三方工具需要導(dǎo)入jar包,c3p0使用時還需要添加配置文件c3p0-config.xml.
- 使用C3P0需要添加c3p0-0.9.1.2.jar
5.2.2c3p0的使用
-
通過硬編碼來編寫(不需要配置文件.了解一下)
import org.junit.Test;
import com.xxxx.bean.User;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class C3P0Demo {
@Test
//查詢id=1的用戶
//使用C3P0連接池方式一:硬編碼(了解)
public void fun01() throws Exception{
//1 創(chuàng)建連接池(數(shù)據(jù)源)
ComboPooledDataSource cpds = new ComboPooledDataSource();
//加載四個基本項(驅(qū)動,路徑,用戶名,密碼)
cpds.setDriverClass("com.mysql.jdbc.Driver");
cpds.setJdbcUrl("jdbc:mysql://localhost:3306/web11");
cpds.setUser("root");
cpds.setPassword("123456");
//初始化連接數(shù)量(選配)
//cpds.setInitialPoolSize(5);
//2. 從連接池里面獲得Connection
Connection connection = cpds.getConnection();
//3. 創(chuàng)建預(yù)編譯sql語句對象
String sql = "select * from user where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//4. 設(shè)置參數(shù), 執(zhí)行, 處理結(jié)果;
preparedStatement.setInt(1, 1);
ResultSet resultSet = preparedStatement.executeQuery();
User user = null;
while(resultSet.next()){
user = new User(resultSet.getInt("id"), resultSet.getString("username"), resultSet.getString("password"),
resultSet.getString("nickname"));
}
System.out.println(user);
//5. 釋放資源(這個方法還是close,但是不是銷毀了,而是歸還; 因為這個connection是從連接池里面獲得的, 連接池內(nèi)部重寫了close)
connection.close();
}
}
-
通過配置文件來編寫
編寫配置文件c3p0-config.xml磷仰,放在src中(注:文件名一定不要寫錯,不要改)
配置文件:
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/web11</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">5</property>
</default-config>
</c3p0-config>
代碼實現(xiàn):
import org.junit.Test;
import com.xxxx.bean.User;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class C3P0Demo {
@Test
//查詢id=1的用戶
//使用C3P0連接池方式二:配置文件方式(重點)
public void fun02() throws Exception{
//1 創(chuàng)建連接池(數(shù)據(jù)源);
DataSource cpds = new ComboPooledDataSource();//會自動讀取src目錄下的c3p0-config.xml配置文件
//2. 從連接池里面獲得Connection
Connection connection = cpds.getConnection();
//3. 創(chuàng)建預(yù)編譯sql語句對象
String sql = "select * from user where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//4. 設(shè)置參數(shù), 執(zhí)行, 處理結(jié)果;
preparedStatement.setInt(1, 1);
ResultSet resultSet = preparedStatement.executeQuery();
User user = null;
while(resultSet.next()){
user = new User(resultSet.getInt("id"), resultSet.getString("username"), resultSet.getString("password"),
resultSet.getString("nickname"));
}
System.out.println(user);
//5. 釋放資源(這個方法還是close,但是不是銷毀了,而是歸還; 因為這個connection是從連接池里面獲得的, 連接池內(nèi)部重寫了close)
resultSet.close();
preparedStatement.close();
connection.close();
}
}
5.3使用C3P0連接池改寫工具類(C3P0配置文件方式+C3P0工具類抡爹,開發(fā)中常用)
配置文件:
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/web11</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">5</property>
</default-config>
</c3p0-config>
c3p0工具類的抽取:
public class C3P0Utils {
//創(chuàng)建一個連接池對象
private static DataSource ds = new ComboPooledDataSource();//會自動讀取src目錄下的c3p0-config.xml配置文件
//從池中獲得一個連接
public static Connection getConnection() throws SQLException{
return ds.getConnection();
}
//釋放資源
public static void closeAll(ResultSet rs,Statement stmt,Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
rs = null;
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
stmt = null;
}
if(conn!=null){
try {
conn.close();//放心的關(guān)芒划。是否關(guān)閉取決連接是怎么來的
} catch (SQLException e) {
throw new RuntimeException(e);
}
conn = null;
}
}
}
代碼實現(xiàn):
public class C3P0Demo {
@Test
//查詢id=1的用戶
public void fun01() throws Exception{
// 1. 獲得連接
Connection connection = C3P0Utils.getConnection();
//3. 創(chuàng)建預(yù)編譯sql語句對象
String sql = "select * from user where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//4. 設(shè)置參數(shù), 執(zhí)行, 處理結(jié)果;
preparedStatement.setInt(1, 1);
ResultSet resultSet = preparedStatement.executeQuery();
User user = null;
while(resultSet.next()){
user = new User(resultSet.getInt("id"), resultSet.getString("username"), resultSet.getString("password"),
resultSet.getString("nickname"));
}
System.out.println(user);
//5. 釋放資源(這個方法還是close,但是不是銷毀了,而是歸還; 因為這個connection是從連接池里面獲得的, 連接池內(nèi)部重寫了close)
C3P0Utils.release(resultSet, preparedStatement, connection);
}
}
六:使用DBUtils 增刪改查的操作(簡化JDBC代碼開發(fā))
6.1概述
- DBUtils是java編程中的數(shù)據(jù)庫操作實用工具冬竟,小巧簡單實用。 第一個操作數(shù)據(jù)庫框架(jar),
- DBUtils封裝了對JDBC的操作民逼,簡化了JDBC操作流程泵殴,可以少寫代碼。
- Dbutils三個核心功能介紹
QueryRunner 執(zhí)行sql語句. update() 執(zhí)行update, delete,insert , query()執(zhí)行select
ResultSetHandler 封裝查詢結(jié)果集.(select )
6.2QueryRunner核心類
- QueryRunner(DataSource ds) ,拼苍,構(gòu)造函數(shù). 底層自動維護(hù)連接connection
- update(String sql, Object... params) 笑诅,執(zhí)行更新數(shù)據(jù) insert update delete 參數(shù)就是一個數(shù)組,參數(shù)個數(shù)取決于語句中?的個數(shù).
- query(String sql, ResultSetHandler<T> rsh, Object... params) ,執(zhí)行查詢 select
6.3ResultSetHandler結(jié)果集處理類
6.4使用DBUtils完成數(shù)據(jù)庫的CRUD
6.4.1開發(fā)步驟:
- 創(chuàng)建項目疮鲫,并導(dǎo)入jar包
- 創(chuàng)建連接池
-
編寫測試類
連接池配置文件c3p0-config.xml:
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/web11</property>
<property name="user">root</property>
<property name="password">123</property>
<property name="initialPoolSize">5</property>
</default-config>
</c3p0-config>
工具類:代碼上面貼了吆你。
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.Test;
import com.xxxx.bean.User;
import com.xxxxx.utils.C3P0Utils;
public class DbUtilsTest {
@Test
//更新(底部封裝了 PrepareStatemmet)
//把id = 1的用戶的名字改成zl
public void fun01() throws SQLException{
//1.創(chuàng)建QueryRunner
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
//執(zhí)行方法update
String sql = "update user set username = ? where id = ?";
queryRunner.update(sql, "zl",1);
}
@Test
//增加
public void fun02() throws SQLException{
//1創(chuàng)建QueryRunner對象
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
//2執(zhí)行方法update
String sql = "insert into user values(?,?,?,?)";
queryRunner.update(sql, null,"zs","123456","張三");
}
@Test
//把id=1為1的用戶刪除
public void fun03() throws SQLException{
//1創(chuàng)建QueryRunner對象
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
//2.執(zhí)行方法update
String sql = "delete from user where id = ?";
queryRunner.update(sql, 1);
}
@Test
//查詢id為2的用戶 一條數(shù)據(jù) ---》封裝成一個User對象(JavaBean) BeanHandler
public void fun04() throws SQLException{
//1.創(chuàng)建 QueryRunner對象
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
//2.執(zhí)行方法query
String sql = "select * from user where id = ?";
User user = queryRunner.query(sql, new BeanHandler<>(User.class),2);
System.out.println(user);
}
@Test
//查詢所有 BeanListHandler
public void fun05() throws SQLException{
//1.創(chuàng)建 QueryRunner對象
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
//2.執(zhí)行方法query
String sql = "select * from user ";
List<User> user = queryRunner.query(sql, new BeanListHandler<>(User.class));
System.out.println(user);
}
//統(tǒng)計總數(shù)量 select count(*) from user
@Test
public void fun06() throws SQLException{
//1.創(chuàng)建 QueryRunner對象
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
//2.執(zhí)行方法query
String sql = "select count(*) from user ";
Long n = (long)queryRunner.query(sql, new ScalarHandler());
System.out.println(n);
}
}
七.什么是數(shù)據(jù)源?
由SUN制定的用于獲取數(shù)據(jù)庫連接的規(guī)范接口俊犯。它存在于 javax.sql包中妇多,用來代替 DriverManager 的方式來獲取連接,JDBC2.0 提供了javax.sql.DataSource接口燕侠,它負(fù)責(zé)建立與數(shù)據(jù)庫的連接者祖,當(dāng)在應(yīng)用程序中訪問數(shù)據(jù)庫時不必編寫連接數(shù)據(jù)庫的代碼,直接引用DataSource獲取數(shù)據(jù)庫的連接對象即可绢彤。用于獲取操作數(shù)據(jù)Connection對象七问。
7.1.數(shù)據(jù)源與數(shù)據(jù)庫連接池
數(shù)據(jù)源建立多個數(shù)據(jù)庫連接,這些數(shù)據(jù)庫連接會保存在數(shù)據(jù)庫連接池中茫舶,當(dāng)需要訪問數(shù)據(jù)庫時械巡,只需要從數(shù)據(jù)庫連接池中獲取空閑的數(shù)據(jù)庫連接,當(dāng)程序訪問數(shù)據(jù)庫結(jié)束時饶氏,數(shù)據(jù)庫連接會放回數(shù)據(jù)庫連接池中讥耗。
7.2關(guān)于Datasource與數(shù)據(jù)庫連接池的區(qū)別。
數(shù)據(jù)庫連接有兩種方式:
- 1 :直連數(shù)據(jù)庫方式
當(dāng)調(diào)用DataSource.getConnection()時,其實它調(diào)用的是DriverManager.getConnection(url, user, password)來獲取一個Connection,Connection使用完后被close,斷開與數(shù)據(jù)庫的連接,我們稱這總方式是直連數(shù)據(jù)庫,因為每次都需要重新建立與數(shù)據(jù)庫之間的連接,而并沒有把之前的Connection保留供下次使用.
-
2 :池化連接方式
1.可以說這種方式就是使用了連接池技術(shù).DataSource內(nèi)部封裝了一個連接池,當(dāng)你獲取DataSource的時候,它已經(jīng)敲敲的與數(shù)據(jù)庫建立了多個Connection,并將這些Connection放入了連接池,此時調(diào)用DataSource.getConnection()它從連接池里取一個Connection返回,Connection使用完后被close,但這個close并不是真正的與數(shù)據(jù)庫斷開連接,而是告訴連接池"我"已經(jīng)被使用完,"你"可以把我分配給其它"人"使用了.就這樣連接池里的Connection被循環(huán)利用,避免了每次獲取Connection時重新去連接數(shù)據(jù)庫.
對DataSource的兩種實現(xiàn)方式已經(jīng)介紹完畢,現(xiàn)在知道DataSource與連接池之間的是關(guān)系而不是區(qū)別了吧,因為DataSource與連接池根本就不是同一類型的東西,只有同一類型的東西才存在區(qū)別,例如:oracle與db2都是數(shù)據(jù)庫,它們才存在區(qū)別.
DataSource與連接池的關(guān)系是:DataSource利用連接池緩存Connection,以達(dá)到系統(tǒng)效率的提升,資源的重復(fù)利用.
而連接池它可以單獨存在,不需要依靠DataSource來獲取連接,你可以直接調(diào)用連接池提供的方法來獲取連接.
目前大多數(shù)應(yīng)用服務(wù)器都支持池化連接方式的DataSource.
常用的連接池有c3p0,dbcp,Proxool...
一般場景:JNDI-> DataSource->連接池(c3p0,dbcp,Proxool等)->DriverManager->connection
參考資料:https://www.xuebuyuan.com/3222156.html
https://www.cnblogs.com/songyinan/p/7117245.html