1.簡介
2、dbutils操作數據庫,實現的數據的CRUD
2.1、dbutils的核心類
1:QueryRunner– 具體類
|
Constructor for QueryRunner that takes a |
Executes SQL queries with pluggable strategies for handling 執行SQL查詢與可插拔策略處理結果集。這個類是線程安全的。 |
2:在執行select時直接返回查詢封裝以後結果。
在執行select時,必須要傳遞:
ResultSetHandler – 接口
它有很多的子類。
ResultSetHandler就是一個回調的接口。
2.2、dbutils的核心方法,update,query,接收一個dataSource
int |
update( String sql, Object... params) |
|
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對象封裝好的其他對象1 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() |
|
ArrayListHandler(RowProcessor
convert) |
|
protected Object[] |
handleRow(ResultSet
rs) 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的都是查詢第一行
|
|
handle(ResultSet
rs) |
將第一行結果封裝到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
|
|
handle(ResultSet
rs) |
查詢全部的結果,封裝成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
構造一個屬性編輯器對象爲一個有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);
}
}