use of org.sagacity.sqltoy.config.model.TableCascadeModel in project sagacity-sqltoy by chenrenfei.
the class EntityManager method parseCascade.
/**
* @todo 解析主键关联的子表信息配置(外键关联)
* @param sqlToyContext
* @param entityMeta
* @param entity
* @param field
* @param idList
*/
private void parseCascade(SqlToyContext sqlToyContext, EntityMeta entityMeta, Entity entity, Field field, List<String> idList) {
// 主表关联多子表记录
OneToMany oneToMany = field.getAnnotation(OneToMany.class);
OneToOne oneToOne = field.getAnnotation(OneToOne.class);
if (oneToMany == null && oneToOne == null) {
return;
}
TableCascadeModel cascadeModel = new TableCascadeModel();
String[] fields;
String[] mappedFields;
String load = null;
String orderBy = null;
String update = null;
// oneToMany
if (oneToMany != null) {
fields = oneToMany.fields();
mappedFields = oneToMany.mappedFields();
cascadeModel.setCascadeType(1);
cascadeModel.setMappedType((Class) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]);
load = oneToMany.load();
orderBy = oneToMany.orderBy();
update = oneToMany.update();
// 是否交由sqltoy进行级联删除,数据库本身存在自动级联机制
cascadeModel.setDelete(oneToMany.delete());
} else {
fields = oneToOne.fields();
mappedFields = oneToOne.mappedFields();
cascadeModel.setCascadeType(2);
cascadeModel.setMappedType(field.getType());
load = oneToOne.load();
update = oneToOne.update();
cascadeModel.setDelete(oneToOne.delete());
}
// 获取子表的信息(存在递归调用)
EntityMeta subTableMeta = getEntityMeta(sqlToyContext, cascadeModel.getMappedType());
if ((fields == null || fields.length == 0) && idList.size() == 1) {
fields = entityMeta.getIdArray();
}
if (fields == null || fields.length != mappedFields.length) {
throw new IllegalArgumentException(StringUtil.fillArgs("主表:{}的fields 跟子表:{} mappedFields 长度不一致,请检查!", entityMeta.getTableName(), subTableMeta.getTableName()));
}
String[] mappedColumns = new String[fields.length];
// 剔除下划线,避免手工维护时将属性名称写成数据库字段名称
fields = StringUtil.humpFieldNames(fields);
mappedFields = StringUtil.humpFieldNames(mappedFields);
// 主表字段名称
for (int i = 0; i < fields.length; i++) {
// 检查属性名称配置是否正确
if (entityMeta.getFieldMeta(fields[i]) == null) {
throw new IllegalArgumentException(StringUtil.fillArgs("表级联配置对应主表:{}的field属性:{} 并不存在,请检查!", entityMeta.getTableName(), fields[i]));
}
if (subTableMeta.getFieldMeta(mappedFields[i]) == null) {
throw new IllegalArgumentException(StringUtil.fillArgs("表级联配置对应子表:{}的field属性:{} 并不存在,请检查!", subTableMeta.getTableName(), mappedFields[i]));
}
// 提取子表属性对应的数据库字段名称,并进行关键词处理
mappedColumns[i] = ReservedWordsUtil.convertWord(subTableMeta.getColumnName(mappedFields[i]), null);
}
cascadeModel.setFields(fields);
cascadeModel.setMappedColumns(mappedColumns);
cascadeModel.setMappedFields(mappedFields);
// 子表的schema.table
String subSchemaTable = subTableMeta.getSchemaTable(null, null);
cascadeModel.setMappedTable(subSchemaTable);
cascadeModel.setProperty(field.getName());
// 子表外键查询条件
String subWhereSql = " where ";
// 级联删除,自动组装sql不允许外部修改,所以用?作为条件,顺序在对象加载时约定
String subDeleteSql = "delete from ".concat(subSchemaTable).concat(" where ");
for (int i = 0; i < fields.length; i++) {
if (i > 0) {
subWhereSql = subWhereSql.concat(" and ");
subDeleteSql = subDeleteSql.concat(" and ");
}
subWhereSql = subWhereSql.concat(mappedColumns[i]).concat("=:").concat(mappedFields[i]);
subDeleteSql = subDeleteSql.concat(mappedColumns[i]).concat("=?");
}
cascadeModel.setLoadSubTableSql(subTableMeta.getLoadAllSql().concat(subWhereSql));
cascadeModel.setDeleteSubTableSql(subDeleteSql);
boolean matchedWhere = false;
// 自定义load sql
if (StringUtil.isNotBlank(load)) {
String loadLow = load.toLowerCase();
// 是否是:xxx形式的引入主键条件(原则上不允许这么操作)
boolean isNamedSql = SqlConfigParseUtils.isNamedQuery(load);
if (isNamedSql && !StringUtil.matches(loadLow, "(\\>|\\<)|(\\=)|(\\<\\>)|(\\>\\=|\\<\\=)")) {
// 自定义加载完整sql
if (!loadLow.equals("default") && !loadLow.equals("true")) {
cascadeModel.setLoadSubTableSql(load);
}
} else {
String loadSql = SqlUtil.convertFieldsToColumns(subTableMeta, load);
matchedWhere = StringUtil.matches(loadLow, "\\s+where\\s+");
if (matchedWhere) {
cascadeModel.setLoadSubTableSql(loadSql);
} else {
cascadeModel.setLoadSubTableSql(subTableMeta.getLoadAllSql().concat(subWhereSql).concat(" and ").concat(loadSql));
cascadeModel.setLoadExtCondition(loadSql);
}
}
}
// update 2020-11-20 增加子表级联order by
if (StringUtil.isNotBlank(orderBy)) {
// 对属性名称进行替换,替换为实际表字段名称
orderBy = SqlUtil.convertFieldsToColumns(subTableMeta, orderBy);
cascadeModel.setOrderBy(orderBy);
cascadeModel.setLoadSubTableSql(cascadeModel.getLoadSubTableSql().concat(" order by ").concat(orderBy));
}
// 深度级联修改
if (StringUtil.isNotBlank(update)) {
String updateLow = update;
// 表示先删除子表
if (updateLow.equals("delete")) {
cascadeModel.setCascadeUpdateSql("delete from ".concat(subSchemaTable).concat(subWhereSql));
} else {
// 修改数据(如设置记录状态为失效)
matchedWhere = StringUtil.matches(updateLow, "\\s+where\\s+");
cascadeModel.setCascadeUpdateSql("update ".concat(subSchemaTable).concat(" set ").concat(update).concat(matchedWhere ? "" : subWhereSql));
}
}
// 是否完成了覆盖
boolean isRepeat = entityMeta.addCascade(cascadeModel);
if (isRepeat) {
logger.warn("表:{} 级联操作子表:{} 出现重复关联,后续:{}关联类型覆盖前面的关联", entityMeta.getTableName(), subTableMeta.getTableName(), (cascadeModel.getCascadeType() == 1) ? "oneToMany" : "oneToOne");
}
}
use of org.sagacity.sqltoy.config.model.TableCascadeModel in project sagacity-sqltoy by chenrenfei.
the class DialectUtils method save.
/**
* @todo 保存对象
* @param sqlToyContext
* @param entityMeta
* @param pkStrategy
* @param isAssignPK
* @param returnPkType
* @param insertSql
* @param entity
* @param generateSqlHandler
* @param generateSavePKStrategy
* @param conn
* @param dbType
* @return
* @throws Exception
*/
public static Object save(final SqlToyContext sqlToyContext, final EntityMeta entityMeta, final PKStrategy pkStrategy, final boolean isAssignPK, final ReturnPkType returnPkType, final String insertSql, Serializable entity, final GenerateSqlHandler generateSqlHandler, final GenerateSavePKStrategy generateSavePKStrategy, final Connection conn, final Integer dbType) throws Exception {
final boolean isIdentity = (pkStrategy != null && pkStrategy.equals(PKStrategy.IDENTITY));
final 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(null, sqlToyContext.getUnifyFieldsHandler());
handler = getSecureReflectHandler(handler, sqlToyContext.getFieldsSecureProvider(), sqlToyContext.getDesensitizeProvider(), entityMeta.getSecureFields());
Object[] fullParamValues = BeanUtil.reflectBeanToAry(entity, reflectColumns, null, handler);
boolean needUpdatePk = false;
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产生id并赋予其值
if (entityMeta.getIdStrategy() != null && null != entityMeta.getIdGenerator()) {
int bizIdLength = entityMeta.getBizIdLength();
int idLength = entityMeta.getIdLength();
Object[] relatedColValue = null;
String businessIdType = hasBizId ? entityMeta.getColumnJavaType(entityMeta.getBusinessIdField()) : "";
if (relatedColumn != null) {
relatedColValue = new Object[relatedColumnSize];
for (int meter = 0; meter < relatedColumnSize; meter++) {
relatedColValue[meter] = fullParamValues[relatedColumn[meter]];
if (StringUtil.isBlank(relatedColValue[meter])) {
throw new IllegalArgumentException("对象:" + entityMeta.getEntityClass().getName() + " 生成业务主键依赖的关联字段:" + relatedColumnNames[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]);
}
}
SqlExecuteStat.showSql("执行单记录插入", insertSql, null);
final Object[] paramValues = fullParamValues;
final Integer[] paramsType = entityMeta.getFieldsTypeArray();
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 || isSequence) {
if (returnPkType.equals(ReturnPkType.GENERATED_KEYS)) {
pst = conn.prepareStatement(insertSql, PreparedStatement.RETURN_GENERATED_KEYS);
} else if (returnPkType.equals(ReturnPkType.PREPARD_ID)) {
pst = conn.prepareStatement(insertSql, new String[] { entityMeta.getColumnName(entityMeta.getIdArray()[0]) });
} else {
pst = conn.prepareStatement(insertSql);
}
} else {
pst = conn.prepareStatement(insertSql);
}
SqlUtil.setParamsValue(sqlToyContext.getTypeHandler(), conn, dbType, pst, paramValues, paramsType, 0);
ResultSet keyResult = null;
if ((isIdentity || isSequence) && returnPkType.equals(ReturnPkType.RESULT_GET)) {
keyResult = pst.executeQuery();
} else {
pst.execute();
}
if (isIdentity || isSequence) {
if (!returnPkType.equals(ReturnPkType.RESULT_GET)) {
keyResult = pst.getGeneratedKeys();
}
if (keyResult != null) {
List result = new ArrayList();
while (keyResult.next()) {
result.add(keyResult.getObject(1));
}
if (result.size() == 1) {
this.setResult(result.get(0));
} else {
this.setResult(result.toArray());
}
}
}
}
});
// 无主键直接返回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;
String insertSubTableSql;
SavePKStrategy savePkStrategy;
for (TableCascadeModel cascadeModel : entityMeta.getCascadeModels()) {
final String[] mappedFields = cascadeModel.getMappedFields();
final Object[] mainValues = BeanUtil.reflectBeanToAry(entity, cascadeModel.getFields());
subTableEntityMeta = sqlToyContext.getEntityMeta(cascadeModel.getMappedType());
// oneToMany
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);
insertSubTableSql = generateSqlHandler.generateSql(subTableEntityMeta, null);
savePkStrategy = generateSavePKStrategy.generate(subTableEntityMeta);
saveAll(sqlToyContext, subTableEntityMeta, savePkStrategy.getPkStrategy(), savePkStrategy.isAssginValue(), insertSubTableSql, subTableData, sqlToyContext.getBatchSize(), new ReflectPropsHandler() {
public void process() {
for (int i = 0; i < mappedFields.length; i++) {
this.setValue(mappedFields[i], mainValues[i]);
}
}
}, conn, dbType, null);
} else {
logger.info("未执行save操作的级联子表{}批量保存,子表数据为空!", subTableEntityMeta.getTableName());
}
}
}
return result;
}
use of org.sagacity.sqltoy.config.model.TableCascadeModel in project sagacity-sqltoy by chenrenfei.
the class DialectUtils method load.
/**
* @todo 加载获取单笔数据库记录
* @param sqlToyContext
* @param sqlToyConfig
* @param sql
* @param entityMeta
* @param entity
* @param cascadeTypes
* @param conn
* @param dbType
* @return
* @throws Exception
*/
public static Serializable load(final SqlToyContext sqlToyContext, SqlToyConfig sqlToyConfig, String sql, EntityMeta entityMeta, Serializable entity, List<Class> cascadeTypes, Connection conn, final Integer dbType) throws Exception {
Object[] pkValues = BeanUtil.reflectBeanToAry(entity, entityMeta.getIdArray());
// 检查主键值是否合法
for (int i = 0; i < pkValues.length; i++) {
if (StringUtil.isBlank(pkValues[i])) {
throw new IllegalArgumentException(entityMeta.getSchemaTable(null, dbType) + " load method must assign value for pk,null pk field is:" + entityMeta.getIdArray()[i]);
}
}
SqlToyResult sqlToyResult = SqlConfigParseUtils.processSql(sql, entityMeta.getIdArray(), pkValues, null);
// 加密字段解密
DecryptHandler decryptHandler = null;
if (entityMeta.getSecureColumns() != null) {
decryptHandler = new DecryptHandler(sqlToyContext.getFieldsSecureProvider(), entityMeta.getSecureColumns());
}
QueryResult queryResult = findBySql(sqlToyContext, sqlToyConfig, sqlToyResult.getSql(), sqlToyResult.getParamsValue(), null, decryptHandler, conn, dbType, 0, -1, -1);
List rows = queryResult.getRows();
Serializable result = null;
Class entityClass;
if (rows != null && rows.size() > 0) {
entityClass = BeanUtil.getEntityClass(entity.getClass());
rows = BeanUtil.reflectListToBean(sqlToyContext.getTypeHandler(), rows, ResultUtils.humpFieldNames(queryResult.getLabelNames(), entityMeta.getColumnFieldMap()), entityClass);
result = (Serializable) rows.get(0);
// 处理类中的@Translate注解,进行缓存翻译
ResultUtils.wrapResultTranslate(sqlToyContext, result, entityClass);
}
if (result == null) {
return null;
}
// 存在主表对应子表
if (null != cascadeTypes && !cascadeTypes.isEmpty() && !entityMeta.getCascadeModels().isEmpty()) {
List pkRefDetails;
EntityMeta mappedMeta;
Object[] mainFieldValues;
String loadSubTableSql;
for (TableCascadeModel cascadeModel : entityMeta.getCascadeModels()) {
// 判定是否要加载
if (cascadeTypes.contains(cascadeModel.getMappedType())) {
mainFieldValues = BeanUtil.reflectBeanToAry(result, cascadeModel.getFields());
loadSubTableSql = ReservedWordsUtil.convertSql(cascadeModel.getLoadSubTableSql(), dbType);
sqlToyResult = SqlConfigParseUtils.processSql(loadSubTableSql, cascadeModel.getMappedFields(), mainFieldValues, null);
SqlExecuteStat.showSql("级联子表加载查询", sqlToyResult.getSql(), sqlToyResult.getParamsValue());
mappedMeta = sqlToyContext.getEntityMeta(cascadeModel.getMappedType());
// 子表加密字段解密
DecryptHandler subDecryptHandler = null;
if (mappedMeta.getSecureColumns() != null) {
subDecryptHandler = new DecryptHandler(sqlToyContext.getFieldsSecureProvider(), mappedMeta.getSecureColumns());
}
pkRefDetails = SqlUtil.findByJdbcQuery(sqlToyContext.getTypeHandler(), sqlToyResult.getSql(), sqlToyResult.getParamsValue(), cascadeModel.getMappedType(), null, subDecryptHandler, conn, dbType, false, mappedMeta.getColumnFieldMap(), SqlToyConstants.FETCH_SIZE, -1);
// 处理子类中@Translate注解,进行缓存翻译
ResultUtils.wrapResultTranslate(sqlToyContext, pkRefDetails, cascadeModel.getMappedType());
if (null != pkRefDetails && !pkRefDetails.isEmpty()) {
// oneToMany
if (cascadeModel.getCascadeType() == 1) {
BeanUtil.setProperty(result, cascadeModel.getProperty(), pkRefDetails);
} else {
BeanUtil.setProperty(result, cascadeModel.getProperty(), pkRefDetails.get(0));
}
}
}
}
}
return result;
}
use of org.sagacity.sqltoy.config.model.TableCascadeModel 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.config.model.TableCascadeModel in project sagacity-sqltoy by chenrenfei.
the class DialectUtils method delete.
/**
* @todo 删除单个对象以及其级联表数据
* @param sqlToyContext
* @param entity
* @param conn
* @param dbType
* @param tableName
* @return
* @throws Exception
*/
public static Long delete(SqlToyContext sqlToyContext, Serializable entity, Connection conn, final Integer dbType, final String tableName) throws Exception {
if (entity == null) {
return 0L;
}
EntityMeta entityMeta = sqlToyContext.getEntityMeta(entity.getClass());
String realTable = entityMeta.getSchemaTable(tableName, dbType);
if (null == entityMeta.getIdArray()) {
throw new IllegalArgumentException("delete 操作,表:" + realTable + " 没有主键,请检查表设计!");
}
Object[] idValues = BeanUtil.reflectBeanToAry(entity, entityMeta.getIdArray());
Integer[] parameterTypes = new Integer[idValues.length];
boolean validator = true;
// 判断主键值是否为空
for (int i = 0, n = idValues.length; i < n; i++) {
parameterTypes[i] = entityMeta.getColumnJdbcType(entityMeta.getIdArray()[i]);
if (StringUtil.isBlank(idValues[i])) {
validator = false;
break;
}
}
if (!validator) {
throw new IllegalArgumentException(realTable + " delete operate is illegal,table must has primary key and all primaryKey's value must has value!");
}
// 级联删除子表数据
if (!entityMeta.getCascadeModels().isEmpty()) {
int mapFieldSize;
for (TableCascadeModel cascadeModel : entityMeta.getCascadeModels()) {
EntityMeta subMeta;
// 如果数据库本身通过on delete cascade机制,则sqltoy无需进行删除操作
if (cascadeModel.isDelete()) {
subMeta = sqlToyContext.getEntityMeta(cascadeModel.getMappedType());
Object[] mainFieldValues = BeanUtil.reflectBeanToAry(entity, cascadeModel.getFields());
mapFieldSize = cascadeModel.getFields().length;
for (int i = 0; i < mapFieldSize; i++) {
if (mainFieldValues[i] == null) {
throw new IllegalArgumentException("表:" + realTable + " 级联删除子表:" + subMeta.getTableName() + " 对应属性:" + cascadeModel.getFields()[i] + " 值为null!");
}
}
Integer[] subTableFieldType = new Integer[mapFieldSize];
for (int i = 0, n = mapFieldSize; i < n; i++) {
subTableFieldType[i] = subMeta.getColumnJdbcType(cascadeModel.getMappedFields()[i]);
}
SqlExecuteStat.debug("执行级联删除操作", null);
SqlUtil.executeSql(sqlToyContext.getTypeHandler(), cascadeModel.getDeleteSubTableSql(), mainFieldValues, subTableFieldType, conn, dbType, null, true);
}
}
}
String deleteSql = "delete from ".concat(realTable).concat(" ").concat(entityMeta.getIdArgWhereSql());
return SqlUtil.executeSql(sqlToyContext.getTypeHandler(), deleteSql, idValues, parameterTypes, conn, dbType, null, true);
}
Aggregations