此类针对javaBean类写了一个通用的查询方法,List<javaBean> 通用查询更新中...;通过学习,深刻体会到学会反射就等于掌握了java基础的半壁江山!

一、使用JDBC驱动程序处理元数据:
 *   .java通过JDBC获得连接后得到一个Connection对象,可以从这个对象获得有关数据库管理系统的各种信息,
 *   包括数据库的各个表,表中的各个列,数据类型,触发器,存储过程等各方面的信息。根据这些信息,JDBC可以访问
 *   一个事先并不了解的数据库。
 *   .获取这些信息的方法都是在DataBaseMetaData类的对象上实现的,而DataBaseMetaData对象是在
 *   Connection对象上获得的。
二、ResultSetMetaData类
 *   .是描述ResultSet的元数据对象,可用于获取ResultSet对象中列的类型和属性信息的对象:
 *    ---getColumnName(int column) :获取指定列的名称
 *    ---getColumnCount() : 返回当前ResultSet对象中的列数
 *    ---getColumnLabel(int column) : 获取指定列的别名(索引从1开始)
 *    ---getColumnTypeName() : 检索指定列的数据库特定的类型名称
 *    ---getColumnDisplaySize() : 指示指定列的最大标准宽度,以字符为单位
 *    ---isNullable(int column) : 指示指定列中的值是否可以为null
 *    ---isAutoIncrement() : 指示是否自动为指定列进行编号,这样这些列仍然是只读的。
 *    
 *    调用ResultSet的getMetaData()方法得到ResultSetMetaData对象。

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;

public class JDBCTest2 {
 
 @Test
 public void testGet(){
    String sql="select id,name,email,birth from customers where id=?";
  
    Customer customer=get(Customer.class,sql,2);
    System.out.println(customer);
    /*
     * **FlowID对应数据库表属性字段,要求别名(flow_Id)对应javaBean的属性名**
     *   解析sql语句中列的别名、值,再通过反射技术把值赋给对应的属性,详细过程如下:
     *     1、先利用SQL语句进行查询,得到结果集
     *     2、利用反射创建实体类的对象
     *     3、获取结果集列的别名
     *      如何获取?
     *     4、再获取结果集的每一列的值,结合3得到一个Map,键:列的别名,值:列的值
     *     5、再利用反射为2的对应的属性赋值,属性即为Map的键,值即为Map的值。
     * */
    sql="select FlowId flow_Id,Type,IDCard,ExamCard,StudentName from examstudent where FlowId=?";
    Student stu=get(Student.class,sql,1);
    System.out.println(stu);
  
   }
    public <T> T get(Class<T> clazz, String sql,Object... args){
  
      /* 0、得到ResultSet对象
       * 1、得到ResultSetMetaData的对象
       * 2、创建一个Map<String,Object>对象
       * 3、处理结果集,利用ResultSetMetaData填充2对应的Map对象
       * 4、若Map不为空集,利用反射创建clazz对应的对象
       * 5、遍历Map对象,利用反射为Class对象对应的属性赋值
       *
       * */
  
      T entity=null;
  
      Connection con=null;
      PreparedStatement ps=null;
      ResultSet rs=null;
  
      try {
   
         con=JDBCTools.getConnection();
         ps=con.prepareStatement(sql);
         for (int i = 0; i < args.length; i++) {
            ps.setObject(i+1, args[i]);
         }
         rs=ps.executeQuery();
   
         ResultSetMetaData rsmd=rs.getMetaData();
   
         Map<String,Object> values=new HashMap<>();
         //因获取的是一个类...,所以if非while
         if(rs.next()) {
            for (int i = 0; i < rsmd.getColumnCount(); i++) {
               String columnLabel=rsmd.getColumnLabel(i+1);
               Object columnValue=rs.getObject(i+1);
               values.put(columnLabel, columnValue);
            }
    
         }
         //若Map不为空
         if (values.size()>0) {
            entity=clazz.newInstance();
            //为javaBean的属性赋值
            for (Map.Entry<String, Object> entry:values.entrySet()) {
                 String fieldName=entry.getKey();
                 Object value=entry.getValue();
                  ReflectionUtils.setFieldValue(entity, fieldName, value);
            }
         }
   
   
      } catch (Exception e) {
         e.printStackTrace();
      }finally{
         JDBCTools.release(rs, ps, con);
      }
  
      return entity;
   }
 }

帮助工具类

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 反射的 Utils 函数集合
 * 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数
 * @author Administrator
 *
 */
