Search in sources :

Example 16 with ReflectPropsHandler

use of org.sagacity.sqltoy.callback.ReflectPropsHandler in project sagacity-sqltoy by chenrenfei.

the class DialectUtils method getSaveOrUpdateReflectHandler.

/**
 * @todo 构造创建和修改记录时的反射
 * @param idFields
 * @param prepHandler
 * @param forceUpdateProps
 * @param unifyFieldsHandler
 * @return
 */
public static ReflectPropsHandler getSaveOrUpdateReflectHandler(final String[] idFields, final ReflectPropsHandler prepHandler, String[] forceUpdateProps, IUnifyFieldsHandler unifyFieldsHandler) {
    if (unifyFieldsHandler == null) {
        return prepHandler;
    }
    final Map<String, Object> addKeyValues = unifyFieldsHandler.createUnifyFields();
    final Map<String, Object> updateKeyValues = unifyFieldsHandler.updateUnifyFields();
    if ((addKeyValues == null || addKeyValues.isEmpty()) && (updateKeyValues == null || updateKeyValues.isEmpty())) {
        return prepHandler;
    }
    // update操作强制更新字段优先
    final Set<String> forceSet = new HashSet<String>();
    if (forceUpdateProps != null && forceUpdateProps.length > 0) {
        for (String field : forceUpdateProps) {
            forceSet.add(field.toLowerCase().replace("_", ""));
        }
    }
    // 强制修改字段赋值
    IgnoreCaseSet tmpSet = unifyFieldsHandler.forceUpdateFields();
    final IgnoreCaseSet forceUpdateFields = (tmpSet == null) ? new IgnoreCaseSet() : tmpSet;
    final int idLength = (idFields == null) ? 0 : idFields.length;
    // 构造一个新的包含update和save 的字段处理
    ReflectPropsHandler handler = new ReflectPropsHandler() {

        @Override
        public void process() {
            if (prepHandler != null) {
                prepHandler.setPropertyIndexMap(this.getPropertyIndexMap());
                prepHandler.setRowIndex(this.getRowIndex());
                prepHandler.setRowData(this.getRowData());
                prepHandler.process();
            }
            // 主键为空表示save操作
            if (idLength > 0 && this.getValue(idFields[0]) == null) {
                for (Map.Entry<String, Object> entry : addKeyValues.entrySet()) {
                    if (StringUtil.isBlank(this.getValue(entry.getKey()))) {
                        this.setValue(entry.getKey(), entry.getValue());
                    }
                }
            }
            // 修改属性值
            for (Map.Entry<String, Object> entry : updateKeyValues.entrySet()) {
                // 统一修改字段不在强制更新字段范围内
                if (!forceSet.contains(entry.getKey().toLowerCase())) {
                    if (StringUtil.isBlank(this.getValue(entry.getKey())) || forceUpdateFields.contains(entry.getKey())) {
                        this.setValue(entry.getKey(), entry.getValue());
                    }
                }
            }
        }
    };
    return handler;
}
Also used : ReflectPropsHandler(org.sagacity.sqltoy.callback.ReflectPropsHandler) Map(java.util.Map) HashMap(java.util.HashMap) IgnoreKeyCaseMap(org.sagacity.sqltoy.model.IgnoreKeyCaseMap) IgnoreCaseSet(org.sagacity.sqltoy.model.IgnoreCaseSet) HashSet(java.util.HashSet)

Example 17 with ReflectPropsHandler

use of org.sagacity.sqltoy.callback.ReflectPropsHandler in project sagacity-sqltoy by chenrenfei.

the class DialectUtils method saveAll.

/**
 * @todo 保存批量对象数据
 * @param sqlToyContext
 * @param entityMeta
 * @param pkStrategy
 * @param isAssignPK
 * @param insertSql
 * @param entities
 * @param batchSize
 * @param reflectPropsHandler
 * @param conn
 * @param dbType
 * @param autoCommit
 * @return
 * @throws Exception
 */
