apache commons 之 DbUtils QueryRunner使用之迷雾重重

DbUtils 和 DBCP一般需要一起使用。

在ORALCE环境下运行。

首先创建一张表,创建表语句。

create table tb_user(USERNAME varchar2(64)  ,PASSWORD  varchar2(64));

首先来看一段程序运行后的异常:

Exception in thread "main"java.lang.AbstractMethodError

atorg.apache.commons.dbcp.DelegatingPreparedStatement.getParameterMetaData(DelegatingPreparedStatement.java:221)

atorg.apache.commons.dbcp.DelegatingPreparedStatement.getParameterMetaData(DelegatingPreparedStatement.java:221)

atorg.apache.commons.dbutils.AbstractQueryRunner.fillStatement(AbstractQueryRunner.java:225)

atorg.apache.commons.dbutils.QueryRunner.update(QueryRunner.java:487)

atorg.apache.commons.dbutils.QueryRunner.update(QueryRunner.java:377)

attest.ffm83.commons.dbutils.QueryRunnerError.test_insert(QueryRunnerError.java:72)

attest.ffm83.commons.dbutils.QueryRunnerError.main(QueryRunnerError.java:62)

在网上查了下,这种类似的异常很多,但是解决办法千奇百怪,这种代码是下面类似的代码产生的。

Commons DbUtils中QueryRunner总是出错的源代码:

package test.ffm83.commons.dbutils;

import java.sql.Connection;

import java.sql.SQLException;

import java.util.Properties;

import org.apache.commons.dbcp.BasicDataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;

import org.apache.commons.dbutils.DbUtils;

import org.apache.commons.dbutils.QueryRunner;

/**

* 通过commons dbUtils进行数据库的简单访问和实用,同时暴露一些异常

* dbUtils1.6,Oracle驱动:class12

* @author范芳铭

*/

public
class
QueryRunnerError {

private
static
BasicDataSource dataSource =
null;

privateQueryRunner
runner= null;

publicQueryRunnerError() {

init();

runner = new QueryRunner(dataSource);

}

public
static void
init() {

if (dataSource !=
null) {

try {

dataSource.close();

}catch(Exception e) {

e.printStackTrace();

}

dataSource =
null;

}

try {

Propertiesp = newProperties();

p.setProperty("driverClassName","oracle.jdbc.driver.OracleDriver");

p.setProperty("url",
"jdbc:oracle:thin:@192.168.1.1:1521:fanfangming");

p.setProperty("password","ffm");

p.setProperty("username","ffm");

p.setProperty("maxActive","2");

p.setProperty("maxIdle","1");

p.setProperty("maxWait","100");

dataSource =(BasicDataSource) BasicDataSourceFactory

.createDataSource(p);

}catch(Exception e) {

e.printStackTrace();

}

}

public
static synchronized
ConnectiongetConnection()
throwsSQLException {

if (dataSource ==
null) {

init();

}

Connectionconn = null;

if (dataSource !=
null) {

conn= dataSource.getConnection();

}

return conn;

}

public
static void
main(String[] args)
throws SQLException {

test_insert();

}

public
static void
test_insert()
throws
SQLException {

System.out.println("-------------test_insert()-------------");

//创建连接

Connection conn = getConnection();

//创建SQL执行工具

QueryRunner qRunner =
new QueryRunner();

//执行SQL插入

int n =
qRunner.update(conn,
"insert into tb_user(username,password) values(‘范芳铭‘,‘ffm‘)");

System.out.println("成功插入" + n +
"条数据!");

//关闭数据库连接

DbUtils.closeQuietly(conn);

}

public
class
tb_user{

private String
username ;

private String
password;

public tb_user(String username,String password){

this.username = username;

this.password = password;

}

public String getUsername() {

return
username;

}

public
void
setUsername(Stringusername) {

this.username = username;

}

public String getPassword() {

return
password;

}

public
void
setPassword(Stringpassword) {

this.password = password;

}

}

}

这段代码就是一个相对比较常见的代码。但是这种代码,至少在oracle的环境下,无法正常使用。

问题发现了,要怎么解决?

首先是信心,很多大人物特别喜欢说信心比黄金还重要,所以我们先要有信心;如果dbutils不能连接Oracle数据库,那么我们没有必要在这里继续倒腾;

