Commons DbUtils 使用總結

jopen 11年前發布 | 27K 次閱讀 DbUtils 持久層框架

DBUtils是個小巧的JDBC輕量級封裝的工具包,其最核心的特性是結果集的封裝,可以直接將查詢出來的結果集封裝成JavaBean,這就為我們做了最枯燥乏味、最容易出錯的一大部分工作。
  在使用DBUtils之前,應該注意一些問題:
  1、DBUtils是JDBC的簡單封裝,可以和JDBC混合使用。
  2、DBUtils對結果集自動封裝為JavaBean是有著苛刻要求的:必須滿足JavaBean的規范,其次Bean的getter與setter方法的名字與結果集的列名一一對應,而不要求JavaBean的私有成員與表結果集列名一一對應。
  比如:
  person表中有個字段叫:address,那么對應的JavaBean的Person類中必須有getAddress和setAddress兩個方法,而Person類中可以將address屬性命名為add,這是沒問題的。
  3、DBUtils可以將結果集封裝為各種類型,主要有:Bean/List<Bean>,Map/List<Map>/Map<Map>,數組/List<數組>,列/List<列>,這些類型。
  對于Map<Map>的類型使用KeyedHandler作為結果集處理器,內層的Map是“列名-值"對,外層的Map是“主鍵-內層Map的引用”,但此處的主鍵不一定就是數據庫的主鍵,可以隨意指定,比如:
  ResultSetHandler h = new KeyedHandler("id");
  Map found = (Map) queryRunner.query("select id, name, age from person", h);
  Map jane = (Map) found.get(new Long(1)); // jane's id is 1
  String janesName = (String) jane.get("name");
  Integer janesAge = (Integer) jane.get("age");
  4、DBUtils執行插入操作的時候,無法返回自增主鍵,這是一個很嚴重的問題,當然不能怪DBUtils,可以通過變通的方法來實現,比如在MySQL中,執行完了一個插入SQL后,接著執行SELECT LAST_INSERT_ID()語句,就可以獲取到自增主鍵。
  5、DBUtils的性能和JDBC性能是一樣,測試過程中沒發現性能損失,擁有了很高性能的同時,而不失JDBC的靈活性。
  6、對于JavaBean的成員類型定義,有一條原則那就是:盡可能使用包裝類型,而不要使用基本類型。很多人不理解為什么,包括我見到一些傻B(,我提出讓改為包裝類型,他還信誓旦旦的說他的代碼多牛多叼),都干好多年了,這個簡單的道理還不知道:

        //錯誤
        int a1 = (Integer) null;
        boolean x1 = (Boolean)null;
        //正確
        Integer a2 = (Integer) null;
        Boolean x2 = (Boolean)null;