public static Long saveAll(SqlToyContext sqlToyContext, EntityMeta entityMeta, PKStrategy pkStrategy, boolean isAssignPK, String insertSql, List<?> entities, final int batchSize, ReflectPropsHandler reflectPropsHandler, Connection conn, final Integer dbType, final Boolean autoCommit) throws Exception {
    boolean isIdentity = pkStrategy != null && pkStrategy.equals(PKStrategy.IDENTITY);
    boolean isSequence = pkStrategy != null && pkStrategy.equals(PKStrategy.SEQUENCE);
    String[] reflectColumns;
    if ((isIdentity && !isAssignPK) || (isSequence && !isAssignPK)) {
        reflectColumns = entityMeta.getRejectIdFieldArray();
    } else {
        reflectColumns = entityMeta.getFieldsArray();
    }
    // 构造全新的新增记录参数赋值反射(覆盖之前的)
    ReflectPropsHandler handler = getAddReflectHandler(reflectPropsHandler, sqlToyContext.getUnifyFieldsHandler());
    handler = getSecureReflectHandler(handler, sqlToyContext.getFieldsSecureProvider(), sqlToyContext.getDesensitizeProvider(), entityMeta.getSecureFields());
    List paramValues = BeanUtil.reflectBeansToInnerAry(entities, reflectColumns, null, handler);
    int pkIndex = entityMeta.getIdIndex();
    // 是否存在业务ID
    boolean hasBizId = (entityMeta.getBusinessIdGenerator() == null) ? false : true;
    int bizIdColIndex = hasBizId ? entityMeta.getFieldIndex(entityMeta.getBusinessIdField()) : 0;
    // 标识符
    String signature = entityMeta.getBizIdSignature();
    Integer[] relatedColumn = entityMeta.getBizIdRelatedColIndex();
    String[] relatedColumnNames = entityMeta.getBizIdRelatedColumns();
    int relatedColumnSize = (relatedColumn == null) ? 0 : relatedColumn.length;
    // 无主键值以及多主键以及assign或通过generator方式产生主键策略
    if (pkStrategy != null && null != entityMeta.getIdGenerator()) {
        int bizIdLength = entityMeta.getBizIdLength();
        int idLength = entityMeta.getIdLength();
        Object[] rowData;
        boolean isAssigned = true;
        String idJdbcType = entityMeta.getIdType();
        Object[] relatedColValue = null;
        String businessIdType = hasBizId ? entityMeta.getColumnJavaType(entityMeta.getBusinessIdField()) : "";
        List<Object[]> idSet = new ArrayList<Object[]>();
        for (int i = 0, s = paramValues.size(); i < s; i++) {
            rowData = (Object[]) paramValues.get(i);
            // 判断主键策略关联的字段是否有值,合法性验证
            if (relatedColumn != null) {
                relatedColValue = new Object[relatedColumnSize];
                for (int meter = 0; meter < relatedColumnSize; meter++) {
                    relatedColValue[meter] = rowData[relatedColumn[meter]];
                    if (StringUtil.isBlank(relatedColValue[meter])) {
                        throw new IllegalArgumentException("对象:" + entityMeta.getEntityClass().getName() + " 生成业务主键依赖的关联字段:" + relatedColumnNames[meter] + " 值为null!");
                    }
                }
            }
            // 主键值为null,调用主键生成策略并赋值
            if (StringUtil.isBlank(rowData[pkIndex])) {
                isAssigned = false;
                rowData[pkIndex] = entityMeta.getIdGenerator().getId(entityMeta.getTableName(), signature, entityMeta.getBizIdRelatedColumns(), relatedColValue, null, idJdbcType, idLength, entityMeta.getBizIdSequenceSize());
            }
            if (hasBizId && StringUtil.isBlank(rowData[bizIdColIndex])) {
                rowData[bizIdColIndex] = entityMeta.getBusinessIdGenerator().getId(entityMeta.getTableName(), signature, entityMeta.getBizIdRelatedColumns(), relatedColValue, null, businessIdType, bizIdLength, entityMeta.getBizIdSequenceSize());
                // 回写业务主键值
                BeanUtil.setProperty(entities.get(i), entityMeta.getBusinessIdField(), rowData[bizIdColIndex]);
            }
            idSet.add(new Object[] { rowData[pkIndex] });
        }
        // 批量反向设置最终得到的主键值
        if (!isAssigned) {
            BeanUtil.mappingSetProperties(entities, entityMeta.getIdArray(), idSet, new int[] { 0 }, true);
        }
    }
    SqlExecuteStat.showSql("批量保存[" + paramValues.size() + "]条记录", insertSql, null);
    // sqlserver需要特殊化处理(针对timestamp问题)
    if (dbType == DBType.SQLSERVER) {
        return SqlUtilsExt.batchUpdateBySqlServer(sqlToyContext.getTypeHandler(), insertSql, paramValues, entityMeta.getFieldsTypeArray(), entityMeta.getFieldsDefaultValue(), entityMeta.getFieldsNullable(), batchSize, autoCommit, conn, dbType);
    }
    return SqlUtilsExt.batchUpdateByJdbc(sqlToyContext.getTypeHandler(), insertSql, paramValues, entityMeta.getFieldsTypeArray(), entityMeta.getFieldsDefaultValue(), entityMeta.getFieldsNullable(), batchSize, autoCommit, conn, dbType);
}
Also used : ArrayList(java.util.ArrayList) ReflectPropsHandler(org.sagacity.sqltoy.callback.ReflectPropsHandler) List(java.util.List) ArrayList(java.util.ArrayList)

