深入理解DbUtils

来源:互联网 发布:udp端口命令 编辑:程序博客网 时间:2024/06/09 18:16

自作QueryRunner

package cn.test.utils;

 

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

 

import javax.sql.DataSource;

 

public class MyQueryRunner {

 

//定义一个数据连接源

private DataSource source = null;

public MyQueryRunner(){

}

//new时通过构造函数把数据源传入

public MyQueryRunner(DataSource source){

this.source = source;

}

//执行数据库的增,删,该时的操作函数

public int update(String sql,Object...params)throws SQLException{

      //获取连接

Connection conn = source.getConnection();

     //获取预处理对象

PreparedStatement ps = conn.prepareStatement(sql);

     //对预处理对象传递参数

    int len = params.length;

    for(int i=0;i<len;i++)

    ps.setObject(i+1, params[i]);

    int num=ps.executeUpdate();

    conn.close();

    return num;

}

//对数据库进行查询操作的方法

public <T> T query(String sql,ResultSetHander<T> rsh,Object...params)throws SQLException{

      //获取数据库连接对象

Connection conn = source.getConnection();

       //获得预处理对象

PreparedStatement ps = conn.prepareStatement(sql);

       //对预处理对象设置参数

int len = params.length;

for(int i=0;i<len;i++)

ps.setObject(i+1,params[i]);

       //将获取的结果包装到ResultSet对象中

ResultSet rs = ps.executeQuery();

       //利用回调函数进行ResultSet数据处理

T t =rsh.handle(rs);

conn.close();

return t;

}

}

 

 

思想

要自己做个QueryRunner类要只到有两个方法对数据库个查询和对数据库修改

它需要数据源所以在其内部定义一个数据源成员变量并且我是在构造方法是传入的

接下就需要数据连接类,预处理对象难点是数据库查询方法

query方法中用到了对数据的封装这是我们就需要ResultHandler接口

它有个handle就是对数据处理方法

 

 

 

 

自作各种Handler

package cn.test.utils;

 

import java.sql.ResultSet;

import java.sql.SQLException;

 

public interface ResultSetHander<T> {

T handle(ResultSet rs)throws SQLException;

 

}

 

 

 

自作BeanListHandler

package cn.test.utils;

 

import java.lang.reflect.Method;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.List;

 

public class BeanListHandler<T> implements ResultSetHander<List<T>> {

private Class t;

  //利用new时把对象的Class的对象传入

public BeanListHandler(Class clazz){

this.t=clazz;

}

 

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

if (rs == null)

return null;

      //获取所有的方法

Method[] methods = t.getDeclaredMethods();

      //创建一个list集合对象

List<T> list = new ArrayList<T>();

