dbutils

1.簡介

DBUtils被設計爲一種體積小、透明且快速的工具類。
特色:
1.對於數據表的讀操作,他可以把結果轉換成List,Array,Set等java集合,便於程序員操作;
2.對於數據表的寫操作,也變得很簡單(只需寫sql語句)
3.可以使用數據源,使用JNDI,數據庫連接池等技術來優化性能--重用已經構建好的數據庫連接對象,而不像php,asp那樣,費時費力的不斷重複的構建和析構這樣的對象。

2、dbutils操作數據庫,實現的數據的CRUD


2.1、dbutils的核心類

1:QueryRunner– 具體類

QueryRunner()
Constructor for QueryRunner.

QueryRunner(DataSource ds) 

    Constructor for QueryRunner that takes a DataSource to use.


Executes SQL queries with pluggable strategies for handling ResultSets. This class is thread safe.

執行SQL查詢與可插拔策略處理結果集。這個類是線程安全的。

2:在執行select時直接返回查詢封裝以後結果。

                     在執行select時,必須要傳遞:

           ResultSetHandler – 接口

                            它有很多的子類。

                     ResultSetHandler就是一個回調的接口

2.2、dbutils的核心方法,updatequery,接收一個dataSource

 int

updateString sql, Object... params) 
          Execute an SQL INSERT, UPDATE, or DELETE query.

 

Parameters:

sql - The SQL statement to execute.

params - Initializes the PreparedStatement's IN (i.e. '?') parameters.

Returns:

The number of rows updated.

 

第一步:導入包:


第二步:以下操作update,delete,insert

1:insert

@Test

    public void insertDemo() throws Exception {

        // 1.聲明QueryRunner對象

        QueryRunnerrun = newQueryRunner(DBCPUtils.getDS());

        // 2.聲明個sql語句

        Stringsql = "insert into stud values(?,?)";

        run.update(sql,4, "");

    }

2:update

如果在處理時有參數,則可以調用

  Update(sql,Object...args) – 帶參數的方法。

3.delete

@Test

    public void delete() throws Exception {

        // 聲明QueryRunner對象

        QueryRunnerrun = newQueryRunner(DBCPUtils.getDS());

        // 聲明sql

        Stringsql = "delete  from stud where id = ?";

        run.update(sql,4);

    }

3、批量處理


4、管理事務

       在dbutils中,爲了可以讓用戶管理事務,用戶必須自己提供connection。而不是傳遞datasource.



以下是事務的實現

5、查詢

查詢有另一個核心類

       除了QueryRuner,還有一個ResultSetHandler

       這個ResultSetHanlder專門用於數據封裝回調的.

       以下每個子類,將結果封裝成不同的類型:而不返回resultSet這個對象,而是直接返回RestulSet對象封裝好的其他對象


ArrayHandler

–Object[] – 對象數組,只查詢第一行。只返回一行數據;

    @Test

    public void testArray() throws Exception {

        Stringsql = "select * from stud";

        QueryRunnerrun = newQueryRunner(DBCPUtils.getDS());

        Object[]obj = run.query(sql, new ArrayHandler());

        for (Object object : obj) {// 只返回第一行

            System.err.println(object);

        }

}

2.ArrayListHandler

 返回所有的結果,封裝成List<Object[]>


ArrayListHandler()
Creates a new instance of ArrayListHandler using a BasicRowProcessor for conversions.

ArrayListHandler(RowProcessor convert)
Creates a new instance of ArrayListHandler.

protected Object[]

handleRow(ResultSet rs)
Convert row's columns into an Object[].

Parameters:

rs - ResultSet to process.

Returns:

Object[], never null.


@Test

    public void testArrayList() throws Exception {

        Stringsql = "select * from stud";

        QueryRunnerrun = newQueryRunner(DBCPUtils.getDS());

        List<Object[]>list = run.query(sql, new ArrayListHandler());

        for (Object[] objects :list) {

            for (Object object :objects) {

                System.err.println(object);

            }

        }

}

輸出結果:

3.BeanHandler – 只要是沒有寫list的都是查詢第一行

BeanHandler(Class<T> type)
Creates a new instance of BeanHandler.

 

