DBUtils 學習使用

来源:https://www.cnblogs.com/798911215-Darryl-Tang/archive/2018/06/01/9123228.html
-Advertisement-
Play Games

DBUtils 學習使用 commons-dbutils簡介 commons-dbutils是Apache組織提供的一個開源JDBC工具類庫,它是對JDBC的簡單封裝,學習成本極低,並且使用dbutils能極大簡化jdbc編碼的工作量,同時也不會影響程式的性能。因此dbutils成為很多不喜歡hib ...


DBUtils 學習使用

commons-dbutils簡介

commons-dbutils是Apache組織提供的一個開源JDBC工具類庫,它是對JDBC的簡單封裝,學習成本極低,並且使用dbutils能極大簡化jdbc編碼的工作量,同時也不會影響程式的性能。因此dbutils成為很多不喜歡hibernate的公司的首選。 dbutils的官方網站http://commons.apache.org/proper/commons-dbutils/download_dbutils.cgi

image

dbutils 優點

  1. 對於數據表的讀操作,他可以把結果轉換成List,Array,Set等java集合,便於程式員操作;
  2. 對於數據表的寫操作,也變得很簡單(只需寫sql語句)
  3. 可以使用數據源,使用JNDI,資料庫連接池(dbcp,c3p0)等技術來優化性能--重用已經構建好的資料庫連接對象,而不像php,asp那樣,費時費力的不斷重覆的構建和析構這樣的對象。

commons-dbutils API介紹

  • org.apache.commons.dbutils.QueryRunner QueryRunner (insert、update、delete使用)
  • org.apache.commons.dbutils.ResultSetHandler (用於查詢結果處理使用)
  • org.apache.commons.dbutils.DbUtils (工具類)

QueryRunner 類的主要方法

  • public Object query(Connection conn, String sql, Object[] params, ResultSetHandler rsh) throws SQLException

執行一個查詢操作,在這個查詢中,對象數組中的每個元素值被用來作為查詢語句的置換參數。該方法會自行處理PreparedStatement和ResultSet的創建和關閉。

  • public Object query(String sql, Object[] params, ResultSetHandler rsh) throws SQLException

幾乎與第一種方法一樣;唯一的不同在於它不將資料庫連接提供給方法,並且它是從提供給構造方法的數據源(DataSource)或使用的setDataSource方法中重新獲得Connection。

  • public Object query(Connection conn, String sql, ResultSetHandler rsh) throws SQLException

執行一個不需要置換參數的查詢操作。

  • public int update(Connection conn, String sql, Object[] params) throws SQLException

用來執行一個更新(插入、更新或刪除)操作。

  • public int update(Connection conn, String sql) throws SQLException

用來執行一個不需要置換參數的更新操作。

  • public int[] batch(Connection conn, String sql, Object[][] params) throws SQLException

這個方法對應著批處理,經常用於在同一個表中批量插入數據,或批量更新表的數據。 該方法為何會接收二維數組Object[][] params呢? 答:例如現在要想在同一個表中批量插入數據,編寫的SQL語句為:

  String sql = "insert into users(id,name) values(?,?)";

該方法接收二維數組Object[][] params,那麼調用其的時候就要傳遞一個諸如這樣的實參[[1,aa],[2,bb],[3,cc]],即用二維數組裡面的每一個一維數組生成一條sql語句。 那為何又會返回int[]呢? 答:該方法的返回值是int[],所以會返回諸如這樣的結果:[1,1,1],意思是生成的第一條sql語句影響資料庫幾行、生成的第二條sql語句影響資料庫幾行、生成的第三條sql語句影響資料庫幾行。

ResultSetHandler介面使用講解

該介面用於處理java.sql.ResultSet,將數據按要求轉換為另一種形式。ResultSetHandler介面提供了一個單獨的方法:Object handle (java.sql.ResultSet .rs)

ResultSetHandler介面的實現類

  • ArrayHandler:把結果集中的第一行數據轉成對象數組。
  • ArrayListHandler:把結果集中的每一行數據都轉成一個數組,再存放到List中。
  • BeanHandler:將結果集中的第一行數據封裝到一個對應的JavaBean實例中。
  • BeanListHandler:將結果集中的每一行數據都封裝到一個對應的JavaBean實例中,存放到List里。
  • ColumnListHandler:將結果集中某一列的數據存放到List中。
  • KeyedHandler(name):將結果集中的每一行數據都封裝到一個Map里,再把這些map再存到一個map里,其key為指定的key。
  • MapHandler:將結果集中的第一行數據封裝到一個Map里,key是列名,value就是對應的值。
  • MapListHandler:將結果集中的每一行數據都封裝到一個Map里,然後再存放到List。

