JDBC,連接池,數(shù)據(jù)庫驅(qū)動的關(guān)系辑畦?使用JDBC簡化工具包DBUtils完成單表的增刪改查操作

連接池是優(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

圖1

配置文件:


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)系

圖2

注:接口(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.連接池原理【重點】

圖3
  • 目的:解決建立數(shù)據(jù)庫連接耗費資源和時間很多的問題逗堵,提高性能秉氧。

4.數(shù)據(jù)庫連接池API

4.1數(shù)據(jù)源接口


圖4

4.2數(shù)據(jù)源接口中的方法


圖5

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的使用
  • 方式一:通過硬編碼來編寫【了解】
    圖6
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目錄
    圖7

    配置文件:
    圖8
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的使用

  • 通過硬編碼來編寫(不需要配置文件.了解一下)
    圖9

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中(注:文件名一定不要寫錯,不要改)
    圖10

    配置文件:
<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ā)中常用)

圖11

配置文件:

<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概述

  1. DBUtils是java編程中的數(shù)據(jù)庫操作實用工具冬竟,小巧簡單實用。 第一個操作數(shù)據(jù)庫框架(jar),
  2. DBUtils封裝了對JDBC的操作民逼,簡化了JDBC操作流程泵殴,可以少寫代碼。
  3. 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é)果集處理類

圖12

6.4使用DBUtils完成數(shù)據(jù)庫的CRUD

6.4.1開發(fā)步驟:

  1. 創(chuàng)建項目疮鲫,并導(dǎo)入jar包
  2. 創(chuàng)建連接池
  3. 編寫測試類


    圖13

    連接池配置文件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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嚷往,一起剝皮案震驚了整個濱河市葛账,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌皮仁,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異贷祈,居然都是意外死亡趋急,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門势誊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呜达,“玉大人,你說我怎么就攤上這事粟耻〔榻” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵挤忙,是天一觀的道長霜威。 經(jīng)常有香客問我,道長册烈,這世上最難降的妖魔是什么戈泼? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮赏僧,結(jié)果婚禮上大猛,老公的妹妹穿的比我還像新娘。我一直安慰自己淀零,他們只是感情好挽绩,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著驾中,像睡著了一般琼牧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哀卫,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天巨坊,我揣著相機與錄音,去河邊找鬼此改。 笑死趾撵,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的共啃。 我是一名探鬼主播占调,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼移剪!你這毒婦竟也來了究珊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤纵苛,失蹤者是張志新(化名)和其女友劉穎剿涮,沒想到半個月后言津,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡取试,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年悬槽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞬浓。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡初婆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出猿棉,到底是詐尸還是另有隱情磅叛,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布萨赁,位于F島的核電站弊琴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏位迂。R本人自食惡果不足惜访雪,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掂林。 院中可真熱鬧臣缀,春花似錦、人聲如沸泻帮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锣杂。三九已至脂倦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間元莫,已是汗流浹背赖阻。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留踱蠢,地道東北人火欧。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像茎截,于是被迫代替她去往敵國和親苇侵。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345