Search in sources :

Example 1 with DataSourceCallbackHandler

use of org.sagacity.sqltoy.callback.DataSourceCallbackHandler in project sagacity-sqltoy by chenrenfei.

the class DialectFactory method saveAll.

/**
 * @todo 批量保存
 * @param sqlToyContext
 * @param entities
 * @param batchSize
 * @param reflectPropsHandler
 * @param dataSource
 * @param autoCommit
 */
public Long saveAll(final SqlToyContext sqlToyContext, final List<?> entities, final int batchSize, final ReflectPropsHandler reflectPropsHandler, final DataSource dataSource, final Boolean autoCommit) {
    if (entities == null || entities.isEmpty()) {
        logger.warn("saveAll entities is null or empty,please check!");
        return 0L;
    }
    try {
        SqlExecuteStat.start(BeanUtil.getEntityClass(entities.get(0).getClass()).getName(), "saveAll:[" + entities.size() + "]条记录!", null);
        // 分库分表并行执行
        List<Long> result = ParallelUtils.execute(sqlToyContext, entities, true, dataSource, (context, batchModel) -> {
            ShardingModel shardingModel = batchModel.getShardingModel();
            Long updateCnt = (Long) DataSourceUtils.processDataSource(context, shardingModel.getDataSource(), new DataSourceCallbackHandler() {

                @Override
                public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
                    this.setResult(getDialectSqlWrapper(dbType).saveAll(context, batchModel.getEntities(), batchSize, reflectPropsHandler, conn, dbType, dialect, autoCommit, shardingModel.getTableName()));
                }
            });
            List<Long> tmp = new ArrayList();
            tmp.add(updateCnt);
            return tmp;
        });
        long updateTotalCnt = 0;
        if (result != null) {
            for (Long cnt : result) {
                updateTotalCnt = updateTotalCnt + cnt.longValue();
            }
        }
        SqlExecuteStat.debug("执行结果", "批量保存记录量:{}条!", updateTotalCnt);
        return Long.valueOf(updateTotalCnt);
    } catch (Exception e) {
        SqlExecuteStat.error(e);
        throw new DataAccessException(e);
    } finally {
        SqlExecuteStat.destroy();
    }
}
Also used : Connection(java.sql.Connection) ArrayList(java.util.ArrayList) DataSourceCallbackHandler(org.sagacity.sqltoy.callback.DataSourceCallbackHandler) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) ShardingModel(org.sagacity.sqltoy.config.model.ShardingModel)

Example 2 with DataSourceCallbackHandler

use of org.sagacity.sqltoy.callback.DataSourceCallbackHandler in project sagacity-sqltoy by chenrenfei.

the class DialectFactory method findByQuery.

/**
 * @todo 查询符合条件的数据集合
 * @param sqlToyContext
 * @param queryExecutor
 * @param sqlToyConfig
 * @param lockMode
 * @param dataSource
 * @return
 */