public class ReflectionUtils {

/**
  * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型
  * 如: public EmployeeDao extends BaseDao<Employee, String>
  * @param clazz
  * @param index
  * @return
  */
 @SuppressWarnings("unchecked")
 public static Class getSuperClassGenricType(Class clazz, int index){
  Type genType = clazz.getGenericSuperclass();
  
  if(!(genType instanceof ParameterizedType)){
   return Object.class;
  }
  
  Type [] params = ((ParameterizedType)genType).getActualTypeArguments();
  
  if(index >= params.length || index < 0){
   return Object.class;
  }
  
  if(!(params[index] instanceof Class)){
   return Object.class;
  }
  
  return (Class) params[index];
 }
 
 /**
  * 通过反射, 获得 Class 定义中声明的父类的泛型参数类型
  * 如: public EmployeeDao extends BaseDao<Employee, String>
  * @param <T>
  * @param clazz
  * @return
  */
 @SuppressWarnings("unchecked")
 public static<T> Class<T> getSuperGenericType(Class clazz){
  return getSuperClassGenricType(clazz, 0);
 }
 
 /**
  * 循环向上转型, 获取对象的 DeclaredMethod
  * @param object
  * @param methodName
  * @param parameterTypes
  * @return
  */
 public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes){
  
  for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
   try {
    //superClass.getMethod(methodName, parameterTypes);
    return superClass.getDeclaredMethod(methodName, parameterTypes);
   } catch (NoSuchMethodException e) {
    //Method 不在当前类定义, 继续向上转型
   }
   //..
  }
  
  return null;
 }
 
 /**
  * 使 filed 变为可访问
  * @param field
  */
 public static void makeAccessible(Field field){
  if(!Modifier.isPublic(field.getModifiers())){
   field.setAccessible(true);
  }
 }
 
 /**
  * 循环向上转型, 获取对象的 DeclaredField
  * @param object
  * @param filedName
  * @return
  */
 public static Field getDeclaredField(Object object, String filedName){
  
  for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
   try {
    return superClass.getDeclaredField(filedName);
   } catch (NoSuchFieldException e) {
    //Field 不在当前类定义, 继续向上转型
   }
  }
  return null;
 }
 
 /**
  * 直接调用对象方法, 而忽略修饰符(private, protected)
  * @param object
  * @param methodName
  * @param parameterTypes
  * @param parameters
  * @return
  * @throws InvocationTargetException
  * @throws IllegalArgumentException
  */
 public static Object invokeMethod(Object object, String methodName, Class<?> [] parameterTypes,
   Object [] parameters) throws InvocationTargetException{
  
  Method method = getDeclaredMethod(object, methodName, parameterTypes);
  
  if(method == null){
   throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");
  }
  
  method.setAccessible(true);
  
  try {
   return method.invoke(object, parameters);
  } catch(IllegalAccessException e) {
   System.out.println("不可能抛出的异常");
  }
  
  return null;
 }
 
 /**
  * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter
  * @param object
  * @param fieldName
  * @param value
  */
 public static void setFieldValue(Object object, String fieldName, Object value){
  Field field = getDeclaredField(object, fieldName);
  
  if (field == null)
   throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
  
  makeAccessible(field);
  
  try {
   field.set(object, value);
  } catch (IllegalAccessException e) {
   System.out.println("不可能抛出的异常");
  }
 }
 
 /**
  * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
  * @param object
  * @param fieldName
  * @return
  */
 public static Object getFieldValue(Object object, String fieldName){
  Field field = getDeclaredField(object, fieldName);
  
  if (field == null)
   throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
  
  makeAccessible(field);
  
  Object result = null;
  
  try {
   result = field.get(object);
  } catch (IllegalAccessException e) {
   System.out.println("不可能抛出的异常");
  }
  
  return result;
 }
}

总结:

1、why:如果只有一个结果集。但不知道结果集中有多少列,列的名字都是什么?

1>编写通用的查询方法时需要使用;

public <T> T get(Class<T> clazz,String sql,Object...sql)

2、what:用于描述ResultSet的对象。

3、how

1>得到ResultSetMetaData对象:调用ResultSet的getMetaData()方法

  ResultSetMetaData rsmd=resultSet.getMetaData();

2>ResultSetMetaData有哪些好用的方法:

  >int getColumnCount()结果集中包含哪些列

  >String getColumnLabel(int column):获取指定列的别名,其中索引从1开始。

