JDBC ResultSet 通过反射获取实体对象或者对象的集合

来更新下本文的JDBCTemplate类的内容,新增如下内容:

1. 字段驼峰映射功能,在数据库中是table_name,而在java中就可以写tableName

2. 扩展查询结果提取,增加考虑查询结果为一个单数据的返回情况(如查询结果就是一个long值)。备注:因为前一个版本适用的是查询结果为一个对象的多个属性,可以封装数为对象返回,但是如果查询结果就是一个long值,由于反射获取字段,而long没有属性,所以就无能为力了。


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class JDBCTemplate {
    private Logger logger = LoggerFactory.getLogger(JDBCTemplate.class);

    public List queryObjectList(Connection connection, String sql, Class requiredClass) throws Exception {
        return queryObjectList(connection, sql, requiredClass, false);
    }

    public List queryObjectListWithCameCase(Connection connection, String sql, Class requiredClass) throws Exception {
        return queryObjectList(connection, sql, requiredClass, true);
    }

    private List queryObjectList(Connection connection, String sql, Class requiredClass, boolean camelCase) throws Exception {
        List resutls = new ArrayList<>();
        business(connection, sql, requiredClass, resutls, false, camelCase);
        return resutls;
    }

    public <T> T queryObject(Connection connection, String sql, Class<T> requiredClass) throws Exception {
        return queryObject(connection, sql, requiredClass, false);
    }

    public <T> T queryObjectWithCameCase(Connection connection, String sql, Class<T> requiredClass) throws Exception {
        return queryObject(connection, sql, requiredClass, true);
    }

    private <T> T queryObject(Connection connection, String sql, Class<T> requiredClass, boolean camelCase) throws Exception {
        T instance = requiredClass.getDeclaredConstructor().newInstance();
        business(connection, sql, requiredClass, instance, true, camelCase);
        return instance;
    }

    private <T> T business(Connection connection, String selectSqlTmp, Class<T> requiredClass, Object object, boolean isSingle, boolean camelCase) throws Exception {
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            preparedStatement = connection.prepareStatement(selectSqlTmp);
            resultSet = preparedStatement.executeQuery();

            if (isSingle) {
                while (resultSet.next()) {
                    T instance = generateObject(resultSet, requiredClass, camelCase);
                    object = (T) instance;
                }
//                else {
//                    logger.info("没有查询结果!");
//                }
//                generateObjects(resultSet, requiredClass, null);
            } else {
                List<T> results = (List<T>) object;
                while (resultSet.next()) {
                    T instance = generateObject(resultSet, requiredClass, camelCase);
                    results.add(instance);
                }
//                else {
//                    logger.info("没有查询结果!");
//                }
            }
        } catch (Exception e) {
            logger.error("查询数据库出错!", e);
            throw e;
        } finally {
            try {
                if (preparedStatement != null) {
                    preparedStatement.close();
                }
                if (resultSet != null) {
                    resultSet.close();
                }
            } catch (SQLException throwables) {
                logger.error("preparedStatement error:", throwables);
            }
        }
        return null;
    }

    private <T> T generateObject(ResultSet resultSet, Class<T> requiredClass, boolean camelCase) throws Exception {
        T instance = requiredClass.getDeclaredConstructor().newInstance();
        Field[] declaredFields = requiredClass.getDeclaredFields();
        if (declaredFields == null || declaredFields.length == 0) {
            //也许查询的结果就是对象本身,比如就是查询一个long值出来
            instance = getFieldValue(resultSet, requiredClass);
        } else {
            for (Field declaredField : declaredFields) {
                declaredField.setAccessible(true);
                String fieldName = declaredField.getName();
                Class<?> type = declaredField.getType();
                declaredField.set(instance, getFieldValue(resultSet, fieldName, type, camelCase));
            }
        }
        return instance;
    }

    private <A> A getFieldValue(ResultSet resultSet, Class<A> fieldclazz) throws Exception {
        A object = null;
        try {
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
            while (resultSet.next()) {
                for (int i = 0; i < columnCount; i++) {
                    object = resultSet.getObject(i, fieldclazz);
                    break;
                }
                break;
            }
        } catch (Exception e) {
            logger.error("", e);
        }
        return object;
    }

    private <A> A getFieldValue(ResultSet resultSet, String fieldName, Class<A> fieldclazz, boolean camelCase) throws Exception {
        A object = null;
        try {
            if (camelCase) {
                //驼峰转下划线
                fieldName = CamelCaseUtil.toUnderlineCase(fieldName);
            }
            if (isExitColumn(resultSet, fieldName)) {
                object = (A) resultSet.getObject(fieldName, fieldclazz);
            }
        } catch (Exception e) {
            logger.error("", e);
        }
        return object;
    }

    private boolean isExitColumn(ResultSet resultSet, String fieldName) {
        try {
            resultSet.findColumn(fieldName);
            return true;
        } catch (SQLException throwables) {
            return false;
        }
    }
}
备注:
CamelCaseUtil见: 

