oracle学习笔记(八)——结果集元数据ResultSetMetaData以及ResultSet转为对应的实体类框架

介绍

可用于获取关于 ResultSet 对象中列的类型和属性信息的对象,在持久框层框架(如:mybatis, hibernate)中被广泛的应用。

常用方法

  • int getColumnCount()
    返回此 ResultSet 对象中的列数

  • String getColumnLabel(int column)
    获取用于打印输出和显示的指定列的建议标题。建议标题通常由 SQL AS 子句来指定。

  • String getColumnName(int column)
    获取指定列的名称

    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("select ename,job,hiredate from employee");
    ResultSetMetaData resultSetMetaData = rs.getMetaData();
    int colCount = resultSetMetaData.getColumnCount();
    System.out.println("共有多少列:" + colCount);
    
    for (int i = 1; i <= colCount; i++) {
    	//得到列名
    	String colLabel = resultSetMetaData.getColumnLabel(i);
    	//通过列名得到该列的值
    	Object value = rs.getObject(colLabel);
    	System.out.println("第" + i + "列的值:" + value);
    }
    

一个简单的框架例子代码

以下是一个类,主要是讲数据库返回的ResultSet转为对应的实体类,要注意,实体类的属性名要与数据库中的列名保持一致
可以直接拿来用

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 将查询结果集的数据组装成相应的POJO(简单的Java对象)实体
 *
 * @author StarsOne
 * @date Create in  2019-4-27 0027 09:43:40
 * @description
 */
public class ResultSetHandler<T> {

    private List<T> beanList;
    private Class<T> type;
    private ResultSetMetaData metaData;
    private ResultSet resultSet;

    public ResultSetHandler(ResultSet resultSet, Class<T> type) {
        //初始化beanList
        beanList = new ArrayList<>();
        this.resultSet = resultSet;
        try {
            //获得数据集元数据
            this.metaData = resultSet.getMetaData();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        this.type = type;

        handlerData();

    }


    private void handlerData() {
        /*
        思路分析:
        1. 首先获得实体类中的所有属性:Class.getDeclareFields(),存放在Map<属性名,Field> 中
        2. 通过ResultSetMetaData结果集元数据中的列名,将查询结果相应的列的值取出来resultset.getObject()
        3. 将实体类的属性的名与结果集中相应的列进行反射赋值*/


        Field[] declaredFields = type.getDeclaredFields();
        Map<String, Field> fieldMap = new HashMap<>();
        for (Field declaredField : declaredFields) {
            //Map<"NUM",NUm属性对象>
            fieldMap.put(declaredField.getName().toUpperCase(), declaredField);
        }


        try {

            // while循环,遍历结果集ResultSet中的全部数据
            while (resultSet.next()) {
                //将一条数据对应的实体类对象添加到list中
                beanList.add(getT(fieldMap));
            }

        } catch (SQLException | IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
        }

    }

    /**
     * 获得每一条数据所对应的一个实体类对象
     * @param fieldMap 存放属性field的Map集合
     * @return 一个实体类对象
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws SQLException
     */
    private T getT(Map<String, Field> fieldMap) throws InstantiationException, IllegalAccessException, SQLException {
        // 获得查询结果中的列数
        int columnCount = metaData.getColumnCount();
        T target = type.newInstance();
        // 一次循环代表一列
        for (int i = 1; i <= columnCount; i++) {
            // 获得列的标题(列名)
            String columnLabel = metaData.getColumnLabel(i);
            // 检查此列是否有对应的属性存在
            if (fieldMap.containsKey(columnLabel)) {
                // 通过列名从Map中获得对应的Field对象
                Field field = fieldMap.get(columnLabel);
                field.setAccessible(true);

                //根据此属性的类型来调用相应的结果集方法,
                // 如:String ename --> resultSet.getString()
                Object value = null;
                Class<?> fieldType = field.getType();
                if (fieldType == String.class) { //Character
                    value = resultSet.getString(columnLabel);

                } else if (fieldType == Byte.class || fieldType == Byte.TYPE) { // int
                    value = resultSet.getByte(columnLabel);

                } else if (fieldType == Short.class || fieldType == Short.TYPE) { //
                    value = resultSet.getShort(columnLabel);

                } else if (fieldType == Integer.class || fieldType == Integer.TYPE) { //
                    value = resultSet.getInt(columnLabel);

                } else if (fieldType == Long.class || fieldType == Long.TYPE) { //
                    value = resultSet.getLong(columnLabel);

                } else if (fieldType == Double.class || fieldType == Double.TYPE) { //
                    value = resultSet.getDouble(columnLabel);

                } else if (fieldType == Float.class || fieldType == Float.TYPE) { //
                    value = resultSet.getFloat(columnLabel);

                } else if (fieldType == java.util.Date.class || fieldType == java.sql.Date.class) { //
                    value = resultSet.getDate(columnLabel);

                } else if (fieldType == java.sql.Time.class) { //
                    value = resultSet.getTime(columnLabel);

                } else if (fieldType == Boolean.class || fieldType == Boolean.TYPE) { //
                    value = resultSet.getBoolean(columnLabel);
                }

                field.set(target, value);
            } // end if
        } // end for
        return target;
    }

    /**
     * 获得list
     *
     * @return
     */
    public List<T> getBeanList() {
        return beanList;
    }
	
	public T getBean(){
		beanList!=null && beanList.size()>0?beanList.remove(0):null;
	}
	
}

posted @ 2019-05-10 13:19  Stars-one  阅读(976)  评论(0编辑  收藏