java通过反射机制来创建Dao层通用查询方法

    反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。那我们该如何使用呢?

我们首先得运用java中的Class类,Class是一个类,一个描述类的类(也就是描述类本身),封装了描述方法的Method,描述字段的Filed,描述构造器的Constructor等属性。首先我们要使用这个类首先要去API查看该类的定义和使用方法,通过该类来获取自己所想要得到类的所有属性的一种通用写法:

Class[] getDeclaredClasses()
          返回 Class 对象的一个数组,这些对象反映声明为此 Class 对象所表示的类的成员的所有类和接口。
 Constructor getDeclaredConstructor(Class... parameterTypes)
          返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
 Constructor[] getDeclaredConstructors()
          返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。
 Field getDeclaredField(String name)
          返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
 Field[] getDeclaredFields()
          返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
 Method getDeclaredMethod(String name, Class... parameterTypes)
          返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
 Metod[] getDeclaredMethods()
          返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

//这都是运用反射机制常见的几个方法的相关介绍。下面给大家介绍一个完整的反射机制使用方法:


(1)首先创建一个BaseDao,在该类里面创建通用查询方法:

package com.Myweb.util;
import java.lang.reflect.Field;
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;

//创建BaseDAO类,里面声明了了连接类型Connection类,

PreparedStatement类,结果集类ResultSet类;

public class BaseDao {
public static Connection conn;
public static PreparedStatement ps;
public static ResultSet rs; 

//创建了通用查讯类serachList类,返回结果类型是serachList,集合类型数据,因为可能查询到的数据不止一条,所以优先考虑List;

//该通用查询类有三个参数,第一个参数sql代表你要执行的sql语句,第二个参数pramps是你要传递你sql语句中所需要的参数值,因为考虑到参数可能不止一个,就用了数组Object[],因为不知道数组中参数的数据类型,这里会使用Object类,第三个参数clz代表的数据表所对应的封装类的类对象,代表这个类。

public static List serachList(String sql,Object[] pramps,Class clz){

try {

//这里我用的是c3p0连接池进行获取连接对象的,最后会贴上C3p0Util类的代码

conn=C3p0Util.getConn();
//设置sql查询对象值ps

ps=conn.prepareStatement(sql);

//这句话首先判断查询的参数是否为空,不为空的话把对应的参数设置到preparedstatement类对象中,以便对sql语句进行处理。

if(pramps != null && pramps.length > 0){
for (int i = 0; i < pramps.length; i++) {
ps.setObject(i+1, pramps[i]);
}}

List myList=new ArrayList<>();

//调用PreparedStatement类的executeQuery()方法来进行查询操作,将查询的数据赋值给结果集对象rs。

以便对数据进行相应的操作。


rs=ps.executeQuery();

// rs.next()方法介绍,指针移动到当前位置的下一行。ResultSet 指针的初始位置位于第一行之前;第一次调用next()方法将会把第一行设置为当前行;第二次调用next()方法指针移动到第二行,以此类推。这样就可以把之前通过sql语句查询到的数据映射到对应的表结构,每次取一条数据来进行相应的操作,

while(rs.next()){

//当取到第一条数据,我们怎么取出对应的字段值,和所对应的列数,如何使用该查询到的数据呢?我们需要使用ResultSetMetaData接口,因为该接口可用于获取关于 ResultSet 对象中列的类型和属性信息的对象。以下代码片段创建 ResultSet 对象 rs,创建 ResultSetMetaData 对象metaData,并使用 metaData 查找 rs 有多少列,因为ResultSet类有方法来获取到ResultSetMetaData,以便对结果集对象进行操作

ResultSetMetaData metaData=rs.getMetaData();


下面给大家介绍几个ResultSetMetaData中的常用方法:

 String getColumnClassName(int column)
          如果调用方法 ResultSet.getObject 从列中获取值,则返回构造其实例的 Java 类的完全限定名称。
 int getColumnCount()
          返回此 ResultSet 对象中的列数。
 int getColumnDisplaySize(int column)
          指示指定列的最大标准宽度,以字符为单位。
 String getColumnLabel(int column)
          获取用于打印输出和显示的指定列的建议标题。
 String getColumnName(int column)
          获取指定列的名称。
 int getColumnType(int column)
          获取指定列的 SQL 类型
//我们用到了getColumnCount()方法来获取结果集对象总列数:

int count=metaData.getColumnCount();//获取结果集总列数;

创建javabean对象实例,代表的是数据表所对应的封装类,类中属性名最好和表中字段名一致;

Object obj=clz.newInstance();//获取类对象的实例;

for (int i = 0; i
Object objvalue=rs.getObject(i+1);//获取对应列所对应的字段值
String colname= metaData.getColumnName(i+1);//获取对应列名;

Field field=clz.getDeclaredField(colname);//通过列名获取到字段对象,就是我们所说的属性;

//当需要访问私有字段,属性,方法的时候需要调用setAccessible方法,取消Java访问权限检查机制,这样就可以访问私有属性了。

field.setAccessible(true);

//此处调用了Field类的set方法,就是给封装类对象所对应的字段赋值操作,这样数据表对应的封装类的对象类就有值了,相当于查询到了理想的结果。

field.set(obj, objvalue);//将指定对象变量上此 Field 对象表示的字段设置为指定的新值

}

//因为考虑到查询的结果不止一条,用集合进行操作

myList.add(obj);//然后返回该结果集对象

}return myList;
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();

}finally{

//关闭连接池

C3p0Util.release(conn, ps, rs);
}

return null;//如果没有查询到就返回空值;

}

//下面就是写了一个测试类来测试查询结果,

public class TestBaseDao {


public static void main(String[] args) {
// TODO Auto-generated method stub
//集合查询
String sql="select * from sf_user";

List serachList = (List) BaseDao.serachList(sql,null,User.class);

System.out.println(serachList);

}

查询结果如下图:


[User [id=1, username=dsc, password=123456, telphone=13995972425, sex=男, registDate=2018-04-20]
, User [id=2, username=xww, password=123456, telphone=13487251559, sex=女, registDate=2018-04-20]
, User [id=3, username=null, password=null, telphone=null, sex=null, registDate=null]
, User [id=4, username=dsc, password=123456, telphone=13995972425, sex=男, registDate=null]
, User [id=5, username=zxf, password=123456, telphone=13995972425, sex=女, registDate=null]
, User [id=6, username=rrr, password=123456, telphone=13995972425, sex=男, registDate=2018-04-20]

]


 

你可能感兴趣的:(java通过反射机制来创建Dao层通用查询方法)