Example 18 with ReflectPropsHandler

use of org.sagacity.sqltoy.callback.ReflectPropsHandler in project sagacity-sqltoy by chenrenfei.

the class SqlServerDialectUtils method save.

/**
 * @todo 保存对象
 * @param sqlToyContext
 * @param entity
 * @param conn
 * @param dbType
 * @param tableName
 * @return
 * @throws Exception
 */
public static Object save(SqlToyContext sqlToyContext, Serializable entity, final Connection conn, final Integer dbType, final String tableName) throws Exception {
    EntityMeta entityMeta = sqlToyContext.getEntityMeta(entity.getClass());
    final boolean isIdentity = entityMeta.getIdStrategy() != null && entityMeta.getIdStrategy().equals(PKStrategy.IDENTITY);
    final boolean isSequence = entityMeta.getIdStrategy() != null && entityMeta.getIdStrategy().equals(PKStrategy.SEQUENCE);
    String insertSql = generateInsertSql(dbType, entityMeta, tableName, entityMeta.getIdStrategy(), "isnull", "@mySeqVariable", isIdentity ? false : true);
    if (isSequence) {
        insertSql = "set nocount on DECLARE @mySeqVariable as numeric(20)=NEXT VALUE FOR " + entityMeta.getSequence() + " " + insertSql + " select @mySeqVariable ";
    }
    int pkIndex = entityMeta.getIdIndex();
    ReflectPropsHandler handler = DialectUtils.getAddReflectHandler(null, sqlToyContext.getUnifyFieldsHandler());
    handler = DialectUtils.getSecureReflectHandler(handler, sqlToyContext.getFieldsSecureProvider(), sqlToyContext.getDesensitizeProvider(), entityMeta.getSecureFields());
    Object[] fullParamValues = BeanUtil.reflectBeanToAry(entity, (isIdentity) ? entityMeta.getRejectIdFieldArray() : entityMeta.getFieldsArray(), null, handler);
    boolean needUpdatePk = false;
    // 是否存在业务ID
    boolean hasBizId = (entityMeta.getBusinessIdGenerator() == null) ? false : true;
    int bizIdColIndex = hasBizId ? entityMeta.getFieldIndex(entityMeta.getBusinessIdField()) : 0;
    // 标识符
    String signature = entityMeta.getBizIdSignature();
    Integer[] relatedColumn = entityMeta.getBizIdRelatedColIndex();
    // 主键采用assign方式赋予,则调用generator产生id并赋予其值
    if (entityMeta.getIdStrategy() != null && null != entityMeta.getIdGenerator()) {
        int idLength = entityMeta.getIdLength();
        int bizIdLength = entityMeta.getBizIdLength();
        Object[] relatedColValue = null;
        String businessIdType = hasBizId ? entityMeta.getColumnJavaType(entityMeta.getBusinessIdField()) : "";
        if (relatedColumn != null) {
            relatedColValue = new Object[relatedColumn.length];
            for (int meter = 0; meter < relatedColumn.length; meter++) {
                relatedColValue[meter] = fullParamValues[relatedColumn[meter]];
                if (relatedColValue[meter] == null) {
                    throw new IllegalArgumentException("对象:" + entityMeta.getEntityClass().getName() + " 生成业务主键依赖的关联字段:" + relatedColumn[meter] + " 值为null!");
                }
            }
        }
        if (StringUtil.isBlank(fullParamValues[pkIndex])) {
            // id通过generator机制产生,设置generator产生的值
            fullParamValues[pkIndex] = entityMeta.getIdGenerator().getId(entityMeta.getTableName(), signature, entityMeta.getBizIdRelatedColumns(), relatedColValue, null, entityMeta.getIdType(), idLength, entityMeta.getBizIdSequenceSize());
            needUpdatePk = true;
        }
        if (hasBizId && StringUtil.isBlank(fullParamValues[bizIdColIndex])) {
            fullParamValues[bizIdColIndex] = entityMeta.getBusinessIdGenerator().getId(entityMeta.getTableName(), signature, entityMeta.getBizIdRelatedColumns(), relatedColValue, null, businessIdType, bizIdLength, entityMeta.getBizIdSequenceSize());
            // 回写业务主键值
            BeanUtil.setProperty(entity, entityMeta.getBusinessIdField(), fullParamValues[bizIdColIndex]);
        }
    }
    final Object[] paramValues = fullParamValues;
    final Integer[] paramsType = entityMeta.getFieldsTypeArray();
    SqlExecuteStat.showSql("mssql单条记录插入", insertSql, null);
    final String realInsertSql = insertSql;
    PreparedStatement pst = null;
    Object result = SqlUtil.preparedStatementProcess(null, pst, null, new PreparedStatementResultHandler() {

        @Override
        public void execute(Object obj, PreparedStatement pst, ResultSet rs) throws SQLException, IOException {
            if (isIdentity) {
                pst = conn.prepareStatement(realInsertSql, PreparedStatement.RETURN_GENERATED_KEYS);
            } else {
                pst = conn.prepareStatement(realInsertSql);
            }
            if (null != paramValues && paramValues.length > 0) {
                int index = 0;
                for (int i = 0, n = paramValues.length; i < n; i++) {
                    // sqlserver timestamp类型的字段无需赋值
                    if (!paramsType[i].equals(java.sql.Types.TIMESTAMP)) {
                        SqlUtil.setParamValue(sqlToyContext.getTypeHandler(), conn, dbType, pst, paramValues[i], paramsType[i], index + 1);
                        index++;
                    }
                }
            }
            ResultSet keyResult = null;
            if (isSequence) {
                keyResult = pst.executeQuery();
            } else {
                pst.execute();
            }
            if (isIdentity) {
                keyResult = pst.getGeneratedKeys();
            }
            if (isSequence || isIdentity) {
                while (keyResult.next()) {
                    this.setResult(keyResult.getObject(1));
                }
            }
        }
    });
    // 无主键直接返回null
    if (entityMeta.getIdArray() == null) {
        return null;
    }
    if (result == null) {
        result = fullParamValues[pkIndex];
    }
    // 回置到entity 主键值
    if (needUpdatePk || isIdentity || isSequence) {
        BeanUtil.setProperty(entity, entityMeta.getIdArray()[0], result);
    }
    // 是否有子表进行级联保存
    if (!entityMeta.getCascadeModels().isEmpty()) {
        List subTableData = null;
        EntityMeta subTableEntityMeta;
        for (TableCascadeModel cascadeModel : entityMeta.getCascadeModels()) {
            final Object[] mainFieldValues = BeanUtil.reflectBeanToAry(entity, cascadeModel.getFields());
            final String[] mappedFields = cascadeModel.getMappedFields();
            subTableEntityMeta = sqlToyContext.getEntityMeta(cascadeModel.getMappedType());
            if (cascadeModel.getCascadeType() == 1) {
                subTableData = (List) BeanUtil.getProperty(entity, cascadeModel.getProperty());
            } else {
                subTableData = new ArrayList();
                Object item = BeanUtil.getProperty(entity, cascadeModel.getProperty());
                if (item != null) {
                    subTableData.add(item);
                }
            }
            if (subTableData != null && !subTableData.isEmpty()) {
                logger.info("执行save操作的级联子表{}批量保存!", subTableEntityMeta.getTableName());
                SqlExecuteStat.debug("执行子表级联保存操作", null);
                saveAll(sqlToyContext, subTableData, new ReflectPropsHandler() {

                    @Override
                    public void process() {
                        for (int i = 0; i < mappedFields.length; i++) {
                            this.setValue(mappedFields[i], mainFieldValues[i]);
                        }
                    }
                }, conn, dbType, null, null);
            } else {
                logger.info("未执行save操作的级联子表{}批量保存,子表数据为空!", subTableEntityMeta.getTableName());
            }
        }
    }
    return result;
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) SQLException(java.sql.SQLException) PreparedStatementResultHandler(org.sagacity.sqltoy.callback.PreparedStatementResultHandler) ArrayList(java.util.ArrayList) ReflectPropsHandler(org.sagacity.sqltoy.callback.ReflectPropsHandler) PreparedStatement(java.sql.PreparedStatement) TableCascadeModel(org.sagacity.sqltoy.config.model.TableCascadeModel) IOException(java.io.IOException) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) List(java.util.List)