DbUtils類使用講解

DbUtils:提供如關閉連接、裝載JDBC驅動程式等常規工作的工具類,裡面的所有方法都是靜態的。主要方法如下:

  • public static void close(…) throws java.sql.SQLException DbUtils類提供了三個重載的關閉方法。這些方法檢查所提供的參數是不是NULL,如果不是的話,它們就關閉Connection、Statement和ResultSet。
  • public static void closeQuietly(…) 這一類方法不僅能在Connection、Statement和ResultSet為NULL情況下避免關閉,還能隱藏一些在程式中拋出的SQLException。
  • public static void commitAndCloseQuietly(Connection conn) 用來提交連接,然後關閉連接,並且在關閉連接時不拋出SQL異常。
  • public static boolean loadDriver(java.lang.String driverClassName) 這一方法裝載並註冊JDBC驅動程式,如果成功就返回true。使用該方法,你不需要捕捉這個異常ClassNotFoundException。

使用DBUtils完成資料庫的CRUD

在使用DBUtils完成資料庫的CRUD之前,我們先編寫測試用的SQL腳本:

CREATE TABLE `user` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  `age` tinyint(10) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

使用dbutils遵從以下步驟

  1. 載入JDBC驅動程式類,並用DriverManager來得到一個資料庫連接conn。
  2. 實例化 QueryRunner,得到實例化對象qRunner。
  3. qRunner.update()方法,執行增改刪的sql命令,qRunner.query()方法,得到結果集。

獲取連接對象

private static final String url = "jdbc:mysql://192.168.1.15:3306/test?useUnicode=true&characterEncoding=utf8";
private static final String driver = "com.mysql.jdbc.Driver";
private static final String user = "znsd_test";
private static final String password = "123456";