https://blog.csdn.net/jfqqqqq/article/details/119408238

----------------------------------------------------------- 分割线  -----------------------------------------------------------------

最近想回顾jdbc编程和反射机制,于是产生了下面的代码,其中返回集合的接口绝对测试通过,返回对象的没有测试,应该也没有问题,如果有发现问题的小伙伴,帮忙指出下,谢谢!

package com.jfqqqq.test;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class JDBCTemplate {
    private Logger logger = LoggerFactory.getLogger(JDBCTemplate.class);

    public List queryObjectList(Connection connection, String sql, Class requiredClass) throws Exception {
        List resutls = new ArrayList<>();
        business(connection, sql, requiredClass, resutls, false);
        return resutls;

    }

    public <T> T queryObject(Connection connection, String sql, Class<T> requiredClass) throws Exception {
        T instance = requiredClass.getDeclaredConstructor().newInstance();
        business(connection, sql, requiredClass,  instance, true);
        return instance;

    }

    private <T> T business(Connection connection, String selectSqlTmp, Class<T> requiredClass, Object object, boolean isSingle) {
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            preparedStatement = connection.prepareStatement(selectSqlTmp);
            resultSet = preparedStatement.executeQuery();

            if (isSingle) {
                while (resultSet.next()) {
                    T instance = generateObjects(resultSet, requiredClass);
                    object = (T) instance;
                }
//                else {
//                    logger.info("没有查询结果!");
//                }
//                generateObjects(resultSet, requiredClass, null);
            } else {
                List<T> results = (List<T>) object;
                while (resultSet.next()) {
                    T instance = generateObjects(resultSet, requiredClass);
                    results.add(instance);
                }
//                else {
//                    logger.info("没有查询结果!");
//                }
            }
        } catch (Exception e) {
            logger.error("查询数据库出错!", e);
        } finally {
            try {
                if (preparedStatement != null) {
                    preparedStatement.close();
                }
                if (resultSet != null) {
                    resultSet.close();
                }
            } catch (SQLException throwables) {
                logger.error("preparedStatement error:", throwables);
            }
        }
        return null;
    }

    private <T> T generateObjects(ResultSet resultSet, Class<T> requiredClass) throws Exception {
        T instance = requiredClass.getDeclaredConstructor().newInstance();
        Field[] declaredFields = requiredClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            String fieldName = declaredField.getName();
            Class<?> type = declaredField.getType();
            declaredField.set(instance, getFieldValue(resultSet, fieldName, type));
        }
        return instance;
    }

    private <A> A getFieldValue(ResultSet resultSet, String fieldName, Class<A> fieldclazz) throws Exception {
        A object = null;
        try {
            if (isExitColumn(resultSet, fieldName)) {
                object = (A) resultSet.getObject(fieldName, fieldclazz);
            }
        } catch (Exception e) {
            logger.error("{}", e);
        }
        return object;
    }

    private boolean isExitColumn(ResultSet resultSet, String fieldName) {
        try {
            resultSet.findColumn(fieldName);
            return true;
        } catch (SQLException throwables) {
            return false;
        }
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值