JDBC&&c3p0、事務、批處理、多線程 於一體的經典秘方QueryRunner (common-dbutils)

来源:http://www.cnblogs.com/zyuqiang/archive/2017/07/24/7218083.html
-Advertisement-
Play Games

目錄: 基礎篇_功能各自回顧 JDBC基礎代碼回顧(使用JdbcUtils工具簡化) c3p0資料庫連接池的使用(使用JdbcUtils工具簡化) 大數據的插入(使用c3p0+JdbcUtils工具簡化) 批處理操作(使用c3p0+JdbcUtils工具簡化) 資料庫中的事務處理(使用c3p0+Jd ...



目錄:

基礎篇_功能各自回顧

         JDBC基礎代碼回顧(使用JdbcUtils工具簡化)                                                                  

         c3p0資料庫連接池的使用(使用JdbcUtils工具簡化)

         大數據的插入(使用c3p0+JdbcUtils工具簡化)

         批處理操作(使用c3p0+JdbcUtils工具簡化)

         資料庫中的事務處理(使用c3p0+JdbcUtils工具簡化)

        多線程的併發控制

進階篇_邁向標準開發
        自己編寫dbutils工具( QueryRunner 、TxQueryRunner和JdbcUtils)    (本文核心)

         封裝成jar包後的標準開發--common-dbutisl和itcast-tools    (本文核心)


 

資料庫使用MySQL資料庫,使用的表結構 :

1 CREATE TABLE tab_bin(
2     id     INT     PRIMARY KEY AUTO_INCREMENT,
3     filename    VARCHAR(100),
4     data     MEDIUMBLOB
5 );
tab_bin
1 CREATE TABLE t_user (
2   username varchar(50) DEFAULT NULL,
3   password varchar(50) DEFAULT NULL,
4   age int(11) DEFAULT NULL,
5   gender varchar(20) DEFAULT NULL
6 );
t_user
1 CREATE TABLE account (
2    id int(11) NOT NULL AUTO_INCREMENT,
3    NAME varchar(30) DEFAULT NULL,
4    balance decimal(10,0) DEFAULT NULL,
5    PRIMARY KEY (id)
6 ) ;
account
1 CREATE TABLE t_customer (
2   username VARCHAR(50) DEFAULT NULL,
3   age INT(11) DEFAULT NULL,
4   balance DOUBLE(20,5) DEFAULT NULL
5 );
t_customer

 


 

JDBC基礎代碼回顧

JDBC四大核心對象: 全部來自   java.sql    包下

DriverManager 註冊驅動,獲取Connection對象
Connection   連接對象,獲取preparedStatement
PreparedStatement sql語句發送器,執行更新、查詢操作
ResultSet 結果集,通過next()獲取結果

 

 

 

 

項目src文件下編寫dbconfig.properties配置文件:

name value
driverClassName com.mysql.jdbc.Driver
url jdbc:mysql://localhost:3306/jdbc_test01
username root
password 123456

 

 

 

 

 

 @演示

 1 package cn.kmust.jdbc.demo3.utils.version1;
 2 
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 import java.sql.Connection;
 6 import java.sql.DriverManager;
 7 import java.sql.SQLException;
 8 import java.util.Properties;
 9 /**
10  * JdbcUtils工具類
11  * @功能 從dbconfig.properties配置文件中獲取四大參數,載入驅動類,完成連接資料庫
12  *        返回Connection對象
13  *      
14  * @author ZHAOYUQIANG
15  *
16  */
17 public class JdbcUtils {
18     private static Properties props = null ;
19     /**
20      * 這些代碼都是只執行一次的,在JdbcUtils類被載入時執行
21      */
22     static{        
23         try{
24             /*
25              * 1. 載入dbconfig.properties配置文件裡面的內容到props中    
26              */
27             InputStream in= JdbcUtils.class.getClassLoader()
28                     .getResourceAsStream("dbconfig.properties");
29             props = new Properties();
30             props.load(in);    
31         }catch(IOException e){
32             throw new RuntimeException(e);
33         }
34         try{
35             /*
36              * 2. 載入驅動類
37              */
38             Class.forName(props.getProperty("driverClassName"));
39         }catch(ClassNotFoundException e){
40             throw new RuntimeException(e);
41         }
42     }
43     public static Connection getConnection() throws  SQLException{                    
44         /**
45          * 這些代碼可以被反覆調用,因為獲取資料庫連接可能需要多次獲取
46          */
47         /*
48          * 3. 調用DriverManager.getConnection()得到Connection
49          */
50         return DriverManager.getConnection(
51                 props.getProperty("url"),
52                 props.getProperty("username"),
53                 props.getProperty("password"));                        
54     }
55 }
JdbcUtils類_簡化代碼小工具
  1 package cn.kmust.jdbc.demo3.utils.version1;
  2 
  3 import java.sql.Connection;
  4 import java.sql.DriverManager;
  5 import java.sql.ResultSet;
  6 import java.sql.SQLException;
  7 import java.sql.PreparedStatement;
  8 
  9 import org.junit.Test;
 10 /**
 11  * 對資料庫的操作
 12  * @功能 更新操作 和 查詢操作 以及 測試
 13  *
 14  * @author ZHAOYUQIANG
 15  *
 16  */
 17 public class Demo {
 18      /**
 19       * 增、刪、改
 20       * @param username
 21       * @param password
 22       * @return
 23       */
 24      public void fun1(String username,String password,int age,String gender)   {
 25            Connection con = null ; 
 26            PreparedStatement pstmt = null ;
 27    
 28             try {
 29                 /*
 30                    * 1. 連接資料庫,給con賦值
 31                    * 2. 準備SQL語句
 32                    * 3. 調用 Connection對象的方法來得到PrepareStatement對象
 33                    * 4. 使用PrepareStatement對象給sql參數賦值
 34                    * 5. 使用PrepareStatement對象向資料庫發送sql語句,並且返回影響記錄的行數
 35                    * 6. 關閉資源。 後創建的先關閉
 36                    */                   
 37                    con = JdbcUtils.getConnection();
 38                    String sql ="INSERT INTO t_user VALUES (?,?,?,?)" ;  //sql語句中不加分號
 39 //                   String sql ="UPDATE t_user SET password=? WHERE username=?";
 40 //                   String sql ="DELETE FROM stu WHERE username=?";
 41                     pstmt = con.prepareStatement(sql);
 42                     pstmt.setString(1, username);
 43                     pstmt.setString(2, password);
 44                     pstmt.setInt(3, age);
 45                     pstmt.setString(4, gender);
 46                     int r = pstmt.executeUpdate();
 47                     System.out.println(r);    //輸出影響記錄的行數
 48             } catch (Exception e) {
 49                 throw new RuntimeException(e);            
 50             } finally{                
 51                 if (pstmt !=null) 
 52                     try{ pstmt.close();}catch (Exception e){throw new RuntimeException(e);}
 53                 if (con != null) 
 54                     try{ con.close();}catch (Exception e){throw new RuntimeException(e);}
 55             }                           
 56      }
 57      /**
 58       * 查詢資料庫
 59       */
 60       @Test
 61      public void  fun2() {
 62         Connection con = null ; 
 63         PreparedStatement pstmt = null ;
 64         ResultSet rs = null ;   
 65        try {
 66            /*
 67             * 1. 連接資料庫,給con賦值
 68             * 2. 準備SQL語句
 69             * 3. 調用 Connection對象的方法來得到PrepareStatement對象
 70             * 4. 使用PrepareStatement對象給sql參數賦值
 71             * 5. 使用PrepareStatement對象向資料庫發送sql語句,並且返回ResultSet對象的結果集(就是一個表)
 72             * 6. 調用ResultSet的boolean next()方法 遍歷結果集的每行記錄,方法返回的true和false代表游標指針所指的這一行有沒有記錄
 73             * 7. 調用ResultSet的getXXX(第幾列)/getXXX("列名字")方法  返回當前行記錄的列數據。其中,getObject和getString 能夠獲得所有的類型       
 74             * 8. 關閉資源。 後創建的先關閉
 75             */
 76             con = JdbcUtils.getConnection(); 
 77             String sql = "select * from t_user where username=? and password=? " ;
 78             pstmt = con.prepareStatement(sql);
 79             pstmt.setString(1, "zhaoLiu");
 80             pstmt.setString(2, "123456");                      
 81             rs=pstmt.executeQuery();
 82             while(rs.next()){        
 83                 String name = rs.getString(2);//可以用列名字 : String name = rs.getString("sname");
 84                 String password = rs.getString("password");    
 85                 int age = rs.getInt("age");
 86                 String gender = rs.getString("gender");
 87                 System.out.println("名字"+name+",密碼"+password+",年齡"+age+",性別"+gender);
 88            }
 89         } catch (Exception e) {
 90             throw new RuntimeException(e);
 91         } finally{
 92             if (rs != null)
 93                 try{ rs.close();}catch (Exception e){throw new RuntimeException(e);}
 94             if (pstmt !=null) 
 95                 try{ pstmt.close();}catch (Exception e){throw new RuntimeException(e);}
 96             if (con != null) 
 97                 try{ con.close();}catch (Exception e){throw new RuntimeException(e);}
 98        }        
 99       }
100 
101       /**
102        *  測試增刪改 
103        */
104       @Test
105       public void fun1Test(){
106           String username="zhaoLiu" ;
107           String password ="123456";
108           int age = 12 ;
109           String gender = "男";
110           fun1(username,password,age,gender);
111       }    
112 }
Dao類_操作/測試資料庫

c3p0資料庫連接池的使用

c3p0資料庫連接池 :   資料庫的很多連接對象都放在池中被管理著,誰用誰去租,用完歸還就行了。 c3p0就是一個比較不錯的池子 。

DataSource對象也在 java.sql  包下

項目src文件下編寫c3p0-config.xml配置文件(文件中也給出了oracle的配置模版):(@註意:配置文件的名稱c3p0-config.xml是一個官方給定的標準,不是隨意起的名字)

@演示

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <c3p0-config>
 3     <default-config><!-- 這是預設的配置信息 -->
 4         <!-- 連接四大參數配置 -->
 5         <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc_test01</property>
 6         <property name="driverClass">com.mysql.jdbc.Driver</property>
 7         <property name="user">root</property>
 8         <property name="password">123456</property>
 9         <!-- 池本身的參數配置 -->
10         <property name="acquireIncrement">3</property>
11         <property name="initialPoolSize">10</property>
12         <property name="minPoolSize">2</property>
13         <property name="maxPoolSize">10</property>
14     </default-config>
15     
16     <!-- 專門為oracle準備的配置信息 -->
17     <!-- 這也是命名配置信息,在JDBC中創建連接池對象的時候要加 oracle-config這個參數-->
18     <named-config name="oracle-config">
19         <property name="jdbcUrl">  oracle的url   </property>
20         <property name="driverClass">  oracle的驅動   </property>
21         <property name="user">    oracle的用戶 </property>
22         <property name="password">    密碼</property>
23         <property name="acquireIncrement">3</property>
24         <property name="initialPoolSize">10</property>
25         <property name="minPoolSize">2</property>
26         <property name="maxPoolSize">10</property>
27     </named-config>
28     
29 </c3p0-config>
c3p0-config.xml
 1 package cn.kmust.jdbc.demo9.c3p0Pool.utils.version2;
 2 
 3 import java.sql.Connection;
 4 import java.sql.SQLException;
 5 
 6 import javax.sql.DataSource;
 7 
 8 import com.mchange.v2.c3p0.ComboPooledDataSource;
 9 /**
10  * JdbcUtils工具類     [c3p0資料庫連接池專用工具類]
11  *   需要編寫c3p0-config.xml配置文件
12  * @功能 利用c3p0-config.xml配置文件獲取連接對象並且返回 。 連接池對象也返回
13  * @c3p0說明   借用池中的Connection對象,用完歸還
14  *           需要編寫c3p0-config.xml文件,裡面有四大連接參數和池子本身的參數配置
15  *           文件不需要說明在什麼位置,因為在創建連接池對象時,這個對象會自動載入配置文件
16  * @author ZHAOYUQIANG
17  *
18  */
19 public class JdbcUtils {
20     /*
21      * 1. 創建連接池對象
22      *      創建時自動載入c3p0-config.xml配置文件
23      *      如果是配置文件中是命名配置,如oracle,那麼構造器的參數指定命名配置為元素的名稱,也就是說代碼要變成如下形式:
24      *            ComboPooledDataSource dataSource = new ComboPooledDataSource("oracle-config");
25      */
26     private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
27     /**
28      * 使用連接池返回一個連接對象
29      * @return
30      * @throws SQLException
31      */
32     public static Connection getConnection() throws SQLException{
33         return dataSource.getConnection();
34     }
35     /**
36      * 返回池對象
37      * @return
38      */
39     public static DataSource getDataSource(){
40         return dataSource;
41     }
42 }
JdbcUtis工具類_c3p0版本
 1 package cn.kmust.jdbc.demo9.c3p0Pool.utils.version2;
 2 
 3 import java.beans.PropertyVetoException;
 4 import java.sql.Connection;
 5 import java.sql.SQLException;
 6 
 7 import org.junit.Test;
 8 
 9 import com.mchange.v2.c3p0.ComboPooledDataSource;
10 
11 /**
12  * Test
13  * @功能  通過JdbcUtils工具獲取池子中的一個連接對象,並且輸出這個連接,查看是否獲取到了
14  *
15  * @author ZHAOYUQIANG
16  *
17  */
18 public class Demo01 {
19     @Test
20     public void fun() throws SQLException {
21         /*
22          * 1. 通過c3p0專屬的JdbcUtils工具[版本2]直接獲取連接
23          * 2. 把連接歸還給池子
24          */
25         Connection con = JdbcUtils.getConnection();
26         /**
27          * 此處代碼進行sql的操作,本次省略。
28          */
29         System.out.println(con);
30         con.close();
31     }
32 }
Test類_查看獲取的連接

大數據的插入(使用c3p0+JdbcUtls簡化代碼)

 @解決的問題  如何向mysql中插入一部10M左右的.mp3文件 ???

MySQL中提供存儲大數據的類型如下:(@註意 標準SQL中提供的類型並非如下類型,請自行百度)

類型  長度
tinytext 28-1 B(256B)
text 216-1B(64K)
mediumtext 224-1B(16M)
longtext 232-1B(4G)

 

 

 

 

 

待插入文件地址 : D:\十年.mp3

待下載文件地址: E:\十年.mp3

@使用 c3p0資料庫連接池的使用 中的c3p0-config.xml 和JdbcUtils工具

@演示 

 1 package cn.kmust.jdbc.demo4.bigData;
 2 
 3 import java.io.FileInputStream;
 4 import java.io.FileOutputStream;
 5 import java.io.InputStream;
 6 import java.io.OutputStream;
 7 import java.sql.Blob;
 8 import java.sql.Connection;
 9 import java.sql.PreparedStatement;
10 import java.sql.ResultSet;
11 
12 import javax.sql.rowset.serial.SerialBlob;
13 
14 import org.apache.commons.io.IOUtils;
15 import org.junit.Test;
16 
17 import cn.kmust.jdbc.demo3.utils.version1.JdbcUtils;
18 
19 /**
20  * 大數據,把mp3保存到mysql資料庫的表中
21  *
22  * @author ZHAOYUQIANG
23  *
24  */
25 public class BigData{
26     /**
27      * 把tmp3保存到資料庫中
28      */
29     @Test
30     public void fun1(){
31         Connection con = null ; 
32         PreparedStatement pstmt = null ;
33         try{
34             con = JdbcUtils.getConnection();
35             String sql = "insert into tab_bin values(?,?,?)";
36             pstmt =con.prepareStatement(sql);
37             pstmt.setInt(1, 1);
38             pstmt.setString(2,"十年.mp3");
39             /**
40              * 向資料庫中存入mp3音樂
41              *    資料庫中存儲音樂的類型是要用大小是0~16MB的Blob類型
42              *    要做的事情是把硬碟中.mp3文件變成Blob類型,然後存入到資料庫中
43              */
44             /*
45              * 1. 將流文件變成位元組數組
46              *      導入小工具包: Commons-io.jar
47              * 2. 使用位元組數組創建Blob對象
48              */
49             byte[] bytes = IOUtils.toByteArray(new FileInputStream("D:/十年.mp3"));    
50             Blob blob = new SerialBlob(bytes) ; 
51             pstmt.setBlob(3, blob);
52
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一 概述 1.整合目的 將所有對象的創建與管理任務交給Spring容器,降低程式的耦合度。 2.整合途徑 將Spring容器註入到Web容器中。 3.具體實現 使用ServletContextListener監聽ServletContext,當ServletContexxt創建時同時創建Spring ...
  • 經典數據集CIFAR-10,60000張32x32彩色圖像,訓練集50000張,測試集10000張。標註10類,每類圖片6000張。airplance、automobile、bird、cat、deer、dog、frog、horse、ship、truck。沒有任何重疊。CIFAR-100,100類標註 ...
  • 載入MNIST數據集。創建預設Interactive Session。 初始化函數,權重製造隨機雜訊打破完全對稱。截斷正態分佈雜訊,標準差設0.1。ReLU,偏置加小正值(0.1),避免死亡節點(dead neurons)。 捲積層函數,tf.nn.conv2d,TensorFlow 2 維捲積函數 ...
  • 題目原文: An inversion in an array a[] is a pair of entries a[i] and a[j] such that i<j but a[i]>a[j]. Given an array, design a linearithmic algorithm to ...
  • 一 概述 1.整合目的 在Hibernate中,SessionFactory是一個重量級對象,創建與初始化會耗費大量的資源,應該減少對象的創建次數,並且SessionFactory線程安全,可以採用單例模式,如果將對象的創建任務交給Spring容器就解決了這個問題。 二 實現 1.配置Session ...
  • 第一步:註冊微信支付賬戶,開通掃碼支付 具體流程請參照官方說明 第二步:創建Maven項目 1. 添加微信支付SDK依賴、二維碼工具依賴(微信支付需要自己通過二維碼工具生成支付二維碼) <!-- 微信支付 --> <dependency> <groupId>com.github.wxpay</gro ...
  • 引言 本文以簡單的示例輔助闡述面向對象設計的五個基本原則。 概念 在程式設計領域, SOLID(單一功能、開閉原則、里氏替換、介面隔離以及依賴反轉)是由羅伯特·C·馬丁在21世紀早期引入的記憶術首字母縮略字, 指代了面向對象編程和麵向對象設計的五個基本原則。當這些原則被一起應用時,它們使得一個程式員 ...
  • 顯式與隱式(Explicit And Implicit) 1.概念 1.1 顯式 實現的單詞Explicit意思是清楚的、明確的、詳述的。所以,顯式的“顯”是指明顯且清楚的實現,相對於介面來說,就是明顯而清楚的指定了介面的實現。對於其他的邏輯來說,顯式就是清楚且明確的指定了實現內容。 1.2 隱式 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...