使用反射技术实现对JDBC dao的简化

来源:互联网 发布:淘宝上秒杀价是真的吗 编辑:程序博客网 时间:2024/05/06 12:51

    通常我们的dao层也就是实现业务的逻辑,通常会因为对象的不同,得到数据的不同,返回值不同,参数不同等等的不同原因,而变得很复杂。甚至一个对象就会产生一个数据接口类。如果一个项目中曾在很多的实体,那么数据操作就会变得繁复,冗余,所以我们可以利用JDK1.5以后定义的泛型技术结合反射技术进行数据业务的简化已达到简化代码的目的。

   首先,泛型技术是一种在JDK1.5以后出现的新的技术,它能够给我们带来很多的便利。比如我们在定义了一个数组时我们可以为他定义这里面存储的内容,也就是限定了这个数组曾放的内容为string,那么接下来如果你想要给这个数组赋值,如果你一不小心把一个Int数据放入了这个数组,他就会提示你,这个数组中只能放置string。也就避免了在运行时才会出现错误,而且在上万行代码中想要找那个出来是那个数组,也是很麻烦的事。所以泛型技术的出现给我们带来了太多的便利。

                   List userlist=new ArrayList();

   user就是一个你限定的存储内容类型,这个集合中只能放置user对象。

  然后是反射技术。对于反射技术。首先我们学习反射技术主要是为了学习javaee的框架,如:spring。在spring中大量的运用了反射技术。如AOP。

  反射到底是干什么的?有什么作用?反射可以做到的事情很多。不如在不知道一个类内容的情况下对类中的某一个特定的方法进行调用。

   首先一个类中主要有方法,属性,构造器。所以反射技术就对这三种类的内容进行解析。

 stu.class.getDeclaredFields();//返回所有的属性。private。protected,public,default

 注意:由于java是一门面向对象的语言,所以一般属性我们会私有化,不建议使用此方法。
  stu.class.getDeclaredMethods();//返回所有的方法。private。protected,public,default
  stu.class.getDeclaredConstructors();//返回所有的构造器。private。protected,public,default
  stu.class.getConstructors();//返回所有的public的构造器
  stu.class.getMethods();//返回public的方法
  stu.class.getFields();//返回public的属性

也可以得到类的加载器:

     stu.class.getClassLoader();

那我们得到这些做什么呢?

下面的代码会告诉你我们怎么来实现利用反射技术和泛型技术来操作JDBC数据业务:

1.首先新建实体类:stu类

package cn.bean;

public class stu {
 private int stuid;
 private String stuname;
 private int age;
 public stu(){
  
 }
    publicstu(int stuid,String stuname,int age){
  this.age=age;
  this.stuid=stuid;
  this.stuname=stuname;
 }
 public int getStuid() {
  return stuid;
 }
 public void setStuid(int stuid) {
  this.stuid = stuid;
 }
 public String getStuname() {
  return stuname;
 }
 public void setStuname(String stuname) {
  this.stuname = stuname;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 

}

 

user类

package cn.bean;

public class user {
 private int userid;
 private String username;
 
 public user() {
  super();
 }
 public user(int userid, String username) {
  super();
  this.userid = userid;
  this.username = username;
 }
 public int getUserid() {
  return userid;
 }
 public void setUserid(int userid) {
  this.userid = userid;
 }
 public String getUsername() {
  return username;
 }
 public void setUsername(String username) {
  this.username = username;
 }
 

}

2.创建接口层:

   package cn.dao.supdao;

import java.util.List;

public interface Supdao {
  
    public List findList(Class clazz,String sql,Object[]args);       
    
    public TfindInfo(Class clazz,String sql ,Object[] args);
   
