use of org.sagacity.sqltoy.config.model.EntityMeta in project sagacity-sqltoy by chenrenfei.
the class ImpalaDialect method save.
/*
* (non-Javadoc)
*
* @see org.sagacity.sqltoy.dialect.Dialect#save(org.sagacity.sqltoy.
* SqlToyContext , java.io.Serializable, java.util.List, java.sql.Connection)
*/
@Override
public Object save(SqlToyContext sqlToyContext, Serializable entity, Connection conn, final Integer dbType, final String dialect, final String tableName) throws Exception {
EntityMeta entityMeta = sqlToyContext.getEntityMeta(entity.getClass());
boolean isAssignPK = isAssignPKValue(entityMeta.getIdStrategy());
String insertSql = DialectExtUtils.generateInsertSql(dbType, entityMeta, entityMeta.getIdStrategy(), NVL_FUNCTION, "NEXTVAL FOR " + entityMeta.getSequence(), isAssignPK, tableName);
ReturnPkType returnPkType = (entityMeta.getIdStrategy() != null && entityMeta.getIdStrategy().equals(PKStrategy.SEQUENCE)) ? ReturnPkType.GENERATED_KEYS : ReturnPkType.PREPARD_ID;
return DialectUtils.save(sqlToyContext, entityMeta, entityMeta.getIdStrategy(), isAssignPK, returnPkType, insertSql, entity, null, null, conn, dbType);
}
use of org.sagacity.sqltoy.config.model.EntityMeta in project sagacity-sqltoy by chenrenfei.
the class ImpalaDialect method saveOrUpdateAll.
/*
* (non-Javadoc)
*
* @see org.sagacity.sqltoy.dialect.Dialect#saveOrUpdateAll(org.sagacity.sqltoy
* .SqlToyContext, java.util.List, java.sql.Connection)
*/
@Override
public Long saveOrUpdateAll(SqlToyContext sqlToyContext, List<?> entities, final int batchSize, ReflectPropsHandler reflectPropsHandler, final String[] forceUpdateFields, Connection conn, final Integer dbType, final String dialect, final Boolean autoCommit, final String tableName) throws Exception {
EntityMeta entityMeta = sqlToyContext.getEntityMeta(entities.get(0).getClass());
boolean isAssignPK = isAssignPKValue(entityMeta.getIdStrategy());
String insertSql = DialectExtUtils.generateInsertSql(dbType, entityMeta, entityMeta.getIdStrategy(), NVL_FUNCTION, "NEXTVAL FOR " + entityMeta.getSequence(), isAssignPK, tableName).replaceFirst("(?i)insert ", "upsert ");
return DialectUtils.saveAll(sqlToyContext, entityMeta, entityMeta.getIdStrategy(), isAssignPK, insertSql, entities, batchSize, reflectPropsHandler, conn, dbType, autoCommit);
}
use of org.sagacity.sqltoy.config.model.EntityMeta 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.EntityMeta in project sagacity-sqltoy by chenrenfei.
the class KingbaseDialect method saveAllIgnoreExist.
/*
* (non-Javadoc)
*
* @see org.sagacity.sqltoy.dialect.Dialect#saveAllNotExist(org.sagacity.sqltoy.
* SqlToyContext, java.util.List,
* org.sagacity.sqltoy.callback.ReflectPropsHandler, java.sql.Connection,
* java.lang.Boolean)
*/
@Override
public Long saveAllIgnoreExist(SqlToyContext sqlToyContext, List<?> entities, final int batchSize, ReflectPropsHandler reflectPropsHandler, Connection conn, final Integer dbType, final String dialect, final Boolean autoCommit, final String tableName) throws Exception {
EntityMeta entityMeta = sqlToyContext.getEntityMeta(entities.get(0).getClass());
boolean isAssignPK = KingbaseDialectUtils.isAssignPKValue(entityMeta.getIdStrategy());
String insertSql = DialectExtUtils.insertIgnore(dbType, entityMeta, entityMeta.getIdStrategy(), NVL_FUNCTION, "NEXTVAL FOR " + entityMeta.getSequence(), isAssignPK, tableName);
return DialectUtils.saveAll(sqlToyContext, entityMeta, entityMeta.getIdStrategy(), isAssignPK, insertSql, entities, batchSize, reflectPropsHandler, conn, dbType, autoCommit);
}
use of org.sagacity.sqltoy.config.model.EntityMeta in project sagacity-sqltoy by chenrenfei.
the class KingbaseDialect method saveAll.
/*
* (non-Javadoc)
*
* @see org.sagacity.sqltoy.dialect.Dialect#saveAll(org.sagacity.sqltoy.
* SqlToyContext , java.util.List,
* org.sagacity.sqltoy.callback.ReflectPropsHandler, java.sql.Connection)
*/
@Override
public Long saveAll(SqlToyContext sqlToyContext, List<?> entities, final int batchSize, ReflectPropsHandler reflectPropsHandler, Connection conn, final Integer dbType, final String dialect, final Boolean autoCommit, final String tableName) throws Exception {
EntityMeta entityMeta = sqlToyContext.getEntityMeta(entities.get(0).getClass());
boolean isAssignPK = KingbaseDialectUtils.isAssignPKValue(entityMeta.getIdStrategy());
String insertSql = DialectExtUtils.generateInsertSql(dbType, entityMeta, entityMeta.getIdStrategy(), NVL_FUNCTION, "NEXTVAL FOR " + entityMeta.getSequence(), isAssignPK, tableName);
return DialectUtils.saveAll(sqlToyContext, entityMeta, entityMeta.getIdStrategy(), isAssignPK, insertSql, entities, batchSize, reflectPropsHandler, conn, dbType, autoCommit);
}
Aggregations