zoukankan      html  css  js  c++  java
  • 利用反射及jdbc元数据实现通用的查询方法

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------

    1.customer类:

    package com.lanqiao.javatest;

    import java.sql.Date;

    public class Customer {
    private int id;
    private String name;
    private String email;
    private Date birth;

    public Customer() {
    super();
    }

    public Customer(int id, String name, String email, Date birth) {
    super();
    this.id = id;
    this.name = name;
    this.email = email;
    this.birth = birth;
    }

    public int getId() {
    return id;
    }

    public void setId(int id) {
    this.id = id;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public String getEmail() {
    return email;
    }

    public void setEmail(String email) {
    this.email = email;
    }

    public Date getBirth() {
    return birth;
    }

    public void setBirth(Date birth) {
    this.birth = birth;
    }

    @Override
    public String toString() {
    return "Customer [id=" + id + ", name=" + name + ", email=" + email + ", birth=" + birth + "]";
    }
    }

    ------------------------------------------------------------------------------------------------------------------------------------------------------------

    student类:

    package com.lanqiao.javatest;

    public class Student {

    /*
    * FlowID:int,流水号
    * type:int ,英语四六级
    * IDcard:varchar(18),身份证号码
    * examcard:varchar(15),考试证号
    * studentname:varchar(20),学生姓名
    * localtion:varchar(20),区域
    * grade:int,成绩
    */
    private int flowId;
    private int type;
    private String idCard;
    private String examCard;
    private String studentName;
    private String localtion;
    private int grade;

    public Student() {
    super();
    }

    public Student(int flowId, int type, String idCard, String examCard, String studentName, String localtion,
    int grade) {
    super();
    this.flowId = flowId;
    this.type = type;
    this.idCard = idCard;
    this.examCard = examCard;
    this.studentName = studentName;
    this.localtion = localtion;
    this.grade = grade;
    }

    public int getFlowId() {
    return flowId;
    }
    public void setFlowId(int flowId) {
    this.flowId = flowId;
    }
    public int getType() {
    return type;
    }
    public void setType(int type) {
    this.type = type;
    }
    public String getIdCard() {
    return idCard;
    }
    public void setIdCard(String idCard) {
    this.idCard = idCard;
    }
    public String getExamCard() {
    return examCard;
    }
    public void setExamCard(String examCard) {
    this.examCard = examCard;
    }
    public String getStudentName() {
    return studentName;
    }
    public void setStudentName(String studentName) {
    this.studentName = studentName;
    }
    public String getLocaltion() {
    return localtion;
    }
    public void setLocaltion(String localtion) {
    this.localtion = localtion;
    }
    public int getGrade() {
    return grade;
    }
    public void setGrade(int grade) {
    this.grade = grade;
    }

    @Override
    public String toString() {
    return "Person [flowId=" + flowId + ", type=" + type + ", idCard=" + idCard + ", examCard=" + examCard
    + ", studentName=" + studentName + ", localtion=" + localtion + ", grade=" + grade + "]";
    }

    }

    -----------------------------------------------------------------------------------------------------------------------------------------------------------

    反射方法:

    package com.lanqiao.javatest;

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

    -----------------------------------------------------------------------------------------------------------------------------------------------------------

    实现主方法:

    package com.lanqiao.javatest;

    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.Driver;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Properties;

    import javax.management.ReflectionException;
    import javax.swing.text.FieldView;

    import org.junit.Test;

    import com.mysql.jdbc.ResultSetMetaData;
    import com.mysql.jdbc.Statement;

    /*
    * 建立一个统一的方法可以引用任何类的对象,实现数据库数据的处理
    * 通过一个对象获取任何一个数据库数据
    * */
    public class TestPreparedStatement {


    private static final Class<Customer> Customer = null;
    private static final Class<Student> Student = null;

    =================================================================================
    //连接数据库方法
    public static Connection getConnection() throws Exception{

    //四连接数据必不可少的
    String driverClass=null;
    String jdbcUrl=null;
    String user=null;
    String password=null;

    InputStream in=
    TestPreparedStatement.class.getClassLoader().getResourceAsStream("jdbc.properties");
    //其中getClass与TestConnection.classh互换使用
    Properties properties=new Properties();
    properties.load(in);

    driverClass=properties.getProperty("driver");
    jdbcUrl=properties.getProperty("jdbcUrl");
    user=properties.getProperty("user");
    password=properties.getProperty("password");

    // System.out.println(driverClass+jdbcUrl+user+password);
    Driver driver=(Driver)Class.forName(driverClass).newInstance();
    Properties info=new Properties();
    info.put("user", "root");
    info.put("password", "lxn123");
    Connection connection=driver.connect(jdbcUrl, info);
    return connection;
    }
    //测试类
    public static void testGetConn() throws Exception{
    System.out.println(getConnection());
    }

    ====================================================================================

    关闭资源的方法

    public void close(Connection connection,
    PreparedStatement preparedStatement,ResultSet resultSet) throws Exception{
    if (resultSet!=null) {
    resultSet.close();
    }
    if (preparedStatement!=null) {
    preparedStatement.close();
    }
    if (connection!=null) {
    connection.close();
    }
    }

    ===========================================================================================
    //student类获取数据
    public Student getStudent(String sql,Object...args) throws Exception{
    Student student=null;
    Connection connection=null;
    PreparedStatement preparedStatement=null;
    ResultSet resultSet=null;

    try {
    connection=TestPreparedStatement.getConnection();
    preparedStatement=connection.prepareStatement(sql);
    for(int i=0;i<args.length;i++){
    preparedStatement.setObject(i+1, args[i]);
    }
    resultSet=preparedStatement.executeQuery();
    //resultset里面的nest()方法,把查询到的数据,student获取
    if(resultSet.next()){
    student=new Student();
    student.setFlowId(resultSet.getInt(1));
    student.setType(resultSet.getInt(2));
    student.setIdCard(resultSet.getString(3));
    student.setExamCard(resultSet.getString(4));
    student.setStudentName(resultSet.getString(5));
    student.setLocaltion(resultSet.getString(6));
    student.setGrade(resultSet.getInt(7));
    }
    } catch (Exception e) {
    e.printStackTrace();
    }finally {
    close(connection,preparedStatement,resultSet);
    }

    return student;

    }

    ========================================================================================
    //Customer类获取数据
    public Customer getCustomer(String sql,Object...args) throws Exception{
    Customer customer=null;
    Connection connection=null;
    PreparedStatement preparedStatement=null;
    ResultSet resultSet=null;

    try {
    connection=TestPreparedStatement.getConnection();
    preparedStatement=connection.prepareStatement(sql);
    for(int i=0;i<args.length;i++){
    preparedStatement.setObject(i+1, args[i]);
    }
    resultSet=preparedStatement.executeQuery();
    //resultset里面的nest()方法,把查询到的数据,student获取
    if(resultSet.next()){
    customer=new Customer();
    customer.setId(resultSet.getInt(1));
    customer.setName(resultSet.getString(2));
    customer.setEmail(resultSet.getString(3));
    customer.setBirth(resultSet.getDate(4));
    }
    } catch (Exception e) {
    e.printStackTrace();
    }finally {
    close(connection,preparedStatement,resultSet);
    }

    return customer;
    }
    =======================================================================================
    //一个通用的方法的模板:可利用反射,实现数据库查询,插入值
    public <T> T getT(Class <T> clazz,String sql,Object...args) throws Exception{
    T entity=null;

    Connection connection=null;
    PreparedStatement preparedStatement=null;
    ResultSet resultSet=null;

    try {
    connection=TestPreparedStatement.getConnection();
    preparedStatement=connection.prepareStatement(sql);
    for(int i=0;i<args.length;i++){
    preparedStatement.setObject(i+1, args[i]);
    }
    resultSet=preparedStatement.executeQuery();

    //得到ResultSetMetaDate对象,获取数据库中的列和列名
    ResultSetMetaData rsmd=(ResultSetMetaData) resultSet.getMetaData();

    //创建一个Map<String,Object>对象,键:sql查询列的别名;值:列的值;
    Map<String, Object> values=new HashMap<String, Object>();

    //处理结果集,利用ResultSetMetaDate的方法,填充对应的map的对象
    while(resultSet.next()){
    //方法getColumnCount(),是获取ResultSetMetaDate对象获取数据库属性的个数
    for(int i=0;i<rsmd.getColumnCount();i++){
    String columnLabel=rsmd.getColumnLabel(i+1);//获取属性,它是字符串
    Object columnValues=resultSet.getObject(columnLabel);
    // System.out.println(columnValues);
    values.put(columnLabel, columnValues);
    }
    }

    //map不为空,利用反射创建clazz的对象
    if (values.size()>0) {
    entity=clazz.newInstance();

    //遍历map,利用反射class对应的对象的属性赋值
    for (Map.Entry<String, Object> entry: values.entrySet()) {
    String fieldName=entry.getKey();
    Object fieldValues=entry.getValue();
    System.out.println(fieldName+":"+fieldValues);
    //反射获取属性,并修改 xxxx(entity,fieldName,fieldValues);
    ReflectionUtils.setFieldValue(entity, fieldName, fieldValues);
    }

    }

    } catch (Exception e) {
    e.printStackTrace();
    }finally {
    close(connection,preparedStatement,resultSet);
    }
    return entity;
    }
    //测试getT()方法
    @Test
    public void testGetT() throws Exception{
    String sql="select id,name,email,birth from customer where id=?";
    Customer customer=getT(Customer.class,sql,2);
    System.out.println(customer);

    String sql1="SELECT flow_id flowId,type,id_card idCard,"
    + "exam_card examCard,student_name studentName ,"
    + "localtion,grade FROM test WHERE flow_id=?;";
    Student student=getT(Student.class,sql1,2);
    System.out.println(student);
    }
    =======================================================================================
    //ResultSetMetaDate,是描述ResultSet的元数据对象,即从中可以获取到结果集中有多少列,列名是。。。。。
    //用法:调用ResultSet的getMetaDate()方法,
    //好用的方法:int getColumnCount(),sql语句中包含那些列
    //String getColumnLabel(int column):获取指定列的别名,其中索引从1开始

    public void testResultSetMetaDate() throws Exception{
    Connection connection=null;
    PreparedStatement preparedStatement=null;
    ResultSet resultSet=null;

    try {
    String sql="SELECT flow_id flowid,type,id_card idcard,"
    + "exam_card examcard,student_name studentname ,"
    + "localtion,grade FROM test WHERE flow_id=?;";
    connection=TestPreparedStatement.getConnection();
    preparedStatement=connection.prepareStatement(sql);
    preparedStatement.setInt(1, 2);
    resultSet=preparedStatement.executeQuery();

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

    //1.得到ResultSetMetaDate对象,获取数据库中的列和列名
    ResultSetMetaData rsmd= (ResultSetMetaData) resultSet.getMetaData();
    while(resultSet.next()){
    //2.{}打印每一列的列名
    for(int i=0;i<rsmd.getColumnCount();i++){
    String columnLabel=rsmd.getColumnLabel(i+1);//获取指定列的别名
    Object columnValue=resultSet.getObject(columnLabel);//获取指定列的值

    values.put(columnLabel, columnValue);

    }
    }
    System.out.println(values);

    //反射获取
    Class clazz=Student.class;
    Object obj=clazz.newInstance();
    //强制for循环
    for(Map.Entry<String, Object> entry: values.entrySet()){
    String fieldName=entry.getKey();
    Object fieldValues=entry.getValue();
    System.out.println(fieldName+":"+fieldValues);
    }


    } catch (Exception e) {
    e.printStackTrace();
    }finally {
    close(connection,preparedStatement,resultSet);
    }
    }

    }

    数据库图片:

  • 相关阅读:
    限制字数输出,,超出的用...
    tablesorter 的使用
    二维数组根据某个特定字段排序
    对维数组排序 array_multisort()的应用
    多个字段关键字查询
    CASE WHEN用法
    type="submit" button的用法
    获取近30天的数据的时间方式
    练习题
    管理经济学第九章
  • 原文地址:https://www.cnblogs.com/lxnlxn/p/5769911.html
Copyright © 2011-2022 走看看