<五>JDBC_利用反射及JDBC元数据编写通用的查询方法的更多相关文章

  1. Java -- JDBC_利用反射及 JDBC 元数据编写通用的查询方法

    先利用 SQL 进行查询,得到结果集: 利用反射创建实体类的对象:创建对象: 获取结果集的列的别名: 再获取结果集的每一列的值, 结合 3 得到一个 Map,键:列的别名,值:列的值: 再利用反射为 ...

  2. JDBC学习笔记(5)——利用反射及JDBC元数据编写通用的查询方法

    JDBC元数据 1)DatabaseMetaData /** * 了解即可:DatabaseMetaData是描述数据库的元数据对象 * 可以由Connection得到 */ 具体的应用代码: @Te ...

  3. 【转】JDBC学习笔记(5)——利用反射及JDBC元数据编写通用的查询方法

    转自:http://www.cnblogs.com/ysw-go/ JDBC元数据 1)DatabaseMetaData /** * 了解即可:DatabaseMetaData是描述数据库的元数据对象 ...

  4. MYSQL 之 JDBC(六): 增删改查(四)利用反射及JDBC元数据编写通用的查询

    1.先利用SQL进行查询,得到结果集2.利用反射创建实体类的对象:创建Student对象3.获取结果集的列的别名:idCard.studentName4.再获取结果集的每一列的值,结合3得到一个Map ...

  5. 利用反射及jdbc元数据实现通用的查询方法

    ---------------------------------------------------------------------------------------------------- ...

  6. JDBC--利用反射及JDBC元数据编写通用的查询方法

    1.JDBC元数据(ResuleSetMetaData):描述ResultSet的元数据对象,可以从中获取到结果集中的列数和列名等: --使用ResultSet类的getMetaData()方法获得R ...

  7. java攻城狮之路--复习JDBC(利用BeanUtils、JDBC元数据编写通用的查询方法;元数据;Blob;事务;批量处理)

    1.利用BeanUtils的前提得要加入以下两个jar包: commons-beanutils-1.8.0.jar commons-logging-1.1.1.jar package com.shel ...

  8. 利用反射及JDBC元数据编写通用查询方法

    元数据:描述数据的数据,ResultSetMetaData是描述ResultSet的元数据对象,从它可以得到数据集有多少了,每一列的列名... ResultSetMetaData可以通过ResultS ...

  9. JDBC课程5--利用反射及JDBC元数据(ResultSetMetaData)编写通用的查询方法

    /**-利用反射及JDBC元数据编写通用的查询方法 * 1.先利用SQl语句进行查询,得到结果集--> * 2.查找到结果集的别名:id--> * 3.利用反射创建实体类的对象,创建aut ...

随机推荐

  1. Linux 命令行总结

    1.使用ln不加参数,会创建硬链接,如果要创建软连接,需要加-s 参数. # ln test1 test8 -rw-r--r-- root root Nov : test1 -rw-r--r-- ro ...

  2. 【WIN10】绑定x:Bind

    在WP8.WP8中,我们知道有一个绑定{Binding},而在Win10中,新增了一个绑定{x:Bind} x:Bind :为编译时绑定 ,内存.内存相对于传统绑定都有优化 特性: 1.为强类型    ...

  3. URL、URN、URI的区别?

    URL.URN.URI区别 既然Web应用程序的文件等资源是放在服务器上,而服务器是因特网(Internet)上的主机,当然必须要有个方法,告诉浏览器到哪里取得文件等资源.通常会听到有人这么说:“你要 ...

  4. mysql连接超时与jndi数据源配置

    昨天有运营说添加活动不能用了,我就看了一下后台日志,发现访问数据库是报错: at java.lang.Thread.run(Thread.java:722) Caused by: com.mysql. ...

  5. webview滑动事件 与内部html左右滑动事件冲突问题的解决办法

    最近在做个混合app , 用html做页面,然后通过webview嵌套在activity中,效果是这样: 开始还是比较顺利,增加了菜单退出按钮,返回键页面回退功能,页面加载显示加载图标(在app端实现 ...

  6. jq小插件--方便设置css属性

    $.fn.extend({ setCss:function(name,value){ $(this).css(name,value) } }) 调用方式,如: $('.login-btn').setC ...

  7. Python验证码6位自动生成器

    Python验证码6位自动生成器

  8. python写计算器

    #!/usr/bin/env python # -*- coding:utf-8 -*- import re def chu(arg1): #定义加减 arg = arg1[0] #beacuse p ...

  9. js计算散点图方程式

    //pointArrayX,pointArrayY 为两个数组,分别为x轴对应的点和y轴对应的点 function getEquationPara(pointArrayX, pointArrayY) ...

  10. mysql事务和锁InnoDB

    背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备 ...