實際上就是為了保證在查詢結果為null的時候,也不會因為給基本類型賦null值而發生錯誤。
下面給出一個簡單例子,作為以后寫代碼時候有點參考:
環境:
MySQL5.4
JDK1.5
建表SQL:
CREATE TABLE person (
     id bigint(20) NOT NULL AUTO_INCREMENT,
     name varchar(24) DEFAULT NULL,
     age int(11) DEFAULT NULL,
     address varchar(120) DEFAULT NULL,
     PRIMARY KEY (id)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=gbk
Java代碼:
public class Person {
        private Long id;
        private String sdf;
        private String address2;
        private Integer age;
        public Person() {
        }
        public Person(String sdf) {
                this.sdf = sdf;
        }
        public Person(String sdf, Integer age, String address) {
                this.sdf = sdf;
                this.age = age;
                this.address2 = address;
        }
        public Long getId() {
                return id;
        }
        public void setId(Long id) {
                this.id = id;
        }
        public String getSdf() {
                return sdf;
        }
        public void setSdf(String sdf) {
                this.sdf = sdf;
        }
        public Integer getAge() {
                return age;
        }
        public void setAge(Integer age) {
                this.age = age;
        }
        public String getAddress() {
                return address2;
        }
        public void setAddress(String address2) {
                this.address2 = address2;
        }
}
測試
package com.lavasoft.dbstu;
import com.lavasoft.common.DBToolkit;
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.MapHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
/**

  • Created by IntelliJ IDEA.
    *
  • @author leizhimin 2010-1-25 21:00:29
    /
    public class PersonDAOImpl implements PersonDAO {
            private static PersonDAOImpl instance = new PersonDAOImpl();
            public static PersonDAOImpl getInstance() {
                    return instance;
            }
            public static void main(String[] args) {
                    //錯誤
                    int a1 = (Integer) null;
                    boolean x1 = (Boolean) null;
                    //正確
                    Integer a2 = (Integer) null;
                    Boolean x2 = (Boolean) null;
                    getInstance().save(null);
    //                getInstance().save(null);
    //                getInstance().save(null);
    //                getInstance().save(null);
    //                getInstance().save(null);
                    getInstance().update(null);
                    getInstance().load(null);
                    getInstance().load4Map(null);
            }
            @Override
            public Long save(String sql) {
                    Long id = null;
                    String ins_sql = "INSERT INTO person (NAME, age, address) VALUES ('aaa', 21, 'address001')";
                    Connection conn = DBToolkit.getConnection();
                    QueryRunner qr = new QueryRunner();
                    try {
                            qr.update(conn, ins_sql);
                            //獲取新增記錄的自增主鍵
                            id = (Long) qr.query(conn, "SELECT LAST_INSERT_ID()", new ScalarHandler(1));
                    } catch (SQLException e) {
                            e.printStackTrace();
                    } finally {
                            DBToolkit.closeConnection(conn);
                    }
                    return id;
            }
            @Override
            public int delete(Long id) {
                    int x = 0;
                    Connection conn = DBToolkit.getConnection();
                    QueryRunner qr = new QueryRunner();
                    try {
                            x = qr.update(conn, "DELETE FROM person WHERE id = ?", id);
                    } catch (SQLException e) {
                            e.printStackTrace();
                    } finally {
                            DBToolkit.closeConnection(conn);
                    }
                    return x;
            }
            @Override
            public int update(Person person) {
                    int x = 0;
                    Connection conn = DBToolkit.getConnection();
                    QueryRunner qr = new QueryRunner();
                    try {
                            x = qr.update(conn, "UPDATE person SET NAME = ?, age = ?, address = ? WHERE id = ?", "xxx", 23, "ttt", 5);
                    } catch (SQLException e) {
                            e.printStackTrace();
                    } finally {
                            DBToolkit.closeConnection(conn);
                    }
                    return x;
            }
            @Override
            public Person load(Long id) {
                    Connection conn = DBToolkit.getConnection();
                    QueryRunner qr = new QueryRunner();
                    try {
                            Person person = (Person) qr.query(conn, "SELECT
    FROM person where id = ?", new BeanHandler(Person.class), 3L);
                            System.out.println(person.getId() + "\t" + person.getSdf() + "\t" + person.getAge() + "\t" + person.getAddress());
                    } catch (SQLException e) {
                            e.printStackTrace();
                    }
                    return null;
            }
            @Override
            public List<Person> findPerson(String sql) {
                    Connection conn = DBToolkit.getConnection();
                    QueryRunner qr = new QueryRunner();
                    try {
                            List<Person> pset = (List) qr.query(conn, "SELECT FROM person", new BeanListHandler(Person.class));
                            for (Person person : pset) {
                                    System.out.println(person.getId() + "\t" + person.getSdf() + "\t" + person.getAge() + "\t" + person.getAddress());
                            }
                    } catch (SQLException e) {
                            e.printStackTrace();
                    }
                    return null;
            }
            public Person load4Map(Long id) {
                    Connection conn = DBToolkit.getConnection();
                    QueryRunner qr = new QueryRunner();
                    try {
                            //先將兩個字段置為null
                            qr.update(conn, "update person set age = null,address =null where id =1");
                            Map<String, Object> map = qr.query(conn, "SELECT
    FROM person where id = ?", new MapHandler(), 1L);
                            Person person = new Person();
                            person.setId((Long) map.get("id"));
                            person.setSdf((String) map.get("name"));
                            person.setAge((Integer) map.get("age"));
                            person.setAddress((String) map.get("address"));
                            System.out.println(person.getId() + "\t" + person.getSdf() + "\t" + person.getAge() + "\t" + person.getAddress());
                    } catch (SQLException e) {
                            e.printStackTrace();
                    }
                    return null;
            }
    }
    注意:
    從上面的過程看,每個SQL的執行都需要用到QueryRunner,這其實是一個普通的類,非線程安全。在創建這個QueryRunner對象的時候,每次都要new。
    QueryRunner對象的創建方式很多,可以通過DateSource,也可以通過Connection來創建。從QueryRunner對象上,可以直接獲取到DataSource或者Connection對象。
    Dbutil 的使用示例
    代碼
    package cn.lining.test;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.util.List;
    import java.util.Map;
    import org.apache.commons.dbutils.DbUtils;
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.ArrayHandler;
    import org.apache.commons.dbutils.handlers.ArrayListHandler;
    import org.apache.commons.dbutils.handlers.BeanHandler;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    import org.apache.commons.dbutils.handlers.ColumnListHandler;
    import org.apache.commons.dbutils.handlers.KeyedHandler;
    import org.apache.commons.dbutils.handlers.MapHandler;
    import org.apache.commons.dbutils.handlers.MapListHandler;
    import org.apache.commons.dbutils.handlers.ScalarHandler;
    public class test {
     @SuppressWarnings("unchecked")
     public static void main(String[] args) throws ClassNotFoundException {
      UserField userField = new UserField();
      Connection conn = null;
      String jdbcURL = "jdbc:mysql://localhost:3306/macaw4";
      String jdbcDriver = "com.mysql.jdbc.Driver";
      try {
       DbUtils.loadDriver(jdbcDriver);
       conn = DriverManager.getConnection(jdbcURL, "root", "root");
       conn.setAutoCommit(false);//關閉自動提交
       QueryRunner qRunner = new QueryRunner();
       // 以下部分代碼采用MapHandler存儲方式查詢
       System.out.println("Using MapHandler");
       Map map = (Map) qRunner.query(conn,
         "select from mc_user_field where id = ?",
         new MapHandler(), new Object[] { "5" });
       System.out.println("id ------------- name ");
       System.out.println(map.get("id") + "  ------------- "
         + map.get("name"));
       // 以下部分代碼采用MapListHandler存儲方式查詢
       System.out.println("**
    Using MapListHandler");
       List lMap = (List) qRunner.query(conn,
         "select
    from mc_user_field", new MapListHandler());
       System.out.println("id ------------- name ");
       for (int i = 0; i < lMap.size(); i++) {
        Map vals = (Map) lMap.get(i);
        System.out.println(vals.get("id") + "  ------------- "
          + vals.get("name"));
       }
       // 以下部分代碼采用BeanHandler存儲方式查詢
       System.out.println("*
    Using BeanHandler");
       userField = (UserField) qRunner.query(conn,
         "select
    from mc_user_field where id = ?",
         new BeanHandler(Class.forName("cn.lining.test.UserField")),
         new Object[] { "5" });
       System.out.println("id ------------- name ");
       System.out.println(userField.getId() + "  ------------- "
         + userField.getName());
       // 以下部分代碼采用BeanListHandler存儲方式查詢
       System.out.println("*
    Using BeanListHandler");
       List lBean = (List) qRunner.query(conn,
         "select
    from mc_user_field", new BeanListHandler(Class
           .forName("cn.lining.test.UserField")));
       System.out.println("id ------------- name ");
       for (int i = 0; i < lBean.size(); i++) {
        userField = (UserField) lBean.get(i);
        System.out.println(userField.getId() + "  ------------- "
          + userField.getName());
       }
       // 以下部分代碼采用ArrayHandler存儲方式查詢
       System.out.println("*
    Using ArrayHandler");
       Object[] array = (Object[]) qRunner.query(conn,
         "select
    from mc_user_field where id = ?",
         new ArrayHandler(), new Object[] { "5" });
       System.out.println("id ------------- name ");
       System.out.println(array[0].toString() + "  ------------- "
         + array[1].toString());
       // 以下部分代碼采用ArrayListHandler存儲方式查詢
       System.out.println("*
    Using ArrayListHandler");
       List lArray = (List) qRunner.query(conn,
         "select
    from mc_user_field", new ArrayListHandler());
       System.out.println("id ------------- name ");
       for (int i = 0; i < lArray.size(); i++) {
        Object[] var = (Object[]) lArray.get(i);
        System.out.println(var[0].toString() + "  ------------- "
          + var[1].toString());
       }
       // 以下部分代碼采用ColumnListHandler存儲方式查詢指定列
       System.out.println("*
    Using ColumnListHandler");
       List lName = (List) qRunner.query(conn,
         "select
    from mc_user_field where id = ?",
         new ColumnListHandler("name"), new Object[] { "5" });
       System.out.println("name ");
       for (int i = 0; i < lName.size(); i++) {
        String name = (String) lName.get(i);
        System.out.println(name);
       }
       // 以下部分代碼采用ScalarHandler存儲方式查詢
       System.out.println("*
    Using ScalarHandler");
       String name = (String) qRunner.query(conn,
         "select
    from mc_user_field where id = ?",
         new ScalarHandler("name"), new Object[] { "5" });
       System.out.println("name ");
       System.out.println(name);
       // 以下部分代碼采用KeyedHandler存儲方式查詢
       System.out.println("*
    Using KeyedHandler");
       Map<String, Map> map2 = (Map<String, Map>) qRunner.query(conn,
         "select
    from mc_user_field", new KeyedHandler("name"));
       System.out.println("name: field_name2");
       Map vals = (Map) map2.get("field_name2");
       System.out.println(vals.get("id") + "  " + vals.get("name") + "  "
         + vals.get("type"));
       // 以下部分代碼插入一條數據
       System.out.println("*
    Insert begin");
       userField = new UserField();
       qRunner.update(conn, "insert into mc_user_field ("
         + "id,name,type,sort_order,required,visible)"
         + "values (?,?,?,?,?,?)", new Object[] { userField.getId(),
         userField.getName(), userField.getType(),
         userField.getSort_order(), userField.getRequired(),
         userField.getVisible() });
       System.out.println("
    update end");
       // 以下部分代碼更新一條數據
       System.out.println("
    update begin");
       userField = new UserField();
       qRunner.update(conn, "update mc_user_field set "
         + "name = ?,type = ?,sort_order = ?,"
         + "required = ?,visible = ?" + "where id = ?",
         new Object[] { userField.getName(), userField.getType(),
           userField.getSort_order(), userField.getRequired(),
           userField.getVisible(), userField.getId() });
       System.out.println("
    update end");
       // 以下部分代碼刪除一條數據
       System.out.println("
    delete begin");
       userField = new UserField();
       qRunner.update(conn, "delete from mc_user_field where id2 = ?",
         new Object[] { userField.getId() });
       System.out.println("
    delete end");
      } catch (SQLException ex) {
       ex.printStackTrace();
       try {
        System.out.println("
    rollback begin");
        DbUtils.rollback(conn);
        System.out.println("
    rollback end***");
       } catch (SQLException e) {
        e.printStackTrace();
       }
      } finally {
       DbUtils.closeQuietly(conn);
      }
     }
    }
    ·  ArrayHandler:把結果集中的第一行數據轉成對象數組。
    ·  ArrayListHandler:把結果集中的每一行數據都轉成一個對象數組,再存放到List中。
    ·  BeanHandler:將結果集中的第一行數據封裝到一個對應的JavaBean實例中。
    ·  BeanListHandler:將結果集中的每一行數據都封裝到一個對應的JavaBean實例中,存放到List里。
    ·  ColumnListHandler:將結果集中某一列的數據存放到List中。
    ·   KeyedHandler:將結果集中的每一行數據都封裝到一個Map里,然后再根據指定的key把每個Map再存放到一個Map里。
    ·   MapHandler:將結果集中的第一行數據封裝到一個Map里,key是列名,value就是對應的值。
    ·   MapListHandler:將結果集中的每一行數據都封裝到一個Map里,然后再存放到List。
    ·   ScalarHandler:將結果集中某一條記錄的其中某一列的數據存成Object。
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!