然后是学习,在网上看了一大圈,用百度找到一些资料,看看总没有坏处。

仔细看这个异常,最后一节抛出来的是 getParameterMetaData()方法,那么姑且认为和 参数的元数据有关系;

因为这个实例简单,因此可以聚焦问题。只需要关注 conn连接,QueryRunner初始化和执行update三个地方有关。

如果不用QueryRunner,conn也可以访问数据库,那么排除下来。只要关注QueryRunner初始化和执行update两个地方就可以了。

QueryRunner 初始化有四个方法,看下类的说明,好像有两个和元数据有关系。

那就试一试,诶,都可以。

把上面的代码稍微调整下:

QueryRunner qRunner= new QueryRunner(dataSource,true);

或者

QueryRunner qRunner= new QueryRunner(true);

都可以解决问题,输出结果为:

-------------test_insert()-------------

成功插入1条数据!

数据插入了,那么下一步就是要查询了。

哎呦,又出异常了:

-------------test_query()-------------

Exception in thread"main" java.sql.SQLException: Cannot createtest.ffm83.commons.dbutils.QueryRunnerError$tb_user:test.ffm83.commons.dbutils.QueryRunnerError$tb_user Query: select username,passwordfrom tb_user Parameters: []

atorg.apache.commons.dbutils.AbstractQueryRunner.rethrow(AbstractQueryRunner.java:392)

atorg.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:351)

atorg.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:226)

attest.ffm83.commons.dbutils.QueryRunnerError.test_query(QueryRunnerError.java:90)

attest.ffm83.commons.dbutils.QueryRunnerError.main(QueryRunnerError.java:67)

这可如何是好?

先看下这段利用QueryRunner进行查询的源代码:

packagetest.ffm83.commons.dbutils;

importjava.sql.Connection;

importjava.sql.SQLException;

importjava.util.List;

importjava.util.Properties;

importorg.apache.commons.dbcp.BasicDataSource;

importorg.apache.commons.dbcp.BasicDataSourceFactory;

importorg.apache.commons.dbutils.DbUtils;

importorg.apache.commons.dbutils.QueryRunner;

importorg.apache.commons.dbutils.handlers.ArrayHandler;

importorg.apache.commons.dbutils.handlers.BeanListHandler;

/**

* 通过commons dbUtils进行数据库的简单访问和实用,同时暴露一些异常 dbUtils1.6,Oracle驱动:class12

*

* @author 范芳铭

*/

public classQueryRunnerError {

private static BasicDataSourcedataSource = null;

private QueryRunner runner = null;

public QueryRunnerError() {

init();

runner = newQueryRunner(dataSource);

}

public static void init() {

if (dataSource != null) {

try {

dataSource.close();

} catch (Exceptione) {

e.printStackTrace();

}

dataSource = null;

}

try {

Properties p = newProperties();

p.setProperty("driverClassName","oracle.jdbc.driver.OracleDriver");

p.setProperty("url","jdbc:oracle:thin:@192.168.1.1:1521:fanfangming");

p.setProperty("password","ffm");

p.setProperty("username","ffm");

p.setProperty("maxActive","4");

p.setProperty("maxIdle","1");

p.setProperty("maxWait","100");

dataSource =(BasicDataSource) BasicDataSourceFactory

.createDataSource(p);

} catch (Exception e) {

e.printStackTrace();

}

}

public static synchronized ConnectiongetConnection() throws SQLException {

if (dataSource == null) {

init();

}

Connection conn = null;

if (dataSource != null) {

conn =dataSource.getConnection();

}

return conn;

}

public static void main(String[] args)throws SQLException {

// test_insert();

test_query();

}

public static void test_insert() throwsSQLException {

System.out.println("-------------test_insert()-------------");

// 创建连接

Connection conn =getConnection();

// 创建SQL执行工具

QueryRunner qRunner = newQueryRunner(dataSource, true);

// 执行SQL插入

int n = qRunner.update(conn,

"insertinto tb_user(username,password) values(‘范芳铭‘,‘ffm‘)");

System.out.println("成功插入" + n + "条数据!");

// 关闭数据库连接

DbUtils.closeQuietly(conn);

}

public static void test_query() throwsSQLException {

System.out.println("-------------test_query()-------------");

// 创建连接

Connection conn =getConnection();

QueryRunner qRunner = newQueryRunner(true);

// 执行SQL查询,并获取结果

List<tb_user> list =(List<tb_user>) qRunner.query(conn,

"select username,password from tb_user ", new BeanListHandler(

tb_user.class));

// 输出查询结果

for (tb_user user : list) {

System.out.println(user);

}

//关闭数据库连接

DbUtils.closeQuietly(conn);

}

public class tb_user {

private String username;

private String password;

public tb_user(String username,String password) {

this.username =username;

this.password =password;

}

public String getUsername() {

return username;

}

public voidsetUsername(String username) {

this.username =username;

}

public String getPassword() {

return password;

}

public voidsetPassword(String password) {

this.password =password;

}

}

}