    public intupdate(String sql,Object[] args) ;

}

3.对接口实现:

package cn.dao.supdao.impl;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import cn.dao.supdao.Supdao;
import cn.jdbc.conn;

public class SupdaoImpl implements Supdao {
  private conn c=null;
  private Connection connection=null;
  private PreparedStatement pstmt=null;
  private ResultSet rs=null;

 
 @Override
 public T findInfo(Class clazz, Stringsql,Object[] args){ 
   Tt=null;  
   //实例化链接类
   c=new conn();
   try {
      //建立连接
    connection=c.getConnection();
    //System.out.println(connection);
    //新建ststement对象
    pstmt=connection.prepareStatement(sql);
    //设置参数
    for(int i = 0; i < args.length; i++) {
     pstmt.setObject(i+1,args[i]);
    }
    //查询语句
    rs=pstmt.executeQuery();
    //获取数据对象
    ResultSetMetaDatarsmd=rs.getMetaData();
    //获取查询对象的行数
    intcount=rsmd.getColumnCount();
    //建立数组对象
    String[]colname = new String[count];
    //赋值给数组对象
    for(int i = 0; i < colname.length; i++)
    {
     colname[i]=rsmd.getColumnLabel(i+1); 
     //System.out.println(colname[i]);
    }
    //获得所有的类对象方法
    Method[]ms=clazz.getMethods();
    //遍历
    while(rs.next())
      //实例化类对象
     t=clazz.newInstance();
     //System.out.println(t+"dd");
     //对列名东湖租对象进行遍历匹配方法
     for(int i = 0; i < colname.length; i++)
     {
      StringcolName=colname[i].toLowerCase();
      //拼接对象方法注意属性的首字母大写
      StringmethedName="set"+colName.replaceFirst(colName.substring(0,1),colName.substring(0, 1).toUpperCase()) ;
      //遍历方法数组
      for(Method m:ms)
       //判断匹配列名和方法名
       if(methedName.equals(m.getName()))
         //判断是否符合对象的属性
        //System.out.println(clazz.getDeclaredField(colName).getType().getName());
          if(clazz.getDeclaredField(colName).getType().getName().equals("java.lang.String")){
         //执行该方法
         m.invoke(t,rs.getString(colName.toUpperCase()));
        }elseif(clazz.getDeclaredField(colName).getType().getName().equals("int")){
         m.invoke(t,rs.getInt(colName.toUpperCase()));
        }
        
       }
      }
     }
    }
    returnt;
  } catch (SecurityException e){
   // TODOAuto-generated catch block
   e.printStackTrace();
  } catch(IllegalArgumentException e) {
   // TODOAuto-generated catch block
   e.printStackTrace();
  } catch (SQLException e){
   // TODOAuto-generated catch block
   e.printStackTrace();
  } catch (InstantiationExceptione) {
   // TODOAuto-generated catch block
   e.printStackTrace();
  } catch (IllegalAccessExceptione) {
   // TODOAuto-generated catch block
   e.printStackTrace();
  } catch (NoSuchFieldExceptione) {
   // TODOAuto-generated catch block
   e.printStackTrace();
  } catch(InvocationTargetException e) {
   // TODOAuto-generated catch block
   e.printStackTrace();
  }finally{
   c.close(connection,pstmt, rs);
  }
  return t;
  
  
 
  
 }

 @Override
 public List findList(Class clazz, Stringsql,Object[] args){
   Tt=null;  
   //建立返回的数组
   List objList= newArrayList();  
   c=new conn();
   try {
      //开启连接
    connection=c.getConnection();
    //System.out.println(connection);
    pstmt=connection.prepareStatement(sql);
    //参数赋值
    for(int i = 0; i < args.length; i++) {
     pstmt.setObject(i+1,args[i]);
    }
    rs=pstmt.executeQuery();
    //获得查询对象的数据
    ResultSetMetaDatarsmd=rs.getMetaData();
    
    intcount=rsmd.getColumnCount();
    String[]colname = new String[count];
    //循环赋值
    for(int i = 0; i < colname.length; i++)
    {
     colname[i]=rsmd.getColumnLabel(i+1); 
     //System.out.println(colname[i]);
    }
    //获得方法数组
    Method[]ms=clazz.getMethods();
    //遍历
    while(rs.next())
    {
     t=clazz.newInstance();
     //System.out.println(t+"dd");
     //循环列名的数组
     for(int i = 0; i < colname.length; i++)
     {
      StringcolName=colname[i].toLowerCase();
      //拼接方法名首字母大写
      StringmethedName="set"+colName.replaceFirst(colName.substring(0,1),colName.substring(0, 1).toUpperCase()) ;
      for(Method m:ms)
       //判断方法名是否匹配
       if(methedName.equals(m.getName()))
         //判断属性对象 并执行方法
        //System.out.println(clazz.getDeclaredField(colName).getType().getName());
        if(clazz.getDeclaredField(colName).getType().getName().equals("java.lang.String")){
         
         m.invoke(t,rs.getObject(colName.toUpperCase()));
        }elseif(clazz.getDeclaredField(colName).getType().getName().equals("int")){
         m.invoke(t,rs.getInt(colName.toUpperCase()));
        }
        
       }
      }
      
     }
     objList.add(t);
    }
    returnobjList;
  } catch (SecurityException e){
   // TODOAuto-generated catch block
   e.printStackTrace();
  } catch(IllegalArgumentException e) {
   // TODOAuto-generated catch block
   e.printStackTrace();
  } catch (SQLException e){
   // TODOAuto-generated catch block
   e.printStackTrace();
  } catch (InstantiationExceptione) {
   // TODOAuto-generated catch block
   e.printStackTrace();
  } catch (IllegalAccessExceptione) {
   // TODOAuto-generated catch block
   e.printStackTrace();
  } catch (NoSuchFieldExceptione) {
   // TODOAuto-generated catch block
   e.printStackTrace();
  } catch(InvocationTargetException e) {
   // TODOAuto-generated catch block
   e.printStackTrace();
  }finally{
   c.close(connection,pstmt, rs);
  }
  returnobjList; 
  
  
 }

 @Override
 public int update(String sql, Object[] args){
  try
   //实例化连接类
   c=newconn();
   //建立连接
   connection=c.getConnection();
   //获得statement对象
   pstmt=connection.prepareStatement(sql);
   //注入参数
   for (int i =0; i < args.length; i++) {
    pstmt.setObject(i+1,args[i]);
   }
   //返回影响的行数
   returnpstmt.executeUpdate();
  } catch (SQLException e){
   // TODOAuto-generated catch block
   e.printStackTrace();
  }
  return 0;
 }

}

4.测试代码:

  //测试findlist方法
  SupdaoImpl sup=newSupdaoImpl();
  List userlist=newArrayList();
  userlist=sup.findList(stu.class,"select * from stu where age=?",new Object[]{"20"});
  
  for (int i = 0; i <userlist.size(); i++) {
   System.out.println("姓名:"+userlist.get(i).getStuname()+"编号:"+userlist.get(i).getStuid()+"年龄:"+userlist.get(i).getAge());
  }
  
  
  //测试update方法
  int a=sup.update("insertinto  emp values(?,?)",newObject[]{"1001","xue"});
       System.out.println(a);
 }

5.输出结果:

链接成功!
姓名:HOBE编号:1年龄:20
姓名:KAKA编号:2年龄:20
姓名:KOBE编号:3年龄:20
姓名:CR7编号:4年龄:20
姓名:巴神编号:5年龄:20