public QueryResult findByQuery(final SqlToyContext sqlToyContext, final QueryExecutor queryExecutor, final SqlToyConfig sqlToyConfig, final LockMode lockMode, final DataSource dataSource) {
    final QueryExecutorExtend extend = queryExecutor.getInnerModel();
    // 合法校验
    if (StringUtil.isBlank(extend.sql)) {
        throw new IllegalArgumentException("findByQuery operate sql is null!");
    }
    try {
        Long startTime = System.currentTimeMillis();
        // 规整查询参数名称和参数名称对应的值
        QueryExecutorBuilder.initQueryExecutor(sqlToyContext, extend, sqlToyConfig, false);
        SqlExecuteStat.start(sqlToyConfig.getId(), "findByQuery", sqlToyConfig.isShowSql());
        QueryResult result = (QueryResult) DataSourceUtils.processDataSource(sqlToyContext, ShardingUtils.getShardingDataSource(sqlToyContext, sqlToyConfig, queryExecutor, dataSource), new DataSourceCallbackHandler() {

            @Override
            public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
                // 处理sql中的?为统一的:named形式,并进行sharding table替换
                SqlToyConfig realSqlToyConfig = DialectUtils.getUnifyParamsNamedConfig(sqlToyContext, sqlToyConfig, queryExecutor, dialect, false);
                // 通过参数处理最终的sql和参数值
                SqlToyResult queryParam = SqlConfigParseUtils.processSql(realSqlToyConfig.getSql(dialect), extend.getParamsName(realSqlToyConfig), extend.getParamsValue(sqlToyContext, realSqlToyConfig), dialect);
                QueryResult queryResult = getDialectSqlWrapper(dbType).findBySql(sqlToyContext, realSqlToyConfig, queryParam.getSql(), queryParam.getParamsValue(), extend.rowCallbackHandler, wrapDecryptHandler(sqlToyContext, extend.resultType), conn, lockMode, dbType, dialect, getFetchSize(extend.fetchSize), extend.maxRows);
                if (queryResult.getRows() != null && !queryResult.getRows().isEmpty()) {
                    // 存在计算和旋转的数据不能映射到对象(数据类型不一致,如汇总平均以及数据旋转)
                    List pivotCategorySet = ResultUtils.getPivotCategory(sqlToyContext, realSqlToyConfig, queryExecutor, conn, dbType, dialect);
                    // 对查询结果进行计算处理:字段脱敏、格式化、数据旋转、同步环比、分组汇总等
                    boolean changedCols = ResultUtils.calculate(sqlToyContext.getDesensitizeProvider(), realSqlToyConfig, queryResult, pivotCategorySet, extend);
                    // 将结果映射对象单独出来为了解耦,性能影响其实可以忽略,上万条也是1毫秒级
                    if (extend.resultType != null) {
                        queryResult.setRows(ResultUtils.wrapQueryResult(sqlToyContext, queryResult.getRows(), queryResult.getLabelNames(), (Class) extend.resultType, changedCols, extend.humpMapLabel, extend.hiberarchy, extend.hiberarchyClasses, extend.fieldsMap));
                    }
                }
                SqlExecuteStat.debug("查询结果", "共查询出记录数={}条!", queryResult.getRecordCount());
                this.setResult(queryResult);
            }
        });
        result.setExecuteTime(System.currentTimeMillis() - startTime);
        return result;
    } catch (Exception e) {
        SqlExecuteStat.error(e);
        throw new DataAccessException(e);
    } finally {
        SqlExecuteStat.destroy();
    }
}
Also used : SqlToyConfig(org.sagacity.sqltoy.config.model.SqlToyConfig) Connection(java.sql.Connection) DataSourceCallbackHandler(org.sagacity.sqltoy.callback.DataSourceCallbackHandler) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) SqlToyResult(org.sagacity.sqltoy.config.model.SqlToyResult) QueryResult(org.sagacity.sqltoy.model.QueryResult) List(java.util.List) ArrayList(java.util.ArrayList) QueryExecutorExtend(org.sagacity.sqltoy.model.inner.QueryExecutorExtend) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 3 with DataSourceCallbackHandler

use of org.sagacity.sqltoy.callback.DataSourceCallbackHandler in project sagacity-sqltoy by chenrenfei.

the class DialectFactory method saveAllIgnoreExist.

/**
 * @todo 批量保存数据,当已经存在的时候忽视掉
 * @param sqlToyContext
 * @param entities
 * @param batchSize
 * @param reflectPropsHandler
 * @param dataSource
 * @param autoCommit
 */
