use of org.sagacity.sqltoy.config.model.EntityMeta in project sagacity-sqltoy by chenrenfei.
the class DialectUtils method deleteAll.
/**
* @todo 批量删除对象并级联删除掉子表数据
* @param sqlToyContext
* @param entities
* @param batchSize
* @param conn
* @param dbType
* @param autoCommit
* @param tableName
* @return
* @throws Exception
*/
public static Long deleteAll(SqlToyContext sqlToyContext, List<?> entities, final int batchSize, Connection conn, final Integer dbType, final Boolean autoCommit, final String tableName) throws Exception {
if (null == entities || entities.isEmpty()) {
return 0L;
}
EntityMeta entityMeta = sqlToyContext.getEntityMeta(entities.get(0).getClass());
// 记录数量小于1000且无级联采用一次sql执行完成删除
// if (entities.size() < 1000 && entityMeta.getCascadeModels().isEmpty()) {
// }
String realTable = entityMeta.getSchemaTable(tableName, dbType);
if (null == entityMeta.getIdArray()) {
throw new IllegalArgumentException("delete/deleteAll 操作,表:" + realTable + " 没有主键,请检查表设计!");
}
List<Object[]> idValues = BeanUtil.reflectBeansToInnerAry(entities, entityMeta.getIdArray(), null, null);
// 判断主键值是否存在空
Object[] idsValue;
for (int i = 0, n = idValues.size(); i < n; i++) {
idsValue = idValues.get(i);
for (Object obj : idsValue) {
if (StringUtil.isBlank(obj)) {
throw new IllegalArgumentException("第[" + i + "]行数据主键值存在空,批量删除以主键为依据,表:" + realTable + " 主键不能为空!");
}
}
}
int idsLength = entityMeta.getIdArray().length;
Integer[] parameterTypes = new Integer[idsLength];
for (int i = 0, n = idsLength; i < n; i++) {
parameterTypes[i] = entityMeta.getColumnJdbcType(entityMeta.getIdArray()[i]);
}
// 级联批量删除子表数据
if (!entityMeta.getCascadeModels().isEmpty()) {
EntityMeta subTableMeta;
String delSubTableSql;
int mapFieldSize;
int meter = 0;
for (TableCascadeModel cascadeModel : entityMeta.getCascadeModels()) {
// 如果数据库本身通过on delete cascade机制,则sqltoy无需进行删除操作
if (cascadeModel.isDelete()) {
subTableMeta = sqlToyContext.getEntityMeta(cascadeModel.getMappedType());
List<Object[]> mainFieldValues = BeanUtil.reflectBeansToInnerAry(entities, cascadeModel.getFields(), null, null);
mapFieldSize = cascadeModel.getFields().length;
meter = 0;
for (Object[] row : mainFieldValues) {
for (int i = 0; i < mapFieldSize; i++) {
if (row[i] == null) {
throw new IllegalArgumentException("第:" + meter + "行,表:" + realTable + " 级联删除子表:" + subTableMeta.getTableName() + " 对应属性:" + cascadeModel.getFields()[i] + " 值为null!");
}
}
meter++;
}
Integer[] subTableFieldType = new Integer[mapFieldSize];
for (int i = 0, n = mapFieldSize; i < n; i++) {
subTableFieldType[i] = subTableMeta.getColumnJdbcType(cascadeModel.getMappedFields()[i]);
}
delSubTableSql = ReservedWordsUtil.convertSql(cascadeModel.getDeleteSubTableSql(), dbType);
SqlExecuteStat.showSql("级联删除子表记录", delSubTableSql, null);
SqlUtilsExt.batchUpdateByJdbc(sqlToyContext.getTypeHandler(), delSubTableSql, mainFieldValues, subTableFieldType, null, null, sqlToyContext.getBatchSize(), null, conn, dbType);
}
}
}
String deleteSql = ReservedWordsUtil.convertSql("delete from ".concat(realTable).concat(" ").concat(entityMeta.getIdArgWhereSql()), dbType);
SqlExecuteStat.showSql("批量删除[" + idValues.size() + "]条记录", deleteSql, null);
return SqlUtilsExt.batchUpdateByJdbc(sqlToyContext.getTypeHandler(), deleteSql, idValues, parameterTypes, null, null, batchSize, autoCommit, conn, dbType);
}
use of org.sagacity.sqltoy.config.model.EntityMeta in project sagacity-sqltoy by chenrenfei.
the class DialectUtils method isUnique.
/**
* @todo 进行唯一性查询判定
* @param sqlToyContext
* @param entity
* @param paramsNamed
* @param conn
* @param dbType
* @param tableName
* @param uniqueSqlHandler
* @return
*/
public static boolean isUnique(SqlToyContext sqlToyContext, Serializable entity, final String[] paramsNamed, Connection conn, final Integer dbType, final String tableName, final UniqueSqlHandler uniqueSqlHandler) {
try {
EntityMeta entityMeta = sqlToyContext.getEntityMeta(entity.getClass());
String[] realParamNamed;
Object[] paramValues;
int rejectIdFieldsSize = (entityMeta.getRejectIdFieldArray() == null) ? 0 : entityMeta.getRejectIdFieldArray().length;
// 如果没有特别指定属性,则通过数据是否为null来判断具体的字段
if (paramsNamed == null || paramsNamed.length == 0) {
String[] fieldsArray = entityMeta.getFieldsArray();
Object[] fieldValues = BeanUtil.reflectBeanToAry(entity, fieldsArray);
List paramValueList = new ArrayList();
List<String> paramNames = new ArrayList<String>();
boolean hasNoPkField = false;
for (int i = 0; i < fieldValues.length; i++) {
if (null != fieldValues[i]) {
// 非主键字段
if (i < rejectIdFieldsSize) {
hasNoPkField = true;
}
// 存在主键字段,则主键值仅仅作为返回结果的比较,判断是否是记录本身
if (i >= rejectIdFieldsSize && hasNoPkField) {
break;
}
paramNames.add(fieldsArray[i]);
paramValueList.add(fieldValues[i]);
}
}
paramValues = paramValueList.toArray();
realParamNamed = paramNames.toArray(new String[paramNames.size()]);
} else {
realParamNamed = paramsNamed;
paramValues = BeanUtil.reflectBeanToAry(entity, paramsNamed);
}
// 取出符合条件的2条记录
String queryStr = uniqueSqlHandler.process(entityMeta, realParamNamed, tableName, 2);
SqlExecuteStat.showSql("唯一性验证", queryStr, paramValues);
List result = SqlUtil.findByJdbcQuery(sqlToyContext.getTypeHandler(), queryStr, paramValues, null, null, null, conn, dbType, false, null, -1, -1);
if (result.size() == 0) {
return true;
}
if (result.size() > 1) {
return false;
}
// 表没有主键,单条记录算重复
if (null == entityMeta.getIdArray()) {
return false;
}
boolean allPK = false;
// 判断是否是主键字段的唯一性验证
if (realParamNamed.length == entityMeta.getIdArray().length) {
allPK = true;
for (String field : realParamNamed) {
if (!entityMeta.getFieldMeta(field).isPK()) {
allPK = false;
break;
}
}
}
// 针对主键字段的唯一性验证,查询有记录则表示主键已经存在
if (allPK) {
return false;
}
// 判断是否是本身
Object[] idValues = BeanUtil.reflectBeanToAry(entity, entityMeta.getIdArray());
List compareValues = (List) result.get(0);
// 相等表示唯一
boolean isEqual = true;
for (int i = 0, n = idValues.length; i < n; i++) {
// result 第一列数据为固定的1(select 1,pk1,pk2模式),因此compareValues(i+1);
if (null == idValues[i] || null == compareValues.get(i + 1) || !idValues[i].toString().equals(compareValues.get(i + 1).toString())) {
isEqual = false;
break;
}
}
return isEqual;
} catch (Exception e) {
logger.error("执行唯一性查询失败:{}", e.getMessage());
e.printStackTrace();
}
return false;
}
use of org.sagacity.sqltoy.config.model.EntityMeta in project sagacity-sqltoy by chenrenfei.
the class SqlServerDialectUtils method saveAll.
/**
* @todo 批量保存处理
* @param sqlToyContext
* @param entities
* @param reflectPropsHandler
* @param conn
* @param dbType
* @param autoCommit
* @param tableName
* @return
* @throws Exception
*/
public static Long saveAll(SqlToyContext sqlToyContext, List<?> entities, ReflectPropsHandler reflectPropsHandler, Connection conn, final Integer dbType, final Boolean autoCommit, final String tableName) throws Exception {
EntityMeta entityMeta = sqlToyContext.getEntityMeta(entities.get(0).getClass());
boolean isAssignPK = isAssignPKValue(entityMeta.getIdStrategy());
String insertSql = generateInsertSql(dbType, entityMeta, tableName, entityMeta.getIdStrategy(), "isnull", "@mySeqVariable", isAssignPK);
if (entityMeta.getIdStrategy() != null && entityMeta.getIdStrategy().equals(PKStrategy.SEQUENCE)) {
insertSql = "DECLARE @mySeqVariable as numeric(20)=NEXT VALUE FOR " + entityMeta.getSequence() + " " + insertSql;
}
// 返回记录修改量
return saveAll(sqlToyContext, entityMeta, entityMeta.getIdStrategy(), isAssignPK, insertSql, entities, reflectPropsHandler, conn, dbType, autoCommit);
}
use of org.sagacity.sqltoy.config.model.EntityMeta in project sagacity-sqltoy by chenrenfei.
the class SqlServerDialectUtils method update.
/**
* @todo 单个对象修改,包含级联修改
* @param sqlToyContext
* @param entity
* @param forceUpdateFields
* @param cascade
* @param emptyCascadeClasses
* @param subTableForceUpdateProps
* @param conn
* @param dbType
* @param tableName
* @return
* @throws Exception
*/
public static Long update(SqlToyContext sqlToyContext, Serializable entity, String[] forceUpdateFields, final boolean cascade, final Class[] emptyCascadeClasses, final HashMap<Class, String[]> subTableForceUpdateProps, Connection conn, final Integer dbType, final String tableName) throws Exception {
EntityMeta entityMeta = sqlToyContext.getEntityMeta(entity.getClass());
String realTable = entityMeta.getSchemaTable(tableName, dbType);
Long updateCount = DialectUtils.update(sqlToyContext, entity, entityMeta, "isnull", forceUpdateFields, conn, dbType, realTable);
// 级联修改
if (cascade && !entityMeta.getCascadeModels().isEmpty()) {
HashMap<Type, String> typeMap = new HashMap<Type, String>();
if (emptyCascadeClasses != null) {
for (Type type : emptyCascadeClasses) {
typeMap.put(type, "");
}
}
// 级联子表数据
List subTableData = null;
String[] forceUpdateProps = null;
EntityMeta subTableEntityMeta;
for (TableCascadeModel cascadeModel : entityMeta.getCascadeModels()) {
final Object[] mainFieldValues = BeanUtil.reflectBeanToAry(entity, cascadeModel.getFields());
subTableEntityMeta = sqlToyContext.getEntityMeta(cascadeModel.getMappedType());
forceUpdateProps = (subTableForceUpdateProps == null) ? null : subTableForceUpdateProps.get(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);
}
}
final String[] mappedFields = cascadeModel.getMappedFields();
// 针对存量子表数据,调用级联修改的语句,分delete 和update两种操作 1、删除存量数据;2、设置存量数据状态为停用
if (cascadeModel.getCascadeUpdateSql() != null && ((subTableData != null && !subTableData.isEmpty()) || typeMap.containsKey(cascadeModel.getMappedType()))) {
SqlExecuteStat.debug("执行子表级联更新前的存量数据更新", null);
SqlToyResult sqlToyResult = SqlConfigParseUtils.processSql(cascadeModel.getCascadeUpdateSql(), mappedFields, mainFieldValues, null);
SqlUtil.executeSql(sqlToyContext.getTypeHandler(), sqlToyResult.getSql(), sqlToyResult.getParamsValue(), null, conn, dbType, null, true);
}
// 子表数据不为空,采取saveOrUpdateAll操作
if (subTableData != null && !subTableData.isEmpty()) {
logger.info("执行update主表:{} 对应级联子表: {} 更新操作!", tableName, subTableEntityMeta.getTableName());
SqlExecuteStat.debug("执行子表级联更新操作", null);
saveOrUpdateAll(sqlToyContext, subTableData, sqlToyContext.getBatchSize(), // 设置关联外键字段的属性值(来自主表的主键)
new ReflectPropsHandler() {
public void process() {
for (int i = 0; i < mappedFields.length; i++) {
this.setValue(mappedFields[i], mainFieldValues[i]);
}
}
}, forceUpdateProps, conn, dbType, null, null);
} else {
logger.info("未执行update主表:{} 对应级联子表: {} 更新操作,子表数据为空!", tableName, subTableEntityMeta.getTableName());
}
}
}
return updateCount;
}
use of org.sagacity.sqltoy.config.model.EntityMeta in project sagacity-sqltoy by chenrenfei.
the class TidbDialect 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 {
// mysql只支持identity,sequence 值忽略
EntityMeta entityMeta = sqlToyContext.getEntityMeta(entities.get(0).getClass());
boolean isAssignPK = MySqlDialectUtils.isAssignPKValue(entityMeta.getIdStrategy());
String insertSql = DialectExtUtils.generateInsertSql(dbType, entityMeta, entityMeta.getIdStrategy(), NVL_FUNCTION, "NEXTVAL FOR " + entityMeta.getSequence(), isAssignPK, tableName).replaceFirst("(?i)insert ", "insert ignore ");
return DialectUtils.saveAll(sqlToyContext, entityMeta, entityMeta.getIdStrategy(), isAssignPK, insertSql, entities, batchSize, reflectPropsHandler, conn, dbType, autoCommit);
}
Aggregations