java.sql.ResultSetMetaData 接口的使用(结果集元数据)

版权声明:wuyujin1997 reserve all rights. https://blog.csdn.net/wuyujin1997/article/details/89668631

intro

  • 有时需要了解结果集的元数据信息(之后与反射,泛型结合,编写通用方法,减少代码重复):
    columnCount 结果集的列数
    columnName 列的名称 // select columnName as columnLabel…
    columnLabel 列的别名(label)
    columnClassName 列在Java中对应的类型(可配合Class.forName(String className)获取Class类型的返回值)
    columnType 列在数据库中的类型(数值编号)
    columnTypeName 列在数据库中的类型名称
    columnDisplaySize 列大小

  • ResultSet -> ResultSetMetaData
    结果集(ResultSet)和结果集元数据(ResultSetMetaData)同为JDBC标准中的接口|标准。
    java.sql.ResultSet
    java.sql.ResultSetMetaData

  • metaData,元数据。
    可以通过resultSet引用获取其元数据信息:
    ResultSetMetaData resultSet.getMetaData()
    然后根据metaData得到想要的数据。

API

// getCon
String sql = "select username as 'U', password from user";
PreparedStatement pstmt = con.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();

ResultSetMetaData metaData = rs.getMetaData();
System.out.println(metaData.toString());

int columnCount = metaData.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
    String columnName = metaData.getColumnName(i);
    String columnLabel = metaData.getColumnLabel(i);
    String columnClassName = metaData.getColumnClassName(i);
    int columnType = metaData.getColumnType(i);
    String columnTypeName = metaData.getColumnTypeName(i);
    int columnDisplaySize = metaData.getColumnDisplaySize(i);
    System.out.printf("%s %s %s %s %s %s %s\n",
            i, columnName, columnLabel, columnClassName, columnType, columnTypeName, columnDisplaySize);
}

输出:

com.mysql.jdbc.ResultSetMetaData@41906a77 - Field level information: 
	com.mysql.jdbc.Field@4b9af9a9[catalog=easyui,tableName=user,originalTableName=user,columnName=U,originalColumnName=username,mysqlType=253(FIELD_TYPE_VAR_STRING),flags=, charsetIndex=33, charsetName=UTF-8]
	com.mysql.jdbc.Field@5387f9e0[catalog=easyui,tableName=user,originalTableName=user,columnName=password,originalColumnName=password,mysqlType=253(FIELD_TYPE_VAR_STRING),flags=, charsetIndex=33, charsetName=UTF-8]

1 username U java.lang.String 12 VARCHAR 50
2 password password java.lang.String 12 VARCHAR 50

其中com.mysql.jdbc.Field是符合JDBC标准的具体实现。

code

以下工具类是对之前工具类的一个补充。
JDBC CRUD小工具 DBUtil

import cn.jt.pojo.User;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Arrays;

/**
 * 获取RowMapper<T>下实例的工厂
 * 泛型 + 反射获取
 * @author wyj
 * @create 2019-04-28 18:24
 */
public class MapperGetter {

    /** 获取RowMapper<User>下的实例。
     * 但如果有多重JavaBean,这个工厂类的静态方法要一直扩张。违反OCP(Open Close Principle)。
     */
    public static RowMapper<User> getUserMapper() {
        RowMapper<User> mapper = new RowMapper<User>() {
            @Override
            public User mapRow(ResultSet rs) throws SQLException {
                User user = new User();
                user.setId(rs.getInt("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                return user;
            }
        };
        return mapper;
    }

    /** 通用方法,获取RowMapper<T>下的实例
     * 
     */
    public static <T> RowMapper<T> getMapper(Class<T> clazz) {
        RowMapper<T> mapper = new RowMapper<T>() {
            @Override
            public T mapRow(ResultSet rs) throws SQLException {
                T obj =  null;
                try {
                    obj = clazz.newInstance();
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                }

                ResultSetMetaData metaData = rs.getMetaData();
                int columnCount = metaData.getColumnCount();
                String[] columnLabelArr = new String[columnCount];
                for (int i = 0; i < columnCount; i++) {
                    columnLabelArr[i] = metaData.getColumnLabel(i + 1);
                }
                System.out.println(Arrays.toString(columnLabelArr));

                for (int i = 0; i < columnCount; i++) {
                    String columnLabel = columnLabelArr[i];
                    Method setter = null;
                    try {
                        setter = clazz.getDeclaredMethod(setterNameWrapper(columnLabel)); // username -> setUsername()方法
                        setter.invoke(obj, rs.getObject(columnLabel));    // obj.setUsername(rs.getObject("username"));
                    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
                return obj;
            }
        };
        return mapper;
    }

    /**
     * setter方法名包装器wrapper
     * @param name
     * @return
     */
    private static String setterNameWrapper(String name) {
        return "set" + nameWrapper(name);
    }

    /**
     * 首字母转大写
     * @param str
     * @return
     */
    private static String nameWrapper(String str) {
        String firstChar = String.valueOf(str.charAt(0));
        return str.replaceFirst(firstChar, firstChar.toUpperCase());  // 正则替换第一个字符
        // return firstChar.toUpperCase() + str.substring(1, str.length());  // 字符串拼接
    }

}

猜你喜欢

转载自blog.csdn.net/wuyujin1997/article/details/89668631
今日推荐