public Long saveAllIgnoreExist(final SqlToyContext sqlToyContext, final List<?> entities, final int batchSize, final ReflectPropsHandler reflectPropsHandler, final DataSource dataSource, final Boolean autoCommit) {
    if (entities == null || entities.isEmpty()) {
        logger.warn("saveAllIgnoreExist entities is null or empty,please check!");
        return 0L;
    }
    try {
        SqlExecuteStat.start(BeanUtil.getEntityClass(entities.get(0).getClass()).getName(), "saveAllNotExist:[" + entities.size() + "]条记录!", null);
        List<Long> result = ParallelUtils.execute(sqlToyContext, entities, true, dataSource, (context, batchModel) -> {
            ShardingModel shardingModel = batchModel.getShardingModel();
            Long updateCnt = (Long) DataSourceUtils.processDataSource(context, shardingModel.getDataSource(), new DataSourceCallbackHandler() {

                @Override
                public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
                    this.setResult(getDialectSqlWrapper(dbType).saveAllIgnoreExist(context, batchModel.getEntities(), batchSize, reflectPropsHandler, conn, dbType, dialect, autoCommit, shardingModel.getTableName()));
                }
            });
            List<Long> tmp = new ArrayList();
            tmp.add(updateCnt);
            return tmp;
        });
        long updateTotalCnt = 0;
        if (result != null) {
            for (Long cnt : result) {
                updateTotalCnt = updateTotalCnt + cnt.longValue();
            }
        }
        SqlExecuteStat.debug("执行结果", "实际影响记录数量:{} 条!", updateTotalCnt);
        return Long.valueOf(updateTotalCnt);
    } catch (Exception e) {
        SqlExecuteStat.error(e);
        throw new DataAccessException(e);
    } finally {
        SqlExecuteStat.destroy();
    }
}
Also used : Connection(java.sql.Connection) ArrayList(java.util.ArrayList) DataSourceCallbackHandler(org.sagacity.sqltoy.callback.DataSourceCallbackHandler) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) ShardingModel(org.sagacity.sqltoy.config.model.ShardingModel)

Example 4 with DataSourceCallbackHandler

use of org.sagacity.sqltoy.callback.DataSourceCallbackHandler in project sagacity-sqltoy by chenrenfei.

the class DialectFactory method updateFetch.

/**
 * @todo 查询锁定记录,并进行修改
 * @param sqlToyContext
 * @param queryExecutor
 * @param sqlToyConfig
 * @param updateRowHandler
 * @param dataSource
 * @return
 */
public QueryResult updateFetch(final SqlToyContext sqlToyContext, final QueryExecutor queryExecutor, final SqlToyConfig sqlToyConfig, final UpdateRowHandler updateRowHandler, final DataSource dataSource) {
    final QueryExecutorExtend extend = queryExecutor.getInnerModel();
    try {
        Long startTime = System.currentTimeMillis();
        SqlExecuteStat.start(sqlToyConfig.getId(), "updateFetch", sqlToyConfig.isShowSql());
        // 组织参数和参数校验,但忽视数据权限数据的传参和校验
        QueryExecutorBuilder.initQueryExecutor(sqlToyContext, extend, sqlToyConfig, false);
        QueryResult result = (QueryResult) DataSourceUtils.processDataSource(sqlToyContext, ShardingUtils.getShardingDataSource(sqlToyContext, sqlToyConfig, queryExecutor, dataSource), new DataSourceCallbackHandler() {

            @Override
            public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
                // 处理sql中的?为统一的:named形式
                SqlToyConfig realSqlToyConfig = DialectUtils.getUnifyParamsNamedConfig(sqlToyContext, sqlToyConfig, queryExecutor, dialect, false);
                SqlToyResult queryParam = SqlConfigParseUtils.processSql(realSqlToyConfig.getSql(dialect), extend.getParamsName(realSqlToyConfig), extend.getParamsValue(sqlToyContext, realSqlToyConfig), dialect);
                QueryResult queryResult = getDialectSqlWrapper(dbType).updateFetch(sqlToyContext, realSqlToyConfig, queryParam.getSql(), queryParam.getParamsValue(), updateRowHandler, conn, dbType, dialect, (extend.lockMode == null) ? LockMode.UPGRADE : extend.lockMode, getFetchSize(extend.fetchSize), extend.maxRows);
                if (extend.resultType != null) {
                    queryResult.setRows(ResultUtils.wrapQueryResult(sqlToyContext, queryResult.getRows(), queryResult.getLabelNames(), (Class) extend.resultType, false, extend.humpMapLabel, extend.hiberarchy, extend.hiberarchyClasses, extend.fieldsMap));
                }
                SqlExecuteStat.debug("执行结果", "修改并返回记录操作影响记录:{} 条!", queryResult.getRecordCount());
                this.setResult(queryResult);
            }
        });
        result.setExecuteTime(System.currentTimeMillis() - startTime);
        return result;
    } catch (Exception e) {
        SqlExecuteStat.error(e);
        throw new DataAccessException(e);
    } finally {
        SqlExecuteStat.destroy();
    }
}
Also used : QueryResult(org.sagacity.sqltoy.model.QueryResult) SqlToyConfig(org.sagacity.sqltoy.config.model.SqlToyConfig) Connection(java.sql.Connection) QueryExecutorExtend(org.sagacity.sqltoy.model.inner.QueryExecutorExtend) DataSourceCallbackHandler(org.sagacity.sqltoy.callback.DataSourceCallbackHandler) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) SqlToyResult(org.sagacity.sqltoy.config.model.SqlToyResult)

