利用Jakarta Commons组件beanutils、dbutils简化JDBC数据库操作
虽然现在出现了很多ORM框架,可是还是有很多朋友也许还在使用JDBC,就像我现在一样,除了学习的时候在使用Hibernate、Spring类似这些优秀的框架,工作时一直都在使用JDBC。本文就简单介绍一下利用Jakarta Commons旗下beanutils、dbutils简化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,脚本如下:
CREATE TABLE book(
id int(11) NOT NULL auto_increment,
title varchar(50) character set latin1 NOT NULL,
authors varchar(50) character set latin1 default NULL,
PRIMARY KEY (id)
)
然后用你喜欢的编辑器建立一个类BeanutilsJDBCTest,我们先用ResultSetDynaClass来处理,然后再用RowSetDynaClass来实现同样的类,之后看看他们之间有什么不同,用ResultSetDynaClass处理的源代码如下所示:
然后用你喜欢的编辑器建立一个类BeanutilsJDBCTest,我们先用ResultSetDynaClass来处理,然后再用RowSetDynaClass来实现同样的类,之后看看他们之间有什么不同,用ResultSetDynaClass处理的源代码如下所示:
package cn.qtone.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Iterator;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.ResultSetDynaClass;
public class BeanutilsJDBCTest{
public static void main(String[] args) {
Connection con = null;
Statement st = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";
con = DriverManager.getConnection(url, "root", "hyys");
st = con.createStatement();
rs = st.executeQuery("select * from book");
ResultSetDynaClass rsDynaClass = new ResultSetDynaClass(rs);
Iterator itr = rsDynaClass.iterator();
System.out.println("title-------------authors");
while (itr.hasNext()) {
DynaBean dBean = (DynaBean) itr.next();
System.out.println(PropertyUtils.getSimpleProperty(dBean,"title")
+ "-------------"+ PropertyUtils.getSimpleProperty(dBean, "authors"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (rs != null) {
rs.close();
}
if (st != null) {
st.close();
}
if (con != null) {
con.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
用RowSetDynaClass处理的源代码如下所示:
package cn.qtone.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.RowSetDynaClass;
public class BeanutilsJDBCTest{
public static void main(String[] args) {
List rsDynaClass = rsTest();
System.out.println("title ------------- authors ");
Iterator itr = rsDynaClass.iterator();
while (itr.hasNext()) {
DynaBean dBean = (DynaBean) itr.next();
try {
System.out.println(PropertyUtils.getSimpleProperty(dBean,"name")
+ "-------------"+ PropertyUtils.getSimpleProperty(dBean, "mobile"));
} catch (Exception e) {
// TODO 自动生成 catch 块
e.printStackTrace();
}
}
}
private static List rsTest() {
Connection con = null;
Statement st = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";
con = DriverManager.getConnection(url, "root", "hyys");
st = con.createStatement();
rs = st.executeQuery("select * from book");
RowSetDynaClass rsdc = new RowSetDynaClass(rs);
return rsdc.getRows();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (rs != null) {
rs.close();
}
if (st != null) {
st.close();
}
if (con != null) {
con.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
这两个方法输出的结果应该是一样的。但是很显然第二种方式比第一种方式要好,它把数据访问部分抽取出来放到一个方法中,显得简单清晰。
其实在利用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,示例代码如下所示:
package cn.qtone.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.MapListHandler;
public class DbutilsJDBCTest{
public static void main(String[] args) {
Connection conn = null;
String jdbcURL = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";
String jdbcDriver = "com.mysql.jdbc.Driver";
try {
DbUtils.loadDriver(jdbcDriver);
// Username "root". Password "root"
conn = DriverManager.getConnection(jdbcURL, "root", "root");
QueryRunner qRunner = new QueryRunner();
System.out.println("***Using MapListHandler***");
//以下部分代码采用Map存储方式,可以采用Bean的方式代替进行处理
List lMap = (List) qRunner.query(conn,
"select title,authors from books", new MapListHandler());
//以下是处理代码,可以抽取出来
System.out.println("title ------------- authors ");
for (int i = 0; i Map vals = (Map) lMap.get(i);
System.out.println(vals.get("title")+"-------------"+ vals.get("authors"));
}
} catch (SQLException ex) {
ex.printStackTrace();
} finally {
DbUtils.closeQuietly(conn);
}
}
}
怎么样?是不是比采用Beanutils的ResultSetDynaTrial和RowSetDynaClass好多了?采用Beanutils令人难缠的是关闭那些资源以及处理那些异常,而这里采用Dbutils显然代码量减少了很多。
上例在处理结果集时,它把数据库中的每一行映射成一个Map,其中列名作为Key,该列对应的值作为Value存放,查询的所有的数据一起放在一个List里,然后进行处理,当然,一个更明智的处理是直接返回List然后再单独进行处理。
事实上上例返回的结果集中的每一行不必放在一个Map里,你可以放在一个Bean里,当然如果你真的很懒,你也可以使用Beanutils的LazyDynaClass和LazyDynaBean,不过也许没有必要那么做,至于原因请看下文。
如果使用Bean而不是用Map,那么,你也许需要建立一个Bean,如下:
package cn.qtone.test;
public class Book {
public int id;
public String title;
public String authors ;
public StudentBean() {
}
public String getAuthors() {
return authors;
}
public void setAuthors(String authors) {
this.authors = authors;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
然后简单修改一下DbutilsJDBCTest 中的部分代码即可,代替之后的源代码如下:
package cn.qtone.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.BeanListHandler;
public class DbutilsJDBCTest{
public static void main(String[] args) {
Connection conn = null;
String jdbcURL = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";
String jdbcDriver = "com.mysql.jdbc.Driver";
try {
DbUtils.loadDriver(jdbcDriver);
// Username "root". Password "root"
conn = DriverManager.getConnection(jdbcURL, "root", "root");
QueryRunner qRunner = new QueryRunner();
System.out.println("***Using BeanListHandler ***");
//以下部分代码采用Map存储方式,可以采用Bean的方式代替进行处理
List lBeans = (List) qRunner.query(conn," select title,authors from books ", new BeanListHandler(Book.class));
//以下是处理代码,可以抽取出来
System.out.println("title ------------- authors ");
for (int i = 0; i Book vals = (Book) lBeans.get(i);
System.out.println(vals.getTitle ()+"-------------"+ vals. getAuthors ());
}
} catch (SQLException ex) {
ex.printStackTrace();
} finally {
DbUtils.closeQuietly(conn);
}
}
}
这两种法输出的结果应该是一样的。两种处理方式都差不多,但我更愿意采用第一种,因为第一种少写一个bean,而且我测试过采用Map的方式即第一种方式性能要好的多,采用Bean性能比较低可能是因为采用反射的缘故,采用反射的东东性能和不采用反射的还是有点差距。也是这个原因,不推荐采用LazyDynaClass和LazyDynaBean,因为采用这二者是在运行期动态创建Bean类和Bean属性,然后再创建Bean对象的,其性能可想而知了(不过我没有测试过啊,所以我说这个话可说是没有根据的,感兴趣的朋友自己测试一下,记得告诉我结果哦,呵呵),除了MapListHandler以及BeanListHandler之外,DButils还提供了其他的Handler,如果这些不能满足你的需求,你也可以自己实现一个Handler。
最后,也是最大的体会,也许是最大的收获吧,那就是:对于每一个项目,在根据每一个需求获取相应解决方案时,先寻找开源组件,看是否已经有满足某些功能需求的开源组件,如果没有,再考虑自主开发或者向第三方购买,否则尽量采用开源组件.
请尽量享用开源的魅力,尽情的拥抱开源吧。
好了,终于写完了,有什么问题请联系我,大家互相交流交流

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Viele Benutzer stoßen beim Spielen einiger Spiele unter Win10 immer auf Probleme, wie z. B. ein Einfrieren des Bildschirms und unscharfe Bildschirme. Zu diesem Zeitpunkt können wir das Problem lösen, indem wir die Directplay-Funktion aktivieren, und die Bedienungsmethode der Funktion ist ebenfalls sehr einfach. So installieren Sie DirectPlay, die alte Komponente von Win10 1. Geben Sie „Systemsteuerung“ in das Suchfeld ein und öffnen Sie es. 2. Wählen Sie große Symbole als Anzeigemethode. 3. Suchen Sie nach „Programme und Funktionen“. 4. Klicken Sie links, um oder zu aktivieren Win-Funktionen ausschalten 5. Wählen Sie hier die alte Version aus. Aktivieren Sie einfach das Kontrollkästchen

So verwenden Sie GitLab für die Projektdokumentenverwaltung 1. Hintergrundeinführung Im Softwareentwicklungsprozess sind Projektdokumente sehr wichtige Informationen. Sie können dem Entwicklungsteam nicht nur helfen, die Anforderungen und das Design des Projekts zu verstehen, sondern auch als Referenz für das Testteam dienen und Kunden. Um die Versionskontrolle und Teamzusammenarbeit von Projektdokumenten zu erleichtern, können wir GitLab für die Projektdokumentenverwaltung verwenden. GitLab ist ein auf Git basierendes Versionskontrollsystem. Es unterstützt nicht nur die Codeverwaltung, sondern kann auch Projektdokumente verwalten. 2. Einrichtung der GitLab-Umgebung Zuerst I

Vue ist derzeit eines der beliebtesten Front-End-Frameworks, und VUE3 ist die neueste Version des Vue-Frameworks. Im Vergleich zu VUE2 bietet VUE3 eine höhere Leistung und ein besseres Entwicklungserlebnis und ist für viele Entwickler zur ersten Wahl geworden. In VUE3 ist die Verwendung von Erweiterungen zum Erben von Komponenten eine sehr praktische Entwicklungsmethode. In diesem Artikel wird erläutert, wie Erweiterungen zum Erben von Komponenten verwendet werden. Was heißt erweitert? In Vue ist Extends ein sehr praktisches Attribut, das für untergeordnete Komponenten verwendet werden kann, um von ihren Eltern zu erben.

Vue ist ein sehr beliebtes Front-End-Framework. Es bietet viele Tools und Funktionen wie Komponentisierung, Datenbindung, Ereignisbehandlung usw., die Entwicklern beim Erstellen effizienter, flexibler und einfach zu wartender Webanwendungen helfen können. In diesem Artikel werde ich vorstellen, wie man eine Kalenderkomponente mit Vue implementiert. 1. Anforderungsanalyse Zunächst müssen wir die Anforderungen dieser Kalenderkomponente analysieren. Ein einfacher Kalender sollte über die folgenden Funktionen verfügen: Anzeige der Kalenderseite des aktuellen Monats; Unterstützung des Wechsels zum vorherigen oder nächsten Monat; Unterstützung beim Klicken auf einen bestimmten Tag;

Das Standardanzeigeverhalten für Komponenten im Angular-Framework gilt nicht für Elemente auf Blockebene. Diese Designwahl fördert die Kapselung von Komponentenstilen und ermutigt Entwickler, bewusst zu definieren, wie jede Komponente angezeigt wird. Durch explizites Festlegen der CSS-Eigenschaft display kann die Anzeige von Angular-Komponenten vollständig gesteuert werden, um das gewünschte Layout und die gewünschte Reaktionsfähigkeit zu erreichen.

Wie rendert Vue Komponenten dynamisch über JSX? Der folgende Artikel stellt Ihnen vor, wie Vue Komponenten mithilfe von JSX effizient dynamisch rendern kann. Ich hoffe, er wird Ihnen hilfreich sein!

Die alten Win10-Komponenten müssen vom Benutzer selbst aktiviert werden, da viele Komponenten standardmäßig geschlossen sind. Der Vorgang ist sehr einfach Versionskomponenten? Öffnen 1. Klicken Sie auf Start und dann auf „Win-System“. 2. Klicken Sie, um die Systemsteuerung aufzurufen. 3. Klicken Sie dann auf das Programm unten. 4. Klicken Sie auf „Win-Funktionen aktivieren oder deaktivieren“. 5. Hier können Sie auswählen, was Sie möchten öffnen

Vue-Komponentenpraxis: Einführung in die Entwicklung von Paging-Komponenten In Webanwendungen ist die Paging-Funktion eine wesentliche Komponente. Eine gute Paginierungskomponente sollte einfach und klar in der Darstellung sein, reich an Funktionen und leicht zu integrieren und zu verwenden sein. In diesem Artikel stellen wir vor, wie Sie mit dem Vue.js-Framework eine hochgradig anpassbare Paging-Komponente entwickeln. Wir erklären anhand von Codebeispielen ausführlich, wie man mit Vue-Komponenten entwickelt. Technologie-Stack Vue.js2.xJavaScript (ES6) HTML5- und CSS3-Entwicklungsumgebung
