
com.gitee.qdbp.jdbc.result.TablesRowToProperyMapper Maven / Gradle / Ivy
package com.gitee.qdbp.jdbc.result;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.jdbc.support.JdbcUtils;
import com.gitee.qdbp.able.jdbc.condition.TableJoin;
import com.gitee.qdbp.able.jdbc.condition.TableJoin.TableItem;
import com.gitee.qdbp.jdbc.model.AllFieldColumn;
import com.gitee.qdbp.jdbc.model.FieldColumns;
import com.gitee.qdbp.jdbc.model.FieldScene;
import com.gitee.qdbp.jdbc.model.TablesFieldColumn;
import com.gitee.qdbp.jdbc.plugins.DbPluginHelper;
import com.gitee.qdbp.tools.utils.VerifyTools;
/**
* 多个表关联的结果集行数据保存到JavaBean对应子对象的转换类
* 对于SYS_USER,SYS_USER_ROLE,SYS_ROLE这样的关联查询
* 新建一个结果类, 有SysUser user, SysUserRole userRole, SysRole role三个字段(子对象), 分别保存来自三个表的查询结果!
* 如果查询结果不需要关注SYS_USER_ROLE这个关联表, 也可以建SysUser user, SysRole role两个字段(子对象)的类来保存查询结果
* 实现思路:
* TableJoin有参数resultField, 用于指定表数据保存至结果类的哪个字段(子对象)
* 生成的查询语句的查询字段, 对于重名字段加上表别名作为前缀, 生成列别名,
* 如U__ID, U__REMARK, UR__ID, UR__REMARK, R__ID, R__REMARK
* 查询结果根据列别名找到字段名和表别名; 再根据表别名找到resultField, 根据字段名填充数据
*
* @author zhaohuihua
* @version 190617
*/
public class TablesRowToProperyMapper implements RowToBeanMapper, DbPluginHelper.Aware {
private final TableJoin tables;
private final Class mappedClass;
/** 插件容器 **/
private DbPluginHelper plugins;
public TablesRowToProperyMapper(TableJoin tables, Class mappedClass) {
this.tables = tables;
this.mappedClass = mappedClass;
}
protected final TableJoin getTables() {
return this.tables;
}
protected final Class getMappedClass() {
return this.mappedClass;
}
@Override
public void setPlugins(DbPluginHelper plugins) {
this.plugins = plugins;
}
@Override
public T mapRow(ResultSet rs, int rowNum) throws SQLException {
// 将ResultSet的行数据转换为Map
Map map = rowToMap(rs, rowNum);
// 利用工具类进行Map到JavaBean的转换
return plugins.getMapToBeanConverter().convert(map, getMappedClass());
}
protected Map rowToMap(ResultSet rs, int rowNum) throws SQLException {
// 1. 获取列名与字段名的对应关系
// 获取结果类的所有字段信息
AllFieldColumn all = plugins.parseAllFieldColumns(getTables());
FieldColumns fieldColumns = all.filter(FieldScene.RESULT);
Map result = new LinkedHashMap<>(); // 结果容器
Map> subs = new HashMap<>(); // 子对象容器
// 2. 根据TableJoin的resultField生成子Map对象
String majorField = tables.getMajor().getResultField();
if (VerifyTools.isNotBlank(majorField) && !majorField.equals("this")) {
subs.put(majorField, new LinkedHashMap());
}
for (TableItem item : tables.getJoins()) {
String itemField = item.getResultField();
if (VerifyTools.isNotBlank(itemField) && !itemField.equals("this")) {
subs.put(itemField, new LinkedHashMap());
}
}
if (!subs.isEmpty()) {
result.putAll(subs);
}
// 3. 根据列别名查找字段信息, 再找到resultField, 根据字段名填充数据
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
// 根据列别名查找字段信息
String columnAlias = JdbcUtils.lookupColumnName(rsmd, i);
TablesFieldColumn field = fieldColumns.findByColumnAlias(columnAlias);
if (field == null) {
continue; // 结果集的列在结果容器类中找不到对应的字段
}
// 获取resultField
String resultField = field.getResultField();
if (VerifyTools.isBlank(resultField)) {
continue; // 如果没有指定resultField, 说明不需要保存结果
}
// 将字段名和字段值根据resultField填充至对应的子对象中
// 如果resultField=this直接填充到主容器, 否则填充到指定的子容器
Map maps = resultField.equals("this") ? result : subs.get(resultField);
fillColumnValue(rs, i, field, maps);
}
return result;
}
protected void fillColumnValue(ResultSet rs, int index, TablesFieldColumn field, Map maps)
throws SQLException {
// 根据字段类型获取字段值
String fieldName = field.getFieldName();
Class> fieldType = field.getJavaType();
Object value = getColumnValue(rs, index, fieldType);
maps.put(fieldName, value);
}
protected Object getColumnValue(ResultSet rs, int index, Class> fieldType) throws SQLException {
return JdbcUtils.getResultSetValue(rs, index, fieldType);
}
/**
* TablesRowToProperyMapper的工厂类
*
* @author zhaohuihua
* @version 20210306
*/
public static class Factory implements FactoryOfTables, DbPluginHelper.Aware {
/** 插件容器 **/
private DbPluginHelper plugins;
/** 插件容器 **/
@Override
public void setPlugins(DbPluginHelper plugins) {
this.plugins = plugins;
}
@Override
public RowToBeanMapper getRowToBeanMapper(TableJoin tables, Class mappedClass) {
TablesRowToProperyMapper mapper = new TablesRowToProperyMapper<>(tables, mappedClass);
mapper.setPlugins(plugins);
return mapper;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy