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()); // 字符串拼接
}
}