Example 19 with ReflectPropsHandler

use of org.sagacity.sqltoy.callback.ReflectPropsHandler in project sagacity-sqltoy by chenrenfei.

the class ClickHouseDialectUtils method saveAll.

/**
 * @todo 保存批量对象数据
 * @param sqlToyContext
 * @param entityMeta
 * @param insertSql
 * @param entities
 * @param batchSize
 * @param reflectPropsHandler
 * @param conn
 * @param dbType
 * @param autoCommit
 * @return
 * @throws Exception
 */
public static Long saveAll(SqlToyContext sqlToyContext, EntityMeta entityMeta, String insertSql, List<?> entities, final int batchSize, ReflectPropsHandler reflectPropsHandler, Connection conn, final Integer dbType, final Boolean autoCommit) throws Exception {
    PKStrategy pkStrategy = entityMeta.getIdStrategy();
    boolean isIdentity = pkStrategy != null && pkStrategy.equals(PKStrategy.IDENTITY);
    boolean isSequence = pkStrategy != null && pkStrategy.equals(PKStrategy.SEQUENCE);
    String[] reflectColumns;
    boolean isAssignPK = isAssignPKValue(pkStrategy);
    if ((isIdentity && !isAssignPK) || (isSequence && !isAssignPK)) {
        reflectColumns = entityMeta.getRejectIdFieldArray();
    } else {
        reflectColumns = entityMeta.getFieldsArray();
    }
    // 构造全新的新增记录参数赋值反射(覆盖之前的)
    ReflectPropsHandler handler = DialectUtils.getAddReflectHandler(reflectPropsHandler, sqlToyContext.getUnifyFieldsHandler());
    handler = DialectUtils.getSecureReflectHandler(handler, sqlToyContext.getFieldsSecureProvider(), sqlToyContext.getDesensitizeProvider(), entityMeta.getSecureFields());
    List paramValues = BeanUtil.reflectBeansToInnerAry(entities, reflectColumns, null, handler);
    int pkIndex = entityMeta.getIdIndex();
    // 是否存在业务ID
    boolean hasBizId = (entityMeta.getBusinessIdGenerator() == null) ? false : true;
    int bizIdColIndex = hasBizId ? entityMeta.getFieldIndex(entityMeta.getBusinessIdField()) : 0;
    // 标识符
    String signature = entityMeta.getBizIdSignature();
    Integer[] relatedColumn = entityMeta.getBizIdRelatedColIndex();
    String[] relatedColumnNames = entityMeta.getBizIdRelatedColumns();
    int relatedColumnSize = (relatedColumn == null) ? 0 : relatedColumn.length;
    // 无主键值以及多主键以及assign或通过generator方式产生主键策略
    if (pkStrategy != null && null != entityMeta.getIdGenerator()) {
        int bizIdLength = entityMeta.getBizIdLength();
        int idLength = entityMeta.getIdLength();
        Object[] rowData;
        boolean isAssigned = true;
        String idJdbcType = entityMeta.getIdType();
        Object[] relatedColValue = null;
        String businessIdType = hasBizId ? entityMeta.getColumnJavaType(entityMeta.getBusinessIdField()) : "";
        List<Object[]> idSet = new ArrayList<Object[]>();
        for (int i = 0, s = paramValues.size(); i < s; i++) {
            rowData = (Object[]) paramValues.get(i);
            // 判断主键策略关联的字段是否有值,合法性验证
            if (relatedColumn != null) {
                relatedColValue = new Object[relatedColumnSize];
                for (int meter = 0; meter < relatedColumnSize; meter++) {
                    relatedColValue[meter] = rowData[relatedColumn[meter]];
                    if (StringUtil.isBlank(relatedColValue[meter])) {
                        throw new IllegalArgumentException("对象:" + entityMeta.getEntityClass().getName() + " 生成业务主键依赖的关联字段:" + relatedColumnNames[meter] + " 值为null!");
                    }
                }
            }
            // 主键值为null,调用主键生成策略并赋值
            if (StringUtil.isBlank(rowData[pkIndex])) {
                isAssigned = false;
                rowData[pkIndex] = entityMeta.getIdGenerator().getId(entityMeta.getTableName(), signature, entityMeta.getBizIdRelatedColumns(), relatedColValue, null, idJdbcType, idLength, entityMeta.getBizIdSequenceSize());
            }
            if (hasBizId && StringUtil.isBlank(rowData[bizIdColIndex])) {
                rowData[bizIdColIndex] = entityMeta.getBusinessIdGenerator().getId(entityMeta.getTableName(), signature, entityMeta.getBizIdRelatedColumns(), relatedColValue, null, businessIdType, bizIdLength, entityMeta.getBizIdSequenceSize());
                // 回写业务主键值
                BeanUtil.setProperty(entities.get(i), entityMeta.getBusinessIdField(), rowData[bizIdColIndex]);
            }
            idSet.add(new Object[] { rowData[pkIndex] });
        }
        // 批量反向设置最终得到的主键值
        if (!isAssigned) {
            BeanUtil.mappingSetProperties(entities, entityMeta.getIdArray(), idSet, new int[] { 0 }, true);
        }
    }
    SqlExecuteStat.showSql("批量保存[" + paramValues.size() + "]条记录", insertSql, null);
    return SqlUtilsExt.batchUpdateByJdbc(sqlToyContext.getTypeHandler(), insertSql, paramValues, entityMeta.getFieldsTypeArray(), entityMeta.getFieldsDefaultValue(), entityMeta.getFieldsNullable(), batchSize, autoCommit, conn, dbType);
}
Also used : PKStrategy(org.sagacity.sqltoy.config.model.PKStrategy) ArrayList(java.util.ArrayList) ReflectPropsHandler(org.sagacity.sqltoy.callback.ReflectPropsHandler) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