Example 5 with DataSourceCallbackHandler

use of org.sagacity.sqltoy.callback.DataSourceCallbackHandler in project sagacity-sqltoy by chenrenfei.

the class DialectFactory method wrapTreeTableRoute.

/**
 * @todo 构造树形表的节点路径、节点层级、节点类别(是否叶子节点)
 * @param sqlToyContext
 * @param treeModel
 * @param dataSource
 * @return
 */
public boolean wrapTreeTableRoute(final SqlToyContext sqlToyContext, final TreeTableModel treeModel, final DataSource dataSource) {
    if (treeModel == null || StringUtil.isBlank(treeModel.getPidField())) {
        throw new IllegalArgumentException("请检查pidField赋值是否正确!");
    }
    if (StringUtil.isBlank(treeModel.getLeafField()) || StringUtil.isBlank(treeModel.getNodeRouteField()) || StringUtil.isBlank(treeModel.getNodeLevelField())) {
        throw new IllegalArgumentException("请检查isLeafField\nodeRouteField\nodeLevelField 赋值是否正确!");
    }
    try {
        if (null != treeModel.getEntity()) {
            EntityMeta entityMeta = null;
            if (treeModel.getEntity() instanceof Type) {
                entityMeta = sqlToyContext.getEntityMeta((Class) treeModel.getEntity());
            } else {
                entityMeta = sqlToyContext.getEntityMeta(treeModel.getEntity().getClass());
            }
            // 兼容填写fieldName,统一转化为columnName
            // pid
            String columnName = entityMeta.getColumnName(treeModel.getPidField());
            if (columnName != null) {
                treeModel.pidField(columnName);
            }
            // leafField
            columnName = entityMeta.getColumnName(treeModel.getLeafField());
            if (columnName != null) {
                treeModel.isLeafField(columnName);
            }
            // nodeLevel
            columnName = entityMeta.getColumnName(treeModel.getNodeLevelField());
            if (columnName != null) {
                treeModel.nodeLevelField(columnName);
            }
            // nodeRoute
            columnName = entityMeta.getColumnName(treeModel.getNodeRouteField());
            if (columnName != null) {
                treeModel.nodeRouteField(columnName);
            }
            HashMap<String, String> columnMap = new HashMap<String, String>();
            for (FieldMeta column : entityMeta.getFieldsMeta().values()) {
                columnMap.put(column.getColumnName().toUpperCase(), "");
            }
            if (!columnMap.containsKey(treeModel.getNodeRouteField().toUpperCase())) {
                throw new IllegalArgumentException("树形表:节点路径字段名称:" + treeModel.getNodeRouteField() + "不正确,请检查!");
            }
            if (!columnMap.containsKey(treeModel.getLeafField().toUpperCase())) {
                throw new IllegalArgumentException("树形表:是否叶子节点字段名称:" + treeModel.getLeafField() + "不正确,请检查!");
            }
            if (!columnMap.containsKey(treeModel.getNodeLevelField().toUpperCase())) {
                throw new IllegalArgumentException("树形表:节点等级字段名称:" + treeModel.getNodeLevelField() + "不正确,请检查!");
            }
            FieldMeta idMeta = (FieldMeta) entityMeta.getFieldMeta(entityMeta.getIdArray()[0]);
            // 如未定义则使用主键(update 2020-10-16)
            if (StringUtil.isBlank(treeModel.getIdField())) {
                treeModel.idField(idMeta.getColumnName());
            } else {
                // 别名转换
                columnName = entityMeta.getColumnName(treeModel.getIdField());
                if (columnName != null) {
                    treeModel.idField(columnName);
                }
            }
            if (StringUtil.isBlank(treeModel.getTableName())) {
                treeModel.table(entityMeta.getSchemaTable(null, null));
            }
            // 通过实体对象取值给rootId和idValue赋值
            if (!(treeModel.getEntity() instanceof Type)) {
                // update 2020-10-19 从手工设定的字段中取值(原本从主键中取值)
                if (null == treeModel.getRootId()) {
                    Object pidValue = BeanUtil.getProperty(treeModel.getEntity(), StringUtil.toHumpStr(treeModel.getPidField(), false));
                    treeModel.rootId(pidValue);
                }
                if (null == treeModel.getIdValue()) {
                    Object idValue = BeanUtil.getProperty(treeModel.getEntity(), StringUtil.toHumpStr(treeModel.getIdField(), false));
                    treeModel.setIdValue(idValue);
                }
            }
            // 类型,默认值为false
            if (idMeta.getType() == java.sql.Types.INTEGER || idMeta.getType() == java.sql.Types.DECIMAL || idMeta.getType() == java.sql.Types.DOUBLE || idMeta.getType() == java.sql.Types.FLOAT || idMeta.getType() == java.sql.Types.NUMERIC) {
                treeModel.idTypeIsChar(false);
            // update 2016-12-05 节点路径默认采取主键值直接拼接,更加直观科学
            // treeModel.setAppendZero(true);
            } else if (idMeta.getType() == java.sql.Types.VARCHAR || idMeta.getType() == java.sql.Types.CHAR) {
                treeModel.idTypeIsChar(true);
            }
        }
        SqlExecuteStat.start(treeModel.getTableName(), "wrapTreeTableRoute", true);
        return (Boolean) DataSourceUtils.processDataSource(sqlToyContext, dataSource, new DataSourceCallbackHandler() {

            @Override
            public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception {
                this.setResult(SqlUtil.wrapTreeTableRoute(sqlToyContext.getTypeHandler(), treeModel, conn, dbType));
            }
        });
    } catch (Exception e) {
        logger.error("封装树形表节点路径操作:wrapTreeTableRoute发生错误,{}", e.getMessage());
        e.printStackTrace();
        throw new DataAccessException(e);
    } finally {
        SqlExecuteStat.destroy();
    }
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) HashMap(java.util.HashMap) FieldMeta(org.sagacity.sqltoy.config.model.FieldMeta) Connection(java.sql.Connection) DataSourceCallbackHandler(org.sagacity.sqltoy.callback.DataSourceCallbackHandler) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) Type(java.lang.reflect.Type) DBType(org.sagacity.sqltoy.utils.DataSourceUtils.DBType) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Aggregations

