码迷,mamicode.com
首页 > 数据库 > 详细

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

时间:2014-12-24 13:28:51      阅读:281      评论:0      收藏:0      [点我收藏+]

标签:apache   java   code   dbutils   

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 classQueryRunnerError {

    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

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

标签:apache   java   code   dbutils   

原文地址:http://blog.csdn.net/ffm83/article/details/42122657

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!