既然能插入,那么肯定也能读出来,但是我们在准备处理这个问题的生活,有好几个地方可能出错,比如List,比如tb_user,那么我们还是老办法,看看更加简单的办法行不行。

下面是一个尝试的方法,一个是直接读取数据,另外一个是转换为简单bean,而不是list,先看看吧。

package test.ffm83.commons.dbutils;

importjava.sql.Connection;

importjava.sql.SQLException;

importjava.util.Arrays;

importjava.util.List;

importjava.util.Properties;

importorg.apache.commons.dbcp.BasicDataSource;

importorg.apache.commons.dbcp.BasicDataSourceFactory;

importorg.apache.commons.dbutils.DbUtils;

importorg.apache.commons.dbutils.QueryRunner;

importorg.apache.commons.dbutils.handlers.ArrayHandler;

importorg.apache.commons.dbutils.handlers.BeanHandler;

import org.apache.commons.dbutils.handlers.BeanListHandler;

importtest.ffm83.commons.dbutils.QueryRunnerExample.Auser;

/**

* 通过commons dbUtils进行数据库的简单访问和实用,同时暴露一些异常 dbUtils1.6,Oracle驱动:class12

*

* @author 范芳铭

*/

public classQueryRunnerError {

private static BasicDataSourcedataSource = null;

private QueryRunner runner = null;

public QueryRunnerError() {

init();

runner = newQueryRunner(dataSource);

}

public static void init() {

if (dataSource != null) {

try {

dataSource.close();

} catch (Exceptione) {

e.printStackTrace();

}

dataSource = null;

}

try {

Properties p = newProperties();

p.setProperty("driverClassName","oracle.jdbc.driver.OracleDriver");

p.setProperty("url","jdbc:oracle:thin:@192.168.1.1:1521:fanfangming");

p.setProperty("password","ffm");

p.setProperty("username","ffm");

p.setProperty("maxActive","4");

p.setProperty("maxIdle","1");

p.setProperty("maxWait","100");

dataSource = (BasicDataSource)BasicDataSourceFactory

.createDataSource(p);

} catch (Exception e) {

e.printStackTrace();

}

}

public static synchronized ConnectiongetConnection() throws SQLException {

if (dataSource == null) {

init();

}

Connection conn = null;

if (dataSource != null) {

conn =dataSource.getConnection();

}

return conn;

}

public static void main(String[] args)throws SQLException {

// test_insert();

test_query();

}

public static void test_insert() throwsSQLException {

System.out.println("-------------test_insert()-------------");

// 创建连接

Connection conn =getConnection();

// 创建SQL执行工具

QueryRunner qRunner = newQueryRunner(dataSource, true);

// 执行SQL插入

int n = qRunner.update(conn,

"insertinto tb_user(username,password) values(‘范芳铭‘,‘ffm‘)");

System.out.println("成功插入" + n + "条数据!");

// 关闭数据库连接

DbUtils.closeQuietly(conn);

}

public static void test_query() throwsSQLException {

System.out.println("-------------test_query()-------------");

// 创建连接

Connection conn =getConnection();

QueryRunner qRunner = newQueryRunner(true);

//先看看能不能查询

String sql = "SELECT *FROM tb_user WHERE rownum < ? ";

System.out.println("1.TestQueryRunner query, ArrayHandler");

//把ResultSet第一行包装成Object[]

Object[] r1 = qRunner.query(conn,sql,new ArrayHandler(), "3");

System.out.println("  " + Arrays.deepToString(r1));

System.out.println("2.TestQueryRunner query, BeanHandler");

//把ResultSet第一行包装成一个JavaBean

tb_user r2 = qRunner.query(conn,sql,new BeanHandler<tb_user>(tb_user.class), "3");

System.out.println("  " + r2.toString());

/*               // 执行SQL查询,并获取结果

List<tb_user> list =(List<tb_user>) qRunner.query(conn,

"select username,password from tb_user ", new BeanListHandler(

tb_user.class));

// 输出查询结果

for (tb_user user : list) {

System.out.println(user);

}*/

//关闭数据库连接

DbUtils.closeQuietly(conn);

}

public class tb_user {

private String username;

private String password;

public tb_user(Stringusername, String password) {

this.username =username;

this.password =password;

}

public String getUsername() {

return username;

}

public voidsetUsername(String username) {

this.username =username;

}

public String getPassword() {

return password;

}

public voidsetPassword(String password) {

this.password =password;

}

}

}

