利用反射将MySQL查询结果映射到对象(demo)

这篇博客展示了如何使用Java反射技术将MySQL查询结果转换为对象。文章提到,getCamelCase和getSetMethod是用于字符串处理的辅助方法,而日期映射可能存在问题,未深入探讨MySQL日期类型与Java类型的具体对应。java.sql.Date对应MySQL的date,而java.sql.Timestamp对应timestamp,两者在日期精度上有区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码如下

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

/*********************************
 * 文件名称: ResultData.java
 * 功能说明:  
 * 开发人员:
 * 开发时间:2018/8/29 16:29
 *********************************/
public class ResultData {

    /**
     * 将结果集映射到对象中
     *
     * 1,遍历结果集
     * 2,遍历列名
     * 3,匹配对象中的属性
     *
     * @param rs
     * @param tClass
     * @param <T>
     * @return
     */
    public <T> List<T> getData(ResultSet rs, Class<T> tClass) {
        List<T> list = new ArrayList<T>();
        boolean isCamelCase = true; // 是否启用驼峰命名法
        try {
            // 获取所有列名
            ResultSetMetaData rsMeta = rs.getMetaData();
            int columnCount = rsMeta.getColumnCount();
            List<String> columnList = new ArrayList<String>();
            for (int i = 1; i <= columnCount; i++) {
                columnList.add(rsMeta.getColumnLabel(i));
            }

            // 获取类中所有属性(包括private)
            Field[] fields = tClass.getDeclaredFields();

            T obj = null;
            // 遍历结果集
            while (rs.next()) {
                obj = tClass.newInstance();
                // 匹配列名和属性名
                for (String columnName : columnList) {
                    // 列名转成小写
                    String cName = columnName.toLowerCase();
                    // 是否开启驼峰命名法
                    if (isCamelCase) {
                        cName = getCamelCase(columnName);
                    }
                    // 将value映射到属性中
                    for (Field f : fields) {
                        // 属性名称
                        String fName = f.getName();
                        if (cName.equals(fName)) {
                            // 方法名称
                            String mName = getSetMethod(fName);
                            // 字段类型
                            String fType = f.getType().getName();

                            // 获取SET方法
                            Method m = tClass.getMethod(mName, new Class[]{f.getType()});

                            if ("java.lang.Integer".equals(fType) || "int".equals(fType)) {
                                m.invoke(obj, rs.getInt(columnName));
                            }
                            else if ("java.lang.Long".equals(fType) || "long".equals(fType)) {
                                m.invoke(obj, rs.getLong(columnName));
                            }
                            else if ("java.lang.Float".equals(fType) || "float".equals(fType)) {
                                m.invoke(obj, rs.getFloat(columnName));
                            }
                            else if ("java.lang.Double".equals(fType) || "double".equals(fType)) {
                                m.invoke(obj, rs.getDouble(columnName));
                            }
                            else if ("java.lang.Boolean".equals(fType) || "boolean".equals(fType)) {
                                m.invoke(obj, rs.getBoolean(columnName)); // 自动转0-false,>0true
                            }
                            else if ("java.lang.Shot".equals(fType) || "short".equals(fType)) {
                                m.invoke(obj, rs.getShort(columnName));
                            }
                            else if ("java.lang.String".equals(fType)) {
                                m.invoke(obj, rs.getString(columnName));
                            }
                            else if ("java.sql.Date".equals(fType)) {
                                m.invoke(obj, rs.getDate(columnName));
                            }
                            else if ("java.sql.Timestamp".equals(fType) || "java.util.Date".equals(fType)) {
                                m.invoke(obj, rs.getTimestamp(columnName));
                            }
                            else if ("java.math.BigDecimal".equals(fType)) {
                                m.invoke(obj, rs.getBigDecimal(columnName));
                            }
                            continue;
                        }
                    }
                }
                list.add(obj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 获取驼峰命名法名称
     *
     * @param str
     * @return
     */
    public String getCamelCase(String str) {
//        String[] strs = str.split("_");
//        StringBuffer sb = new StringBuffer(strs[0]);
//        for (int i = 1; i < strs.length; i++) {
//            sb.append(strs[i].substring(0, 1).toUpperCase() + strs[i].substring(1));
//        }
//        return sb.toString();

        char[] strs = str.toCharArray();
        int count = 0; // '_'个数
        int i = 0;
        int len = strs.length;
        while (i < len) {
            if ('_' == strs[i]) {
                count++;
                int j = i + 1;
                // 小写转大写
                strs[j] -= 32;
                // 向前覆盖
                while (j < len) {
                    strs[j-1] = strs[j];
                    j++;
                }
                len--;
            }
            i++;
        }
        return new String(strs, 0, strs.length - count);
    }


    /**
     * 获取set方法
     *
     * @param str
     * @return
     */
    public String getSetMethod(String str) {
        return "set" + str.substring(0, 1).toUpperCase() + str.substring(1);

//        char[] strs = str.toCharArray();
//        strs[0] -= 32;
//        // 新数组
//        char[] newStr = new char[3 + strs.length];
//        newStr[0] = 's';
//        newStr[1] = 'e';
//        newStr[2] = 't';
//        newStr[3] = strs[0];
//        for (int i = 4; i < newStr.length; i++) {
//            newStr[i] = strs[i-3];
//        }
//        return new String(newStr);
    }
}

其中getCamelCase和getSetMethod,我封装了对字符串的处理,用不用自行斟酌。

另外,我在日期映射上可能存在bug,没仔细考虑MySQL的日期类型对应Java的类型。

大概对应如下:

java.sql.Date和java.sql.Timestamp都是继承于java.util.Date。

java.sql.Date对应MySQL的date

java.sql.Timestamp对应MySQL的timestamp

区别是java.sql.date从MySQL中取出来的日期是只到日的(yyyy-MM-dd);

java.sql.Timestamp从MySQL中取出来的日期是精确到毫秒的(yyyy-MM-dd HH:mm:ss.s)。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值