Search in sources :

Example 26 with EntityMeta

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);
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) TableCascadeModel(org.sagacity.sqltoy.config.model.TableCascadeModel)

Example 27 with EntityMeta

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;
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) ArrayList(java.util.ArrayList) List(java.util.List) ArrayList(java.util.ArrayList) SQLException(java.sql.SQLException) IOException(java.io.IOException)

Example 28 with EntityMeta

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);
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta)

Example 29 with EntityMeta

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;
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) TableCascadeModel(org.sagacity.sqltoy.config.model.TableCascadeModel) ReflectPropsHandler(org.sagacity.sqltoy.callback.ReflectPropsHandler) SqlToyResult(org.sagacity.sqltoy.config.model.SqlToyResult) DBType(org.sagacity.sqltoy.utils.DataSourceUtils.DBType) Type(java.lang.reflect.Type) ArrayList(java.util.ArrayList) List(java.util.List)

Example 30 with EntityMeta

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);
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta)

Aggregations

EntityMeta (org.sagacity.sqltoy.config.model.EntityMeta)141 SavePKStrategy (org.sagacity.sqltoy.dialect.model.SavePKStrategy)36 PKStrategy (org.sagacity.sqltoy.config.model.PKStrategy)28 GenerateSavePKStrategy (org.sagacity.sqltoy.callback.GenerateSavePKStrategy)24 ArrayList (java.util.ArrayList)23 Serializable (java.io.Serializable)22 SqlToyConfig (org.sagacity.sqltoy.config.model.SqlToyConfig)22 List (java.util.List)20 GenerateSqlHandler (org.sagacity.sqltoy.callback.GenerateSqlHandler)20 GenerateSqlHandler (org.sagacity.sqltoy.dialect.handler.GenerateSqlHandler)13 GenerateSavePKStrategy (org.sagacity.sqltoy.dialect.handler.GenerateSavePKStrategy)12 IOException (java.io.IOException)11 SQLException (java.sql.SQLException)11 HashMap (java.util.HashMap)11 TableCascadeModel (org.sagacity.sqltoy.config.model.TableCascadeModel)10 ReturnPkType (org.sagacity.sqltoy.dialect.model.ReturnPkType)10 OneToManyModel (org.sagacity.sqltoy.config.model.OneToManyModel)8 SqlToyResult (org.sagacity.sqltoy.config.model.SqlToyResult)8 Type (java.lang.reflect.Type)6 PreparedStatement (java.sql.PreparedStatement)6