运行结果如下:

-------------test_query()-------------

1.Test QueryRunnerquery, ArrayHandler

[范芳铭, ffm]

2.Test QueryRunnerquery, BeanHandler

Exception in thread"main" java.sql.SQLException: Cannot createtest.ffm83.commons.dbutils.QueryRunnerError$tb_user:test.ffm83.commons.dbutils.QueryRunnerError$tb_user Query: SELECT * FROMtb_user WHERE rownum < ?  Parameters:[3]

atorg.apache.commons.dbutils.AbstractQueryRunner.rethrow(AbstractQueryRunner.java:392)

atorg.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:351)

atorg.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:212)

attest.ffm83.commons.dbutils.QueryRunnerError.test_query(QueryRunnerError.java:105)

attest.ffm83.commons.dbutils.QueryRunnerError.main(QueryRunnerError.java:73)

这样一来,问题就比较清晰了,QueryRunner读取数据没有问题,在转换成对象的时候,可能有点状况。

仔细看这段错误异常:

Test QueryRunnerquery, BeanHandler

Exception in thread"main" java.sql.SQLException: Cannot createtest.ffm83.commons.dbutils.QueryRunnerError$tb_user:test.ffm83.commons.dbutils.QueryRunnerError$tb_user Query: SELECTUSERNAME,PASSWORD FROM tb_user WHERE rownum < ?  Parameters: [3]

是无法创建这个tb_user对象,那么问题可能不在QueryRunner上面,有可能问题出现在tb_user上面。

和创建有关的首先看构造函数,没有默认的构造函数,那么试一试加上。

这个调用的方法是反射方法,反射可能要调用空的默认的构造函数。因此导致异常的出现。

加一个默认构造函数:

public tb_user(){

}

好吧,运行下看看,异常还是出来了?

为什么额?

我们上面的tb_user是个什么东东呢?是个内部类。内部类在反射机制中,问题会变的很复杂,简单点,把tb_user拿出来吧,就有了2个class.

packagetest.ffm83.commons.dbutils;

/**

* 通过commons dbUtils进行数据库的简单访问和实用的javaBean

* QueryRunner 代码实例

* @author 范芳铭

*/

public classTb_user {

private String username;

private String password;

public Tb_user(){

}

public Tb_user(String username, Stringpassword) {

this.username = username;

this.password = password;

}

public String getUsername() {

return username;

}

public void setUsername(Stringusername) {

this.username = username;

}

public String getPassword() {

return password;

}

public void setPassword(Stringpassword) {

this.password = password;

}

@Override

public String toString(){

return "name:" +username + ",pass:" + password;

}

}

packagetest.ffm83.commons.dbutils;

importjava.sql.Connection;

importjava.sql.SQLException;

importjava.util.Arrays;

importjava.util.List;

importjava.util.Properties;

importorg.apache.commons.dbcp.BasicDataSource;

importorg.apache.commons.dbcp.BasicDataSourceFactory;

import org.apache.commons.dbutils.DbUtils;

importorg.apache.commons.dbutils.QueryRunner;

importorg.apache.commons.dbutils.handlers.ArrayHandler;

