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;
}
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);
}
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;
}
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);
}
Aggregations