public static Connection getConnect() {
    Connection conn = null;
    try {
        Class.forName(driver);
        conn = DriverManager.getConnection(url, user, password);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return conn;
}

創建bean對象關聯資料庫

public class User implements Serializable {
    private Integer id; // 用戶ID
    private String name; // 用戶姓名
    private Integer age;  // 用戶年齡
    // ...忽略set、get方法
}

添加

public Integer add(User user) {
        QueryRunner queryRunner = new QueryRunner();
        Connection connect = ConnectionUtil.getConnect();
        try {
            return queryRunner.update(connect, "insert into user(name, age) values(?, ?)", user.getName(), user.getAge());
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(connect);
        }
        return 0;
}

修改

public Integer update(User user) {

        QueryRunner queryRunner = new QueryRunner();
        Connection conn = ConnectionUtil.getConnect();
        try {
            return queryRunner.update(conn , "update user set name = ?, age = ? where id = ?", user.getName(), user.getAge(), user.getId());
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(conn);
        }
        return 0;
}

刪除

public Integer delete(Integer id) {

        QueryRunner queryRunner = new QueryRunner();
        Connection conn = ConnectionUtil.getConnect();
        try {
            return queryRunner.update(conn , "delete from user where id = ?", id);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(conn);
        }
        return 0;
}

批量添加

public int[] batch(Object[][] values) {

        QueryRunner queryRunner = new QueryRunner();
        Connection conn = ConnectionUtil.getConnect();
        try {
            return queryRunner.batch(conn, "insert into user(name, age) values(?, ?)", values);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(conn);
        }
        return null;
}

查詢所有

public List<User> select() {

        QueryRunner queryRunner = new QueryRunner();
        Connection conn = ConnectionUtil.getConnect();
        try {
            return queryRunner.query(conn, "select id id1, name, age from user", new UserBeanListHandler(User.class));
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(conn);
        }
        return null;
}

查詢返回map

public List<Map<String, Object>> selectAsMap() {

        QueryRunner queryRunner = new QueryRunner();
        Connection conn = ConnectionUtil.getConnect();
        try {
            List<Map<String, Object>> userMaps = queryRunner.query(conn, "select id id1, name, age from user", new MapListHandler());
            return userMaps;
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(conn);
        }
        return null;
}

查詢單個對象

public User selectOne(Integer id) {

        QueryRunner queryRunner = new QueryRunner();
        Connection conn = ConnectionUtil.getConnect();
        try {
            return queryRunner.query(conn, "select id id1, name, age from user where id = ? limit 1", new BeanHandler<User>(User.class) {
                @Override
                public User handle(ResultSet rs) throws SQLException {
                    if (rs.next()) {
                        return new User(rs.getInt("id1"), rs.getString("name"), rs.getInt("age"));
                    }
                    return null;
                }
            }, id);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(conn);
        }
        return null;
}

結合c3p0數據源使用dbutils

c3p0簡介

C3P0是一個開源的JDBC連接池,它實現了數據源和JNDI綁定,支持JDBC3規範和JDBC2的標準擴展。目前使用它的開源項目有Hibernate,Spring等

資料庫連接池簡介

資料庫連接池負責分配、管理和釋放資料庫連接,它允許應用程式重覆使用一個現有的資料庫連接,而不是再重新建立一個;連接池允許多個客戶端使用緩存起來的連接對象,這些對象可以連接資料庫,它們是共用的、可被重覆使用的。

打開/關閉資料庫連接開銷很大,連接池技術允許我們在連接池裡維護連接對象,這樣可以提高資料庫的執行命令的性能。多個客戶端請求可以重覆使用相同的連接對象,當每次收到一個客戶端請求時,就會搜索連接池,看看有沒有閑置的連接對象。如果沒有閑置對象的話,要麼所有的客戶端請求都進入隊列排隊,要麼在池中創建一個新的連接對象(這取決於池裡已經有多少個連接存在以及配置支持多少連接)。一旦某個請求使用完連接對象之後,這個對象會被重新放入池中,然後會被重新分派給排隊等待的請求(分派給哪個請求要看使用什麼調度演算法)。因為大部分請求都是使用現存的連接對象,所以連接池技術大大減少了等待創建資料庫連接的時間,從而減少了平均連接時間。

20171021162546066

使用連接池的優點

  • 資源重用:

由於資料庫連接得以重用,避免了頻繁創建,釋放連接引起的大量性能開銷。在減少系統消耗的基礎上,另一方面也增加了系統運行環境的平穩性。

  • 更快的系統反應速度:

資料庫連接池在初始化過程中,往往已經創建了若幹資料庫連接置於連接池中備用。此時連接的初始化工作均已完成。對於業務請求處理而言,直接利用現有可用連接,避免了資料庫連接初始化和釋放過程的時間開銷,從而減少了系統的響應時間。

  • 統一的連接管理,避免資料庫連接泄露:

在較為完善的資料庫連接池實現中,可根據預先的占用超時設定,強制回收被占用連接,從而避免了常規資料庫連接操作中可能出現的資源泄露。

使用步驟

  1. 首先要導入c3p0和dbutils以及mysql的jar包
  • c3p0-0.9.5.2.jar
  • commons-dbutils-1.7.jar
  • mchange-commons-java-0.2.11.jar
  • mysql-connector-java-5.1.22.jar
  1. 編寫c3p0的配置文件c3p0-config.xml

在src目錄下存放c3p0的配置文件,配置文件是c3p0自己去識別並讀入的,我們不需要在代碼中做任何的操作,但是配置文件一定要命名為c3p0-config.xml

   <?xml version="1.0" encoding="UTF-8"?>
   <c3p0-config>
    <!-- 這是預設配置信息 -->
    <default-config>
        <!-- jdbc連接四大參數配置 -->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://192.168.1.15:3306/test</property>
        <property name="user">znsd_test</property>
        <property name="password">123456</property>

        <!-- 池參數配置 -->
        <!--JDBC的標準參數,用以控制數據源內載入的PreparedStatements數量。但由於預緩存的statements
            屬於單個connection而不是整個連接池。所以設置這個參數需要考慮到多方面的因素。
            如果maxStatements與maxStatementsPerConnection均為0,則緩存被關閉。Default: 0
        -->
        <property name="acquireIncrement">3</property>
        <!--初始化時獲取的連接數,取值應在minPoolSize與maxPoolSize之間。Default: 3 -->
        <property name="initialPoolSize">10</property>
        <!--連接池中保留的最小連接數。-->
        <property name="minPoolSize">2</property>
        <!--連接池中保留的最大連接數。Default: 15 -->
        <property name="maxPoolSize">10</property>
    </default-config>
   </c3p0-config>
  1. 使用c3p0獲取獲取資料庫連接對象
   public class C3p0ConnectionUtil {

    // 配置文件的預設配置!要求你必須給出c3p0-config.xml
    private static ComboPooledDataSource c3p0DataSource = new ComboPooledDataSource();

    /**
     * 獲取連接對象
     * @return
     */
    public static Connection getConnection() {
        try {
            // 得到連接器
            return c3p0DataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 獲取數據源
     * 
     * @return
     */
    public static DataSource getDataSource() {
        return c3p0DataSource;
    }
   }
  1. dbutils 使用c3p0
   public Integer add(User user) {
        QueryRunner queryRunner = new QueryRunner(C3p0ConnectionUtil.getDataSource());
        try {
            return queryRunner.update("insert into user(name, age) values(?, ?)", user.getName(), user.getAge());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
   }
  1. 返回主鍵例子
   public Integer add(User user) {
        DataSource dataSource = C3p0ConnectionUtil.getDataSource();
        QueryRunner queryRunner = new QueryRunner(dataSource);
        try {
            String sql = "insert into user(name, age) values(?, ?)";
                // 需要條用insert方法,指定MapHandler參數
            Map<String, Object> idMap = queryRunner.insert(sql, new MapHandler() {

                @Override
                public Map<String, Object> handle(ResultSet rs) throws SQLException {

                    //rs = rs.getStatement().getGeneratedKeys();
                        // 獲取主鍵
                    int id = rs.next() ? rs.getInt(1) : -1;
                    // 將資料庫返回主鍵放入map中
                    Map<String, Object> idMap = new HashMap<String, Object>();
                    idMap.put("id", id);

                    return idMap;
                }
            }, user.getName(), user.getAge());

            return (Integer) idMap.get("id");
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
   }

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 問題1:無法安裝手機驅動, 解決方法:安裝強大的豌豆莢,通常能都能解決問題 問題2: adb devices 時出現 adb devicesadb server is out of date. killing... ADB server didn't ACK* failed to start dae ...
  • 鄭重承諾:該激活軟體沒有病毒,有任何侵害行為,找我QQ:122317653 Step one: 首先你需要安裝KMS Auto Net激活器,但我們都知道一些殺毒軟體都會將此類激活器警告成木馬病毒,原因:嘿嘿,讓你激活了,windows豈不是虧了?所以,你需要先關閉殺毒軟體,比如360,你需要在右下 ...
  • 不同linux系統,相關軟體是否安裝,會讓iptables的某些命令不能執行,這裡收集了大多數iptables命令,不管是Ubuntu還是Centos,都能找到相關的修改、查詢、保存命令。 ...
  • 1:右鍵菜單點"標記"; 2:按住左鍵選文字; 3:選完右鍵點一下! (關鍵一步,只需點一下就好!!) so 待選文字就跑到剪切板上了 ...
  • 資料庫表和值 -- 4、查詢沒學過關羽老師課的同學的學號、姓名 步驟一SELECT c.id FROM teacher t,course c WHERE t.id=c.teacher_id AND t.name="關羽" 步驟二 SELECT DISTINCT s.id FROM student s ...
  • 10-1 elasticsearch介紹 目前在使用es的大公司: https://www.elastic.co/use-cases Mongodb redis 在 elasticsearch面前就是一個玩笑 哈哈! 10-2 elasticsearch安裝 10-3elasticsearch-he ...
  • 需要學習的同學可以通過網盤下載pdf: http://tadown.com/fs/dyib0ensehucedd08/內容簡介 · · · · · · mongodb如何幫你管理通過web應用收集的海量數據呢?通過本書的權威解讀,你會瞭解面向文檔資料庫的諸多優點,會發現mongodb如此穩定、性能優 ...
  • 一、準備 1、關閉cdh中的服務 hdfs、yarn等所有服務;關閉 cm-server、cm-agent;備份cm元資料庫。 2、下載 CDH-5.13.3-1.cdh5.13.3.p0.2-el7.parcel CDH-5.13.3-1.cdh5.13.3.p0.2-el7.parcel.sha ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...