importorg.apache.commons.dbutils.handlers.BeanHandler;

importorg.apache.commons.dbutils.handlers.BeanListHandler;

/**

* 通过commons dbUtils进行数据库的简单访问和实用,同时暴露一些异常 dbUtils1.6,Oracle驱动:class12

* QueryRunner 代码实例

* @author 范芳铭

*/

public classQueryRunnerError {

private static BasicDataSourcedataSource = null;

private QueryRunner runner = null;

public QueryRunnerError() {

init();

runner = newQueryRunner(dataSource);

}

public static void init() {

if (dataSource != null) {

try {

dataSource.close();

} catch (Exceptione) {

e.printStackTrace();

}

dataSource = null;

}

try {

Properties p = new Properties();

p.setProperty("driverClassName","oracle.jdbc.driver.OracleDriver");

p.setProperty("url","jdbc:oracle:thin:@192.168.1.1:1521:fanfangming");

p.setProperty("password","ffm");

p.setProperty("username","ffm");

p.setProperty("maxActive","4");

p.setProperty("maxIdle","1");

p.setProperty("maxWait","100");

dataSource =(BasicDataSource) BasicDataSourceFactory

.createDataSource(p);

} catch (Exception e) {

e.printStackTrace();

}

}

public static synchronized ConnectiongetConnection() throws SQLException {

if (dataSource == null) {

init();

}

Connection conn = null;

if (dataSource != null) {

conn =dataSource.getConnection();

}

return conn;

}

public static void main(String[] args)throws SQLException {

// test_insert();

test_query();

}

public static void test_insert() throwsSQLException {

System.out.println("-------------test_insert()-------------");

// 创建连接

Connection conn =getConnection();

// 创建SQL执行工具

QueryRunner qRunner = newQueryRunner(dataSource, true);

// 执行SQL插入

int n = qRunner.update(conn,

"insertinto tb_user(username,password) values(‘范芳铭‘,‘ffm‘)");

System.out.println("成功插入" + n + "条数据!");

// 关闭数据库连接

DbUtils.closeQuietly(conn);

}

public static void test_query() throwsSQLException {

System.out.println("-------------test_query()-------------");

// 创建连接

Connection conn =getConnection();

QueryRunner qRunner = newQueryRunner(true);

//先看看能不能查询

String sql = "SELECTUSERNAME,PASSWORD FROM tb_user WHERE rownum < ? ";

System.out.println("TestQueryRunner query, ArrayHandler");

//把ResultSet第一行包装成Object[]

Object[] r1 = qRunner.query(conn,sql,new ArrayHandler(), "3");

System.out.println("  "+ Arrays.deepToString(r1));

System.out.println("TestQueryRunner query, BeanHandler");

//把ResultSet第一行包装成一个JavaBean

Tb_user rBean= qRunner.query(conn,sql,new BeanHandler<Tb_user>(Tb_user.class), "3");

System.out.println("  " + rBean.toString());

// 执行SQL查询,并获取结果

List<Tb_user> list =(List<Tb_user>) qRunner.query(conn,

"select username,password from tb_user ", newBeanListHandler<Tb_user>(

Tb_user.class));

// 输出查询结果

for (Tb_user user : list) {

System.out.println(user);

}

//关闭数据库连接

DbUtils.closeQuietly(conn);

}

}

运行结果如下:

-------------test_query()-------------

Test QueryRunnerquery, ArrayHandler

[范芳铭, ffm]

Test QueryRunnerquery, BeanHandler

name:范芳铭,pass:ffm

name:范芳铭,pass:ffm

name:2,pass:ffm

时间: 2024-08-03 01:39:27

apache commons 之 DbUtils QueryRunner使用之迷雾重重的相关文章

apache commons 之 DbUtils简介

apachecommons dbutils 是 Apache 组织提供的一个开源 JDBC 工具类库,对传统操作数据库的类进行二次封装,可以把结果集转化成List. 目前最新的版本是1.6. 官网地址为:http://commons.apache.org/proper/commons-dbutils/ DBUtils是个小巧的JDBC轻量级封装的工具包,其最核心的特性是结果集的封装,可以直接将查询出来的结果集封装成JavaBean,这就为我们做了最枯燥乏味.最容易出错的一大部分工作. 在使用DB

