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);
}
}