T

handle(ResultSet rs)
Convert the first row of the ResultSet into a bean with the Class given in the constructor.


將第一行結果封裝到Bean。

   示例:

@Test

    public void testBean() throws Exception {

        Stringsql = "select * from stud";

        QueryRunner run = new QueryRunner(DBCPUtils.getDS());

        Studstud = run.query(sql, new BeanHandler<Stud>(Stud.class));

        System.err.println(stud);//一行

}

結果:

Stud [id=2, name=張三, addr=北京]


4.BeanListHandler

BeanListHandler(Class<T> type)
Creates a new instance of BeanListHandler.

 

List<T>

handle(ResultSet rs)
Convert the whole ResultSet into a List of beans with the Class given in the constructor.

查詢全部的結果,封裝成List<Bean>

@Test

    public void testBeanList() throws Exception {

        Stringsql = "select * from stud";

        QueryRunnerrun = newQueryRunner(DBCPUtils.getDS());

        List<Stud>list = run.query(sql, new BeanListHandler<Stud>(Stud.class));

        for (Stud stud : list) {

            System.err.println(stud);

        }

}

QueryRunner和BeanListHandler內部實現:


public class QueryRunner extends AbstractQueryRunner {

public QueryRunner(DataSourceds) {

                super(ds);

    }

private <T> T query(Connection conn, boolean closeConn, String sql,ResultSetHandler<T> rsh, Object... params)

              throws SQLException {

              。。。//此處刪去源碼的一些不核心的判斷

        PreparedStatement stmt = null;

        ResultSet rs = null;

        T result = null;

        try {

            stmt = this.prepareStatement(conn, sql);

            this.fillStatement(stmt, params);

            rs = this.wrap(stmt.executeQuery());

            result = rsh.handle(rs);

        } catch (SQLException e) {

            this.rethrow(e, sql, params);

        } finally {

            try {

                close(rs);

            } finally {

                close(stmt);

                if (closeConn) { close(conn);  }

            }

        }

        return result;

}

}

public class BeanListHandler<T> implementsResultSetHandler<List<T>> {

 private finalClass<T> type;

 private finalRowProcessor convert;

public BeanListHandler(Class<T> type, RowProcessor convert) {

        this.type = type;

        this.convert = convert;

}

@Override

   public  List<T> handle(ResultSet rs) throws SQLException {

        return this.convert.toBeanList(rs, type);

  }

}



@Test

    public void testBeanList() throws Exception {

        Stringsql = "select * from stud";

        QueryRunnerrun = newQueryRunner(DBCPUtils.getDS());

        List<Stud>list = run.query(sql, new BeanListHandler<Stud>(Stud.class));

        for (Stud stud : list) {

            System.err.println(stud);

        }

    }

5.BeanMapHandler

  查詢全部的結果,將數據封裝成

 Map<key,Bean> - 多個key.

  BeanMapHandler總是以第一個列,爲key值,指數據:




6.ColumnListHandler

指定只查詢一個列的記錄List<Object>

  一般用於投影查詢一列。

         即:seelctsid from stud;

                或是

         Select name from stud;


8.MapHandler

  總是返回第一行,將第一行封裝成Map

  與ArrayHanler,BeanHandler

{

  Sid=S001,name=Jack,addr=NY

}



9.MapListHandler


10.ScalarHandler

標量。

       對於執行聚合函數時,就可以使用ScalerHandler,

       它總是返回一行一列的數據。且這個數經常是long。

              用於執行:

              Selectcount(*) from stud;

              Selectavg(money) from emps;


6、封裝成Bean時,如果數據庫中的列,不與Bean的setXxx方法相同解決方案


查詢將表中的信息,封裝到bean:

方式1:使用別名:


方式2:自己開發一ResultsetHandler的子類:


7.PropertyDescriptor屬性編輯器

對於 一個JavaBean來說,只要是有一個getXxxx或是setXxx就是已經是一個JavaBean。

       javaBean必須要擁有一個公開的無參數的構造方法。

 

public class PropertyDescriptor屬性編輯器
extends FeatureDescriptor
 