java.lang.ClassNotFoundException: org.apache.commons.dbutils.QueryRunner

七月 28, 2017 11:06:33 下午 org.apache.catalina.core.StandardWrapperValve invoke严重: Servlet.service() for servlet [com.itheima.transfer.web.TransferServlet] in context with path [/WEB19] threw exception [Servlet execution threw an exception] with root ca

Apache Commons DbUtils

1       概述 Commons DBUtils类库是小型的设计于易于使用JDBC的类集合.JDBC资源清理是平凡的,容易出错,以至于这些类从你的代码中抽象出清理代码,剩下你最初真正想要使用JDBC做的代码:查询和更新数据. 使用DBUtils的一些优势: 没有资源泄露的可能性.正确的JDBC编码并不难,但它耗时且乏味.这常常会导致连接泄漏可能很难追踪. 清晰的持久化代码.需要持久化数据到数据库中的代码大幅减少.剩下的代码清晰的表达你的意图没有凌乱的资源清理. 从ResultSet自动填充J

高性能jdbc封装工具 Apache Commons DbUtils 1.6

转载自原文地址:http://gao-xianglong.iteye.com/blog/2166444 前言 关于Apache的DbUtils中间件或许了解的人并不多,大部分开发人员在生成环境中更多的是依靠Hibernate.Ibatis.Spring JDBC.JPA等大厂提供的持久层技术解决方案,或者是企业内部自己研发的持久层技术.但无论如何,使用这些技术的初衷和本质都是为了能够减少企业开发成本,提高生产效率,降低耦合. 放眼企业级项目,Hibernate等ORM产品是首选,而互联网领域,大

Apache Commons DbUtils使用手册

Apache Commons DbUtils使用手册 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 一.介绍 DBUtils是个小巧的JDBC轻量级封装的工具包,其最核心的特性是在JDBC的基础上做了一层封装,主要是对结果集的封装,可以直接将查询出来的结果集封装成JavaBean,旨在简化JDBC代码混乱与重复.JDBC代码开发,存在很多难点:1)操作过程复杂,代码操作一个模式,大量的重复.2)结果集难以处理.3)到处都强制检查SQLExcepti

高性能jdbc封装工具 Apache Commons DbUtils 1.6(转载)

转载自原文地址:http://gao-xianglong.iteye.com/blog/2166444 前言 关于Apache的DbUtils中间件或许了解的人并不多,大部分开发人员在生成环境中更多的是依靠Hibernate.Ibatis.Spring JDBC.JPA等大厂提供的持久层技术解决方案,或者是企业内部自己研发的持久层技术.但无论如何,使用这些技术的初衷和本质都是为了能够减少企业开发成本,提高生产效率,降低耦合. 放眼企业级项目,Hibernate等ORM产品是首选,而互联网领域,大

Java连接数据库 #04# Apache Commons DbUtils

索引 通过一个简单的调用看整体结构 Examples 修改JAVA连接数据库 #03# HikariCP中的代码 DbUtils并非是什么ORM框架,只是对原始的JDBC进行了一些封装,以便我们少写一些重复代码.就“用”而言,仅仅需要学习QueryRunner类和ResultSetHandler接口就可以了.它的显著特点就是超级轻量级,总代码量目测似乎还不到一万行. 通过一个简单的调用看整体结构 public class TestDbUtils { private static final Qu

Apache Commons 工具类介绍及简单使用

Apache Commons包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动.下面是我这几年做开发过程中自己用过的工具类做简单介绍.   组件 功能介绍 BeanUtils 提供了对于JavaBean进行各种操作,克隆对象,属性等等. Betwixt XML与Java对象之间相互转换. Codec 处理常用的编码方法的工具类包 例如DES.SHA1.MD5.Base64等. Collections java集合框架操作. Compress java提供文件打包 压缩类库. C

编写更少量的代码:使用apache commons工具类库

Commons-configuration   Commons-FileUpload   Commons DbUtils   Commons BeanUtils  Commons CLI  Commons Codec   Commons Collections Commons DBCP    Commons HttpClient  Commons IO  Commons JXPath   Commons Lang   Commons Math   Commons Net   Commons Va