      //遍历rs对象来取出数据

while (rs.next()) {

try {

            //利用反射获取其实例

T instance = (T) t.newInstance();

for (int i = 0; i < methods.length; i++) {

                //获取方法名称

String mn = methods[i].getName();

                 //如果方法名中没有set字符就跳过

int index = mn.indexOf("set");

if (index <= -1)

continue;

                 //切割获取出所要的字符窜

String pn = mn.substring(index + 3).toLowerCase();

                  //获取出参数的类型

Class type = (Class) methods[i].getGenericParameterTypes()[0];

if (type.getSimpleName().equals("int")

|| type.getSimpleName().equals("Integer")) {

                     //rs中封装的数据取出并做类型转换

int param = (Integer) rs.getObject(pn);

methods[i].invoke(instance, param);

else if (type.getSimpleName().equals("char")

|| type.getSimpleName().equals("Character")) {

char param = (Character) rs.getObject(pn);

methods[i].invoke(instance, param);

else if (type.getSimpleName().equals("String")) {

String param = (String) rs.getObject(pn);

methods[i].invoke(instance, param);

else if (type.getSimpleName().equals("float")

|| type.getSimpleName().equals("Float")) {

float param = (Float) rs.getObject(pn);

methods[i].invoke(instance, param);

else if (type.getSimpleName().equals("double")

|| type.getSimpleName().equals("Double")) {

double param = (Double) rs.getObject(pn);

methods[i].invoke(instance, param);

}

}

list.add(instance);

catch (Exception e) {

e.printStackTrace();

}

}

return list;

}

 

}

 

 

自制BeanHandler

package cn.test.utils;

 

import java.lang.reflect.Method;

import java.sql.ResultSet;

import java.sql.SQLException;

 

public class BeanHandler<T> implements ResultSetHander<T> {

 

private Class<T> clazz;

public BeanHandler(Class<T> clazz){

this.clazz=clazz;

}

public T handle(ResultSet rs) throws SQLException {

if(rs==nullreturn null;

T instance=null;

try{

Method[] methods = clazz.getDeclaredMethods();

instance = clazz.newInstance();

int len = methods.length;

while(rs.next()){

for(int i=0;i<len;i++){

String nm = methods[i].getName();

int index = nm.indexOf("set");

if(index<=-1)

continue;

String pn = nm.substring(index+3).toLowerCase();

Class type = (Class) methods[i].getGenericParameterTypes()[0];

if (type.getSimpleName().equals("int")

|| type.getSimpleName().equals("Integer")) {

int param = (Integer) rs.getObject(pn);

methods[i].invoke(instance, param);

else if (type.getSimpleName().equals("char")

|| type.getSimpleName().equals("Character")) {

char param = (Character) rs.getObject(pn);

methods[i].invoke(instance, param);

else if (type.getSimpleName().equals("String")) {

String param = (String) rs.getObject(pn);

methods[i].invoke(instance, param);

else if (type.getSimpleName().equals("float")

|| type.getSimpleName().equals("Float")) {

float param = (Float) rs.getObject(pn);

methods[i].invoke(instance, param);

else if (type.getSimpleName().equals("double")

|| type.getSimpleName().equals("Double")) {

double param = (Double) rs.getObject(pn);

methods[i].invoke(instance, param);

}

}

}

}catch(Exception e){

e.printStackTrace();

}

return instance;

}

 

}

 

 

 

自制ScalarHandler

package cn.test.utils;

 

import java.sql.ResultSet;

import java.sql.SQLException;

 

public class ScalarHandler implements ResultSetHander<Integer> {

 

public Integer handle(ResultSet rs) throws SQLException {

// TODO Auto-generated method stub

if(rs ==null

return 0;

    if(rs.next())

return rs.getInt(1);

    else

    return 0;

}

 

}

 

思想

BeanListHandler实现的思路

它是对许多数据处理这里就要list了每次获取数据还是利用方法上的反射


package cn.test.test1;

 

import java.lang.reflect.Method;

import java.lang.reflect.Type;

import java.util.HashMap;

import java.util.Map;

import java.util.Set;

 

public class MyUtils {

 

private MyUtils(){

}

populate的实现

public static <T> T populate(Class<T> clazz,Map map){

try{

//获取实例化

T t = clazz.newInstance();

//获取所有的方法对象及数据

          Method[] methonds = clazz.getDeclaredMethods();

          

          //遍历所有的方法

          for(int i=0;i<methonds.length;i++){

          //获取方法的名称

          String men = methonds[i].getName();

          //查找set在方法名出现的位置

          int index = men.indexOf("set");

          //如果小于等于-1表示没有直接跳过

          if(index<=-1)

          continue;

          

          //切割出后面的字符窜并把它转成小写

          String key = men.substring(index+3).toLowerCase();

          //获取parameter中的值其mapvalue是数组

          String[] objs = (String[]) map.get(key);

          //如果不存在指定的值后指定值大与1个跳过

          if(objs==null||objs.length>1)

          continue;

          

          //获取方法上的参数类型它是个数组

          Type[] type1 = methonds[i].getGenericParameterTypes();

          //获取第一个参数类型

                Class type = (Class) type1[0];

                

                //判断参数是哪些类型并赋值给它

          if(type.getSimpleName().equals("int")||type.getSimpleName().equals("Integer")){

          Integer obj = Integer.parseInt(objs[0]);

          methonds[i].invoke(t, obj);

          }else if(type.getSimpleName().equals("char")||type.getSimpleName().equals("Character")){

          Character obj =objs[0].charAt(0);

          methonds[i].invoke(t, obj);

          }else if(type.getSimpleName().equals("String")){

          String obj = (String)objs[0];

          methonds[i].invoke(t, obj);

          }else if(type.getSimpleName().equals("float")||type.getSimpleName().equals("Float")){

          Float obj =Float.parseFloat(objs[0]);

          methonds[i].invoke(t, obj);

          }else if(type.getSimpleName().equals("double")||type.getSimpleName().equals("Double")){

          Double obj =Double.parseDouble(objs[0]);

          methonds[i].invoke(t, obj);

          }

          }

return t;

}catch(Exception e){

e.printStackTrace();

throw new RuntimeException(e);

}

}

}

 

思想:

 我是利用反射来获取此类的所有直接方法,然后获取方法上的名称来判断是否是set方法如果不是就跳过继续遍历方法,

当找到后就把方法set后面的属性截取下来,从request中的map中作为key来查找如果为null则直接跳过

如果不为空把结果转为string[] 然后再获取方法上的参数的类型再利用多个if来判断是哪个类型接着就是强转了最后调用methond[i].invoke(obj,param)

 

可以使用字段来实现populate

 

 

 

 

BeanUtils中的getProperty的实现

方法一是通过类中定义的get方法来获取

public static Object getProperty(Object bean, String name) throws Exception {

Class clazz = bean.getClass();

Method[] methods = clazz.getDeclaredMethods();

for (Method method : methods) {

String mn = method.getName().toLowerCase();

if (!mn.contains("get") || !mn.contains(name))

continue;

else {

return method.invoke(bean, null);

}

}

return null;

}

 

 

方法二是通过类中的字段来获取

public static Object getProperty(Object bean,String name) throws IllegalArgumentException, IllegalAccessException{

Class clazz = bean.getClass();

Field[] fieds = clazz.getDeclaredFields();

for(Field fied:fieds){

fied.setAccessible(true);

String name1 = fied.getName();

if(!name1.equals(name))

continue;

else{

return fied.get(bean);

}

}

return null;

}

 

populate的强化版

 public  static <T> T populate(Class<T> clazz,Map map) throws Exception{

      T t = clazz.newInstance();

      Method[] method = clazz.getMethods();

      for(int i=0;i<method.length;i++){

      String mn =method[i].getName();

       int index = mn.indexOf("set");

       if(index<=-1)

      continue;

       String pnm = mn.substring(index+3).toLowerCase();

       Object param = (Object) map.get(pnm);

       if(param==null)

       continue;

            获取set方法上的参数Class类型

       Class type = method[i].getParameterTypes()[0];

            将获得的参数转换为set方法参数的指定的类型 

       T param2 = (T) type.cast(param);

method[i].invoke(t, param2);

      }

      return t;

  }

 

具体用法如下

public class Demo {

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

             Student s;

            Map<String,Object> map = new HashMap<String,Object>();

            map.put("id", 123);

            map.put("date"new SimpleDateFormat("yyyy/mm/dd").parse("1993/12/15"));

            map.put("name""yucui");

            map.put("sex","nv");

            s = MyUtils.populate(Student.class, map);

            System.out.println("id="+s.getId());

            System.out.println("name="+s.getName());

            System.out.println("sex="+s.getSex());

            System.out.println("Date="+s.getDate());

            

}

}

注意点:

在这里使用Class类中的cast方法要object原来是那类型如它是String类型则只会转化为String

还有它必须是引用类型不能为基本类型如intfloat

 

 

 

C:/Users/Administrator/AppData/Local/MyEclipse/Common/binary/com.sun.java.jdk.win32.x86_64_1.6.0.013/src.zip


0 0
原创粉丝点击