PropertyDescriptor(String propertyName, Class<?> beanClass) 
Constructs a PropertyDescriptor for a property that follows the standard Java convention by having getFoo and setFoo accessor methods.
構造一個屬性編輯器對象爲一個有set和get方法的屬性
 

PropertyDescriptor 描述 Java Bean 通過一對存儲器方法導出的一個屬性。

              一對是指

                     getXxx/setXxx




以下是基本的反射:

package cn.oracle.bean;

import java.lang.reflect.Constructor;

import java.lang.reflect.Method;

import org.junit.Test;

public class TestReflect {

    @Test

    public void reflectOne3() throws Exception{

       Class cls = Class.forName("cn.oracle.bean.One");

       //通過一個字的字節碼的構造方法去初始化這個類

       Constructor<?> cons = cls.getConstructor(String.class);

       Object obj = cons.newInstance("Jack");

       System.err.println("-----調用一個abc(String name)-----");

       Method abc2 = One.class.getMethod("abc",Object.class);

       abc2.invoke(obj, "張三1");//One.abc(張三);

       abc2.invoke(obj, "張三2");//One.abc(張三);

    }

    @Test

    public void reflectOne() throws Exception{

       Class cls = Class.forName("cn.oracle.bean.One");

       Object obj = cls.newInstance();//設置默認的構造方法

       //1:反射出abc方法,class.getMethod("方法名",參數類型的字節碼信息);

       //Method abc1 =One.class.getMethod("abc");

       //2:調用abc1

       //abc1.invoke(one);

       System.err.println("-----調用一個abc(String name)-----");

        Method abc2 = One.class.getMethod("abc",Object.class);

       abc2.invoke(obj, "張三1");//One.abc(張三);

       abc2.invoke(obj, "張三2");//One.abc(張三);

    }

   

    @Test

    public void reflectOne2() throws Exception{

//     One one = new One();

//     one.abc(1);//int

//     one.abc("你好");//String

//     one.abc(45.9D);//double

    }

}

class One{

    public One(String addr){

       System.err.println("構造方法。。。"+addr);

    }

   

    public void abc(){

       System.err.println("Hello");

    }

    public void abc(Object name){

       System.err.println("你好:"+name);

    }

}



因爲【它要通過get方法,獲取set方法的參數類型。

 

以下是如何通過get方法 解析到set方法去設置類型從而調用成功:

 

package cn.oracle.bean;

import java.lang.reflect.Method;

public class ReflectDemo2 {

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

       //先獲取getxxx方法

       Method getXxx = Two.class.getMethod("getName");

       //查詢getXxx方法的返回類型

       Class cls = getXxx.getReturnType();

       //先獲取到這個Method方法------------------------

       Object obj = new Two();

       Method m = Two.class.getMethod("setName",cls);

       //就可以從方法上獲取到這個方法上的參數類型

       Object param = "8998";

       //判斷類型

       if(cls==String.class){

           m.invoke(obj,param.toString());

       }else if(cls==Integer.class){

           m.invoke(obj,Integer.valueOf(""+param));

       }

    }

}

class Two{

    public Integer getName(){

       return null;

    }

    public void setName(Integer name){

       System.err.println("你好:"+name);

    }

   

}

在沒有getXxx的情況下,也可以調用成功:

package cn.oracle.bean;

import java.lang.reflect.Method;

public class ReflectDemo3 {

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

       //要求你在不知道類型的情況下,且沒有getXxx的情況下,調用成功這個方法

       //通過反射

       //獲取所有方法,找

       Method[] ms =Demo3.class.getDeclaredMethods();

       //在裏面找setName方法

       Method m = null;

       for(Method mm:ms){

           if(mm.getName().equals("setName")){

              m=mm;

              break;

           }

       }

       //獲取參數看看

       Class cls = m.getParameterTypes()[0];

       Object pp = "34342";

       if(cls==String.class){

           m.invoke(new Demo3(), "Jack");

       }else if(cls==Integer.class || cls==int.class){

           m.invoke(new Demo3(), 90);

       }

    }

}

class Demo3{

    public void setName(int name){

       System.err.println("你好大家:"+name);

    }

}

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章