`
rq2_79
  • 浏览: 239787 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

利用Jakarta Commons组件beanutils、dbutils简化JDBC数据库操作

    博客分类:
  • jdbc
阅读更多
虽然现在出现了很多ORM框架,可是还是有很多朋友也许还在使用JDBC,就像我现在一样,除了学习的时候在使用Hibernate、Spring类似这 些优秀的框架,工作时一直都在使用JDBC。本文就简单介绍一下利用Jakarta Commons旗下beanutils、dbutils简化JDBC 数据库操作,以抛砖引玉,希望对像我一样在使用JDBC的朋友有所帮助。
    下面就分两部分简单介绍beanutils、dbutils在基于JDBC API数据库存取操作中的运用。第一部分显介绍beanutils在 JDBC数据库存取操作中的运用,第二部分介绍dbutils在JDBC 数据库存取操作中的运用,最后看看他们的优缺点,谈谈本人在项目运用过程中对他们的一点心得体会,仅供参考,其中有错误的地方希望不吝赐教,大家多多交流 共同进步。
一、Jakarta Commons beanutils
    Beanutils是操作Bean的锐利武器,其提过的 BeanUtils工具类可以简单方便的读取或设置Bean的属性,利用Dyna系列,还可以在运行期创建Bean,符合懒人的习惯,正如 LazyDynaBean,LazyDynaClass一样,呵呵。这些用法已经有很多文章提及,也可以参考apache的官方文档。
    对于直接利用JDBC API访问数据库时(这里针对的是返回结果集ResultSet的查询select),大多数都是采用两种方式,一种是取 出返回的结果集的数据存于Map中,另一种方式是Bean里。针对第二种方式,Beanutils里提供了ResultSetDynaClass结合 DynaBean以及RowSetDynaClass结合DynaBean来简化操作。下面用以个简单的例子展示一下beanutils的这两个类在 JDBC数据库操作中的运用。
    请在本机建立数据库publish,我用的是MySQL,在publish数据库中建立表book,脚本如下:
java 代码
 
  1. CREATE TABLE book(  
  2.   id int(11) NOT NULL auto_increment,  
  3.   title varchar(50) character set latin1 NOT NULL,  
  4.   authors varchar(50) character set latin1 default NULL,   
  5.   PRIMARY KEY  (id)  
  6. )   


     然后用你喜欢的编辑器建立一个类BeanutilsJDBCTest,我们先用ResultSetDynaClass来处理,然后再用 RowSetDynaClass来实现同样的类,之后看看他们之间有什么不同,用ResultSetDynaClass处理的源代码如下所示:
     然后用你喜欢的编辑器建立一个类BeanutilsJDBCTest,我们先用ResultSetDynaClass来处理,然后再用 RowSetDynaClass来实现同样的类,之后看看他们之间有什么不同,用ResultSetDynaClass处理的源代码如下所示:
java 代码
 
  1. package cn.qtone.test;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.DriverManager;  
  5. import java.sql.ResultSet;  
  6. import java.sql.Statement;  
  7. import java.util.Iterator;   
  8. import org.apache.commons.beanutils.DynaBean;  
  9. import org.apache.commons.beanutils.PropertyUtils;  
  10. import org.apache.commons.beanutils.ResultSetDynaClass;   
  11. public class BeanutilsJDBCTest{  
  12.        public static void main(String[] args) {  
  13.               Connection con = null;  
  14.               Statement st = null;  
  15.               ResultSet rs = null;  
  16.               try {  
  17.                      Class.forName("com.mysql.jdbc.Driver");  
  18.                      String url = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";  
  19.                      con = DriverManager.getConnection(url, "root""hyys");  
  20.                      st = con.createStatement();  
  21.                      rs = st.executeQuery("select * from book");  
  22.                      ResultSetDynaClass rsDynaClass = new ResultSetDynaClass(rs);  
  23.                      Iterator itr = rsDynaClass.iterator();  
  24.                      System.out.println("title-------------authors");  
  25.                      while (itr.hasNext()) {  
  26.                             DynaBean dBean = (DynaBean) itr.next();  
  27.                             System.out.println(PropertyUtils.getSimpleProperty(dBean,"title")+ "-------"+ PropertyUtils.getSimpleProperty(dBean, "authors"));  
  28.   
  29.                      }  
  30.               } catch (Exception e) {  
  31.                      e.printStackTrace();  
  32.               } finally {  
  33.                      try {  
  34.                             if (rs != null) {  
  35.                                    rs.close();  
  36.                             }  
  37.                             if (st != null) {  
  38.                                    st.close();  
  39.                             }  
  40.                             if (con != null) {  
  41.                                    con.close();  
  42.                             }  
  43.                      } catch (Exception e) {  
  44.                             e.printStackTrace();  
  45.                      }  
  46.               }  
  47.        }  
  48. }   


用RowSetDynaClass处理的源代码如下所示: 

java 代码
 
  1. package cn.qtone.test;   
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.DriverManager;  
  5. import java.sql.ResultSet;  
  6. import java.sql.Statement;  
  7. import java.util.Iterator;  
  8. import java.util.List;   
  9. import org.apache.commons.beanutils.DynaBean;  
  10. import org.apache.commons.beanutils.PropertyUtils;  
  11. import org.apache.commons.beanutils.RowSetDynaClass;   
  12.   
  13. public class BeanutilsJDBCTest{  
  14.        public static void main(String[] args) {  
  15.               List rsDynaClass = rsTest();  
  16.               System.out.println("title ------------- authors ");  
  17.               Iterator itr = rsDynaClass.iterator();  
  18.               while (itr.hasNext()) {  
  19.                      DynaBean dBean = (DynaBean) itr.next();  
  20.                      try {  
  21.                             System.out.println(PropertyUtils.getSimpleProperty(dBean,"name")  + "-----"+ PropertyUtils.getSimpleProperty(dBean, "mobile"));  
  22.                      } catch (Exception e) {  
  23.                             // TODO 自动生成 catch 块  
  24.                             e.printStackTrace();  
  25.                      }  
  26.               }  
  27.        }   
  28.        private static List rsTest() {  
  29.               Connection con = null;  
  30.               Statement st = null;  
  31.               ResultSet rs = null;  
  32.               try {  
  33.                      Class.forName("com.mysql.jdbc.Driver");  
  34.                      String url = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";  
  35.                      con = DriverManager.getConnection(url, "root""hyys");  
  36.                      st = con.createStatement();  
  37.                      rs = st.executeQuery("select * from book");  
  38.                      RowSetDynaClass rsdc = new RowSetDynaClass(rs);  
  39.                      return rsdc.getRows();  
  40.               } catch (Exception e) {  
  41.                      e.printStackTrace();  
  42.               } finally {  
  43.                      try {  
  44.                             if (rs != null) {  
  45.                                    rs.close();  
  46.                             }  
  47.                             if (st != null) {  
  48.                                    st.close();  
  49.                             }  
  50.                             if (con != null) {  
  51.                                    con.close();  
  52.                             }  
  53.                      } catch (Exception e) {  
  54.                             e.printStackTrace();  
  55.                      }  
  56.               }  
  57.               return null;  
  58.        }  
  59. }   


     这两个方法输出的结果应该是一样的。但是很显然第二种方式比第一种方式要好,它把数据访问部分抽取出来放到一个方法中,显得简单清晰。
      其实在利用ResultSetDynaClass时,必须在ResultSet等数据库资源关闭之前,处理好那些数据,你不能在资源关闭之后使用 DynaBean,否则就会抛出异常,异常就是说不能在ResultSet之后存取数据(具体的异常名我也忘了),当然你也可以采用以前的方式一个一个的 把数据放到Map里,如果你一定要那样做,建议还是别用Beanutils,因为这没带给你什么好处。总之利用ResultSetDynaClass你的 程序的扩展性非常部好。
    从第二中方式可以看出,利用RowSetDynaClass可以很好的解决上述 ResultSetDynaClass遇到的问题,RowSetDynaClass的getRows()方法,把每一行封装在一个DynaBean对象 里,然后,把说有的行放到一个List里,之后你就可以对返回的List里的每一个DynaBean进行处理,此外对于DynaBean你还可以采用标准 的get/set方式处理,当然你也可以用PropertyUtils. getSimpleProperty(Object bean,  String name)进行处理。
    从上面的分析中,你应该可以决定你应该使用ResultSetDynaClass还是RowSetDynaClass了。

二、Jakarta Commons dbutils:
     用JDBC API时最令人讨厌的就是异常处理,也很烦琐,而且很容易出错,本人曾考虑过利用模板进行处理,后来看到了dbutils,之后就采用那个 dbutils,采用模板的方式各位朋友可以参考Spring,Spring的JdbcTemplate不灵活而强大,呵呵,说句闲话,实在太佩服 Rod Johnson了,Rod Johnson真的很令人尊敬。
    Dbutils的QueryRunner把大多数与关闭资源相关的封装起来,另外,你也可以使用DbUtils进行关闭,当然DbUtils提供 的功能当然不止这些,它提过了几个常用的静态方法,除了上述的关闭资源外, DbUtils. commitAndClose(Connection conn)还提供事务提及等操作。
还是以一个例子来说说吧,毕竟我不是搞业务的,小嘴巴吧嗒吧哒不起来啊,呵呵。
    为了和采用Beanutils更好的进行对比,这个例子还是实现同样的功能,数据库同样采用前一篇文章中提到的publish。
同样的,用你喜欢的编辑器建立一个类DbutilsJDBCTest,示例代码如下所示:
java 代码
 
  1. package cn.qtone.test;  
  2. import java.sql.Connection;  
  3. import java.sql.DriverManager;  
  4. import java.sql.SQLException;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7. import org.apache.commons.dbutils.DbUtils;  
  8. import org.apache.commons.dbutils.QueryRunner;  
  9. import org.apache.commons.dbutils.handlers.MapListHandler;  
  10. public class DbutilsJDBCTest{  
  11.     public static void main(String[] args) {  
  12.         Connection conn = null;  
  13.         String jdbcURL = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";  
  14.         String jdbcDriver = "com.mysql.jdbc.Driver";  
  15.         try {  
  16.             DbUtils.loadDriver(jdbcDriver);  
  17.             // Username "root". Password "root"  
  18.             conn = DriverManager.getConnection(jdbcURL, "root""root");  
  19.             QueryRunner qRunner = new QueryRunner();  
  20.             System.out.println("***Using MapListHandler***");  
  21.             //以下部分代码采用Map存储方式,可以采用Bean的方式代替进行处理  
  22.             List lMap = (List) qRunner.query(conn,  
  23.                     "select title,authors  from books"new MapListHandler());  
  24.             //以下是处理代码,可以抽取出来  
  25. System.out.println("title ------------- authors ");  
  26.                 for (int i = 0; i < lMap.size(); i++) {  
  27.                         Map vals = (Map) lMap.get(i);  
  28.                         System.out.println(vals.get("title")+"-------------"+ vals.get("authors"));  
  29.                 }  
  30.         } catch (SQLException ex) {  
  31.             ex.printStackTrace();  
  32.         } finally {  
  33.             DbUtils.closeQuietly(conn);  
  34.         }  
  35.     }  
  36. }  


怎么样?是不是比采用Beanutils的ResultSetDynaTrial和RowSetDynaClass好多了?采用Beanutils令人难缠的是关闭那些资源以及处理那些异常,而这里采用Dbutils显然代码量减少了很多。
上例在处理结果集时,它把数据库中的每一行映射成一个Map,其中列名作为Key,该列对应的值作为Value存放,查询的所有的数据一起放在一个List里,然后进行处理,当然,一个更明智的处理是直接返回List然后再单独进行处理。
事实上上例返回的结果集中的每一行不必放在一个Map里,你可以放在一个Bean里,当然如果你真的很懒,你也可以使用Beanutils的LazyDynaClass和LazyDynaBean,不过也许没有必要那么做,至于原因请看下文。

如果使用Bean而不是用Map,那么,你也许需要建立一个Bean,如下:
java 代码
 
  1. package cn.qtone.test;  
  2. public class Book {  
  3.     public int id;  
  4.     public String title;  
  5.     public String authors ;  
  6.     public StudentBean() {  
  7.     }  
  8.     public String getAuthors() {  
  9.         return authors;  
  10.     }  
  11.     public void setAuthors(String authors) {  
  12.         this.authors = authors;  
  13.     }  
  14.     public int getId() {  
  15.         return id;  
  16.     }  
  17.     public void setId(int id) {  
  18.         this.id = id;  
  19.     }  
  20.     public String getTitle() {  
  21.         return title;  
  22.     }  
  23.     public void setTitle(String title) {  
  24.         this.title = title;  
  25.     }  
  26. }  


然后简单修改一下DbutilsJDBCTest 中的部分代码即可,代替之后的源代码如下:

java 代码
 
  1. package cn.qtone.test;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.DriverManager;  
  5. import java.sql.SQLException;  
  6. import java.util.List;  
  7. import java.util.Map;  
  8. import org.apache.commons.dbutils.DbUtils;  
  9. import org.apache.commons.dbutils.QueryRunner;  
  10. import org.apache.commons.dbutils.handlers.BeanListHandler;  
  11.   
  12. public class DbutilsJDBCTest{  
  13.     public static void main(String[] args) {  
  14.         Connection conn = null;  
  15.         String jdbcURL = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";  
  16.         String jdbcDriver = "com.mysql.jdbc.Driver";  
  17.         try {  
  18.             DbUtils.loadDriver(jdbcDriver);  
  19.             // Username "root". Password "root"  
  20.             conn = DriverManager.getConnection(jdbcURL, "root""root");  
  21.             QueryRunner qRunner = new QueryRunner();  
  22.             System.out.println("***Using BeanListHandler ***");  
  23.             //以下部分代码采用Map存储方式,可以采用Bean的方式代替进行处理  
  24. List lBeans = (List) qRunner.query(conn," select title,authors from books "new BeanListHandler(Book.class));  
  25.     //以下是处理代码,可以抽取出来  
  26. System.out.println("title ------------- authors ");  
  27.     for (int i = 0; i < lBeans.size(); i++) {  
  28.             Book vals = (Book) lBeans.get(i);      
  29.           System.out.println(vals.getTitle ()+"-------------"+ vals. getAuthors ());  
  30.                 }  
  31.         } catch (SQLException ex) {  
  32.             ex.printStackTrace();  
  33.         } finally {  
  34.             DbUtils.closeQuietly(conn);  
  35.         }  
  36.     }  
  37. }  

     这两种法输出的结果应该是一样的。两种处理方式都差不多,但我更愿意采用第一种,因为第一种少写一个bean,而且我测试过采用Map的方式即第一种方式 性能要好的多,采用Bean性能比较低可能是因为采用反射的缘故,采用反射的东东性能和不采用反射的还是有点差距。也是这个原因,不推荐采用 LazyDynaClass和LazyDynaBean,因为采用这二者是在运行期动态创建Bean类和Bean属性,然后再创建Bean对象的,其性能 可想而知了(不过我没有测试过啊,所以我说这个话可说是没有根据的,感兴趣的朋友自己测试一下,记得告诉我结果哦,呵呵),除了 MapListHandler以及BeanListHandler之外,DButils还提供了其他的Handler,如果这些不能满足你的需求,你也可 以自己实现一个Handler。
    最后,也是最大的体会,也许是最大的收获吧,那就是:对于每一个项目,在根据每一个需求获取相应解决方案时,先寻找开源组件,看是否已经有满足某些功能需求的开源组件,如果没有,再考虑自主开发或者向第三方购买,否则尽量采用开源组件.
    请尽量享用开源的魅力,尽情的拥抱开源吧。
    好了,终于写完了,有什么问题请联系我,大家互相交流交流。
分享到:
评论
1 楼 pearson 2007-09-23  
显然commons-dbutils 好多了。

相关推荐

    commons-beanutils-1.8.3

    commons-beanutils-1.8.3.rar官方正版免费版,BeanUtils主要提供了对于JavaBean进行各种操作。 个包主要提供用于操作JavaBean的工具类,Jakarta-Common-BeanUtils的主要功能都在这个包里实现。

    javaWeb入门jar(BeanUtils C3p0 DBCP DButils dom4j JDBC jstl)

    4. **DBUtils**:Apache Commons DBUtils是基于JDBC的数据库操作工具库,简化了数据库操作。它提供了一套异常处理机制,使得开发者不必频繁地处理SQL语句执行过程中的异常,同时还支持批处理和自动关闭资源,避免了...

    Jakarta Commons cookbook.chm与中文版的笔记

    5. **其他模块**: 还有其他如DBUtils(数据库操作)、BeanUtils(bean操作)、Codec(编码解码)等,它们分别针对特定的编程需求提供解决方案。 在阅读《Jakarta Commons Cookbook》时,你可以学习如何有效地利用...

    JAKARTA COMMONS

    11. **Commons DbUtils**: 是一个 JDBC 辅助库,提供简单的资源清理代码,帮助简化数据库操作。 12. **Commons Digester**: 使用 XML 配置文件映射到 Java 对象,简化 XML 解析和对象创建过程。 13. **Commons ...

    Jakarta commons docs API CHM 格式

    commons-dbutils JDBC 辅助类 commons-digester XML 文件到 Java 对象的映射机制 commons-discovery 提供工具来定位资源 (包括类) ,通过使用各种模式来映射服务/引用名称和资源名称。 commons-el 提供在JSP2.0...

    Pro.Jakarta.Commons.rar

    9. **Commons DbUtils**:简化了数据库操作,提供了一个简单的JDBC工具库,可以防止SQL注入等问题。 10. **Commons Configuration**:提供了一种灵活的方式来管理应用程序的配置,支持多种配置源,如XML、...

    commons-logging,dbcp-1.4.jar,beanutils-1.8.3.jar,dbutils-1.4.jar,pool-1.5.6.jar

    例如,可以考虑升级到DBCP2,同时使用最新的Commons Logging、BeanUtils和DBUtils版本,以利用新特性、性能提升和已知问题的修复。在进行这样的升级时,务必测试新版本与现有代码的兼容性,以确保无缝迁移。

    比较全面的:Jakarta-commons jar包(附: chm参考手册 & 资源简介)

    commons-dbutils JDBC 辅助类 commons-digester XML 文件到 Java 对象的映射机制 commons-discovery 提供工具来定位资源 (包括类) ,通过使用各种模式来映射服务/引用名称和资源名称。 commons-el 提供在JSP2.0...

    apache-commons源码及jar文件

    DbUtils 是一个 JDBC helper 类库,完成数据库任务的简单的资源清除代码. Digester Commons-Digester 是一个 XML-Java对象的映射工具,用于解析 XML配置文件. Discovery Commons-Discovery 提供工具来定位资源 ...

    Java开发常用jar包

    1.commons-beanutils.jar...12.commons-DbUtils.jar:Apache组织提供的一个资源JDBC工具类库,它是对JDBC的简单封装,对传统操作数据库的类进行二次封装,可以把结果集转化成List。 13.commons-Email.jar: 提供开源的API

    数据库连接池DBCP包.7z

    - `commons-dbutils-1.6.jar`:提供简单的数据库访问API,可以配合DBCP使用,简化数据库操作。 5. **连接池的扩展**:除了DBCP,还有其他流行的连接池实现,如C3P0、HikariCP、Druid等。这些连接池各有优缺点,...

    javaWeb阶段所涉及到的部分jar包.rar

    8. **dbutils**: Apache的DBUtils是Java数据库连接的一个实用工具,它提供了一些基础的数据库操作功能,如查询、更新、批处理等,简化了JDBC的使用,降低了出错的可能性。 9. **beanutils**: Apache的BeanUtils库...

    开源框架jar包(百度云盘)

     · commons-dbutils-1.3-bin.zip  · commons-pool-1.5.5-bin.zip  · commons-io-2.0-bin.zip  · commons-lang-2.5-src.zip  · commons-logging-1.1.1-bin.zip  · commons-io-2.0-src.zip  · commons-...

Global site tag (gtag.js) - Google Analytics