Connection (java.sql.Connection)40 DataSourceCallbackHandler (org.sagacity.sqltoy.callback.DataSourceCallbackHandler)40 DataAccessException (org.sagacity.sqltoy.exception.DataAccessException)24 ArrayList (java.util.ArrayList)23 SqlToyConfig (org.sagacity.sqltoy.config.model.SqlToyConfig)20 List (java.util.List)19 BaseException (org.sagacity.sqltoy.exception.BaseException)15 QueryResult (org.sagacity.sqltoy.model.QueryResult)14 ShardingModel (org.sagacity.sqltoy.config.model.ShardingModel)13 SqlToyResult (org.sagacity.sqltoy.config.model.SqlToyResult)12 QueryExecutorExtend (org.sagacity.sqltoy.model.inner.QueryExecutorExtend)9 SqlToyContext (org.sagacity.sqltoy.SqlToyContext)6 ParallelCallbackHandler (org.sagacity.sqltoy.callback.ParallelCallbackHandler)5 ShardingGroupModel (org.sagacity.sqltoy.model.ShardingGroupModel)5 ShardingModel (org.sagacity.sqltoy.model.ShardingModel)5 Serializable (java.io.Serializable)3 SqlParamsModel (org.sagacity.sqltoy.config.model.SqlParamsModel)3 Type (java.lang.reflect.Type)2 HashMap (java.util.HashMap)2 DataSource (javax.sql.DataSource)2