ReflectPropsHandler (org.sagacity.sqltoy.callback.ReflectPropsHandler)19 ArrayList (java.util.ArrayList)9 List (java.util.List)8 EntityMeta (org.sagacity.sqltoy.config.model.EntityMeta)6 HashMap (java.util.HashMap)5 TableCascadeModel (org.sagacity.sqltoy.config.model.TableCascadeModel)4 IOException (java.io.IOException)3 PreparedStatement (java.sql.PreparedStatement)3 ResultSet (java.sql.ResultSet)3 SQLException (java.sql.SQLException)3 Map (java.util.Map)3 PreparedStatementResultHandler (org.sagacity.sqltoy.callback.PreparedStatementResultHandler)3 IgnoreCaseSet (org.sagacity.sqltoy.model.IgnoreCaseSet)3 IgnoreKeyCaseMap (org.sagacity.sqltoy.model.IgnoreKeyCaseMap)3 Type (java.lang.reflect.Type)2 HashSet (java.util.HashSet)2 PKStrategy (org.sagacity.sqltoy.config.model.PKStrategy)2 SqlToyResult (org.sagacity.sqltoy.config.model.SqlToyResult)2 ReturnPkType (org.sagacity.sqltoy.dialect.model.ReturnPkType)2 DBType (org.sagacity.sqltoy.utils.DataSourceUtils.DBType)2