Search in sources :

Example 6 with DataAccessException

use of org.sagacity.sqltoy.exception.DataAccessException in project sagacity-sqltoy by chenrenfei.

the class DefaultDialectUtils method updateSaveFetch.

/**
 * @TODO 实现:1、锁查询;2、记录存在则修改;3、记录不存在则执行insert;4、返回修改或插入的记录信息,尽量不要使用identity、sequence主键
 * @param sqlToyContext
 * @param entity
 * @param updateRowHandler
 * @param uniqueProps
 * @param conn
 * @param dbType
 * @param dialect
 * @param tableName
 * @return
 * @throws Exception
 */
public static Serializable updateSaveFetch(final SqlToyContext sqlToyContext, final Serializable entity, final UpdateRowHandler updateRowHandler, String[] uniqueProps, final Connection conn, final Integer dbType, String dialect, String tableName) throws Exception {
    final EntityMeta entityMeta = sqlToyContext.getEntityMeta(entity.getClass());
    // 条件字段
    String[] whereFields = uniqueProps;
    if (whereFields == null || whereFields.length == 0) {
        whereFields = entityMeta.getIdArray();
    }
    if (whereFields == null || whereFields.length == 0) {
        throw new DataAccessException("updateSaveFetch操作的表:" + tableName + " 没有唯一获得一条记录的条件字段,请检查!");
    }
    // 全部字段的值
    Object[] tempFieldValues = null;
    // 条件字段值
    Object[] whereParamValues = BeanUtil.reflectBeanToAry(entity, whereFields);
    for (int i = 0; i < whereParamValues.length; i++) {
        // 唯一性属性值存在空,则表示首次插入
        if (StringUtil.isBlank(whereParamValues[i])) {
            tempFieldValues = processFieldValues(sqlToyContext, entityMeta, entity);
            whereParamValues = BeanUtil.reflectBeanToAry(entity, whereFields);
            break;
        }
    }
    final Object[] fieldValues = tempFieldValues;
    final boolean hasUpdateRow = (updateRowHandler == null) ? false : true;
    // 组织select * from table for update 语句
    String sql = wrapFetchSql(entityMeta, dbType, whereFields, tableName);
    SqlExecuteStat.showSql("执行锁记录查询", sql, whereParamValues);
    // 可编辑结果集
    PreparedStatement pst = conn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
    List updateResult = (List) SqlUtil.preparedStatementProcess(whereParamValues, pst, null, new PreparedStatementResultHandler() {

        @Override
        public void execute(Object rowData, PreparedStatement pst, ResultSet rs) throws Exception {
            SqlUtil.setParamsValue(sqlToyContext.getTypeHandler(), conn, dbType, pst, (Object[]) rowData, null, 0);
            // 执行类似 select xxx from table for update(sqlserver语法有差异)
            rs = pst.executeQuery();
            int rowCnt = rs.getMetaData().getColumnCount();
            int index = 0;
            List result = new ArrayList();
            while (rs.next()) {
                if (index > 0) {
                    throw new DataAccessException("updateSaveFetch操作只能针对单条记录进行操作,请检查uniqueProps参数设置!");
                }
                // 存在修改记录
                if (hasUpdateRow) {
                    SqlExecuteStat.debug("执行updateRow", "记录存在调用updateRowHandler.updateRow!");
                    // 执行update反调,实现锁定行记录值的修改
                    updateRowHandler.updateRow(rs, index);
                    // 执行update
                    rs.updateRow();
                }
                index++;
                // 重新获得修改后的值
                result.add(ResultUtils.processResultRow(rs, 0, rowCnt, false));
            }
            // 没有查询到记录,表示是需要首次插入
            if (index == 0) {
                SqlExecuteStat.debug("执行insertRow", "查询未匹配到结果则进行首次插入!");
                // 移到插入行
                rs.moveToInsertRow();
                FieldMeta fieldMeta;
                Object[] fullFieldvalues = (fieldValues == null) ? processFieldValues(sqlToyContext, entityMeta, entity) : fieldValues;
                Object fieldValue;
                for (int i = 0; i < entityMeta.getFieldsArray().length; i++) {
                    fieldMeta = entityMeta.getFieldMeta(entityMeta.getFieldsArray()[i]);
                    if (fieldMeta.isPK()) {
                        fieldValue = fullFieldvalues[i];
                    } else {
                        fieldValue = SqlUtilsExt.getDefaultValue(fullFieldvalues[i], fieldMeta.getDefaultValue(), fieldMeta.getType(), fieldMeta.isNullable());
                    }
                    // 插入设置具体列的值
                    if (fieldValue != null) {
                        rs.updateObject(fieldMeta.getColumnName(), fieldValue);
                    }
                }
                // 执行插入
                rs.insertRow();
            }
            this.setResult(result);
        }
    });
    // 记录不存在首次保存,返回entity自身
    if (updateResult == null || updateResult.isEmpty()) {
        return entity;
    } else {
        List entities = BeanUtil.reflectListToBean(sqlToyContext.getTypeHandler(), updateResult, entityMeta.getFieldsArray(), entity.getClass());
        return (Serializable) entities.get(0);
    }
}
Also used : EntityMeta(org.sagacity.sqltoy.config.model.EntityMeta) Serializable(java.io.Serializable) PreparedStatementResultHandler(org.sagacity.sqltoy.callback.PreparedStatementResultHandler) FieldMeta(org.sagacity.sqltoy.config.model.FieldMeta) ArrayList(java.util.ArrayList) PreparedStatement(java.sql.PreparedStatement) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) List(java.util.List) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 7 with DataAccessException

use of org.sagacity.sqltoy.exception.DataAccessException in project sagacity-sqltoy by chenrenfei.

the class Mongo method find.

/**
 * @todo 集合记录查询
 * @return
 */
public List<?> find() {
    QueryExecutor queryExecutor = build();
    SqlToyConfig sqlToyConfig = sqlToyContext.getSqlToyConfig(sql, SqlType.search, "");
    NoSqlConfigModel noSqlModel = sqlToyConfig.getNoSqlConfigModel();
    if (noSqlModel == null || noSqlModel.getCollection() == null || noSqlModel.getFields() == null) {
        throw new IllegalArgumentException(ERROR_MESSAGE);
    }
    try {
        QueryExecutorExtend extend = queryExecutor.getInnerModel();
        // 最后的执行语句
        String realMql = MongoElasticUtils.wrapMql(sqlToyConfig, extend.getParamsName(sqlToyConfig), extend.getParamsValue(sqlToyContext, sqlToyConfig));
        // 聚合查询
        if (noSqlModel.isHasAggs()) {
            return aggregate(getMongoTemplate(), sqlToyConfig, realMql, (Class) extend.resultType, extend.humpMapLabel);
        }
        return findTop(getMongoTemplate(), sqlToyConfig, null, realMql, (Class) extend.resultType, extend.humpMapLabel);
    } catch (Exception e) {
        e.printStackTrace();
        throw new DataAccessException(e);
    }
}
Also used : NoSqlConfigModel(org.sagacity.sqltoy.config.model.NoSqlConfigModel) QueryExecutor(org.sagacity.sqltoy.model.QueryExecutor) SqlToyConfig(org.sagacity.sqltoy.config.model.SqlToyConfig) QueryExecutorExtend(org.sagacity.sqltoy.model.inner.QueryExecutorExtend) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 8 with DataAccessException

use of org.sagacity.sqltoy.exception.DataAccessException in project sagacity-sqltoy by chenrenfei.

the class SqlToyDaoSupport method parallQuery.

/**
 * @TODO 并行查询并返回一维List,有几个查询List中就包含几个结果对象,paramNames和paramValues是全部sql的条件参数的合集
 * @param parallQueryList
 * @param paramNames
 * @param paramValues
 * @param parallelConfig
 * @return
 */
protected <T> List<QueryResult<T>> parallQuery(List<ParallQuery> parallQueryList, String[] paramNames, Object[] paramValues, ParallelConfig parallelConfig) {
    if (parallQueryList == null || parallQueryList.isEmpty()) {
        return null;
    }
    ParallelConfig parallConfig = parallelConfig;
    if (parallConfig == null) {
        parallConfig = new ParallelConfig();
    }
    // 并行线程数量(默认最大十个)
    if (parallConfig.getMaxThreads() == null) {
        parallConfig.maxThreads(10);
    }
    int thread = parallConfig.getMaxThreads();
    if (parallQueryList.size() < thread) {
        thread = parallQueryList.size();
    }
    List<QueryResult<T>> results = new ArrayList<QueryResult<T>>();
    ExecutorService pool = null;
    try {
        pool = Executors.newFixedThreadPool(thread);
        List<Future<ParallQueryResult>> futureResult = new ArrayList<Future<ParallQueryResult>>();
        SqlToyConfig sqlToyConfig;
        Future<ParallQueryResult> future;
        for (ParallQuery query : parallQueryList) {
            sqlToyConfig = sqlToyContext.getSqlToyConfig(new QueryExecutor(query.getExtend().sql).resultType(query.getExtend().resultType), SqlType.search, getDialect(query.getExtend().dataSource));
            // 自定义条件参数
            if (query.getExtend().selfCondition) {
                future = pool.submit(new ParallQueryExecutor(sqlToyContext, dialectFactory, sqlToyConfig, query, query.getExtend().names, query.getExtend().values, getDataSource(query.getExtend().dataSource, sqlToyConfig)));
            } else {
                future = pool.submit(new ParallQueryExecutor(sqlToyContext, dialectFactory, sqlToyConfig, query, paramNames, paramValues, getDataSource(query.getExtend().dataSource, sqlToyConfig)));
            }
            futureResult.add(future);
        }
        pool.shutdown();
        // 设置最大等待时长
        if (parallConfig.getMaxWaitSeconds() != null) {
            pool.awaitTermination(parallConfig.getMaxWaitSeconds(), TimeUnit.SECONDS);
        } else {
            pool.awaitTermination(SqlToyConstants.PARALLEL_MAXWAIT_SECONDS, TimeUnit.SECONDS);
        }
        ParallQueryResult item;
        int index = 0;
        for (Future<ParallQueryResult> result : futureResult) {
            index++;
            item = result.get();
            // 存在执行异常则整体抛出
            if (item != null && !item.isSuccess()) {
                throw new DataAccessException("第:{} 个sql执行异常:{}!", index, item.getMessage());
            }
            results.add(item.getResult());
        }
    } catch (Exception e) {
        e.printStackTrace();
        throw new DataAccessException("并行查询执行错误:" + e.getMessage(), e);
    } finally {
        if (pool != null) {
            pool.shutdownNow();
        }
    }
    return results;
}
Also used : ParallQueryExecutor(org.sagacity.sqltoy.dialect.executor.ParallQueryExecutor) SqlToyConfig(org.sagacity.sqltoy.config.model.SqlToyConfig) ParallelConfig(org.sagacity.sqltoy.model.ParallelConfig) ParallQuery(org.sagacity.sqltoy.model.ParallQuery) ArrayList(java.util.ArrayList) ParallQueryResult(org.sagacity.sqltoy.model.ParallQueryResult) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) QueryResult(org.sagacity.sqltoy.model.QueryResult) ParallQueryResult(org.sagacity.sqltoy.model.ParallQueryResult) ParallQueryExecutor(org.sagacity.sqltoy.dialect.executor.ParallQueryExecutor) QueryExecutor(org.sagacity.sqltoy.model.QueryExecutor) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 9 with DataAccessException

use of org.sagacity.sqltoy.exception.DataAccessException in project sagacity-sqltoy by chenrenfei.

the class HttpClientUtils method doPost.

/**
 * @todo 执行post请求
 * @param sqltoyContext
 * @param nosqlConfig
 * @param esConfig
 * @param postValue
 * @return
 * @throws Exception
 */
public static JSONObject doPost(SqlToyContext sqltoyContext, NoSqlConfigModel nosqlConfig, ElasticEndpoint esConfig, Object postValue) throws Exception {
    if (esConfig.getUrl() == null) {
        throw new IllegalArgumentException("请正确配置sqltoyContext elasticConfigs 指定es的服务地址!");
    }
    String charset = (nosqlConfig.getCharset() == null) ? CHARSET : nosqlConfig.getCharset();
    HttpEntity httpEntity = null;
    // sql 模式
    if (nosqlConfig.isSqlMode()) {
        // 6.3.x 版本支持xpack sql查询
        if (esConfig.isNativeSql()) {
            Map<String, String> map = new HashMap<String, String>();
            map.put("query", postValue.toString());
            httpEntity = new StringEntity(JSON.toJSONString(map), charset);
        } else {
            httpEntity = new StringEntity(postValue.toString(), charset);
        }
    } else {
        httpEntity = new StringEntity(JSON.toJSONString(postValue), charset);
    }
    ((StringEntity) httpEntity).setContentEncoding(charset);
    ((StringEntity) httpEntity).setContentType(CONTENT_TYPE);
    String realUrl;
    // 返回结果
    HttpEntity reponseEntity = null;
    // 使用elastic rest client(默认)
    if (esConfig.getRestClient() != null) {
        realUrl = wrapUrl(esConfig, nosqlConfig);
        if (sqltoyContext.isDebug()) {
            logger.debug("esRestClient执行:URL=[{}],Path={},执行的JSON=[{}]", esConfig.getUrl(), realUrl, JSON.toJSONString(postValue));
        }
        // 默认采用post请求
        RestClient restClient = null;
        try {
            restClient = esConfig.getRestClient();
            Request request = new Request(POST, realUrl);
            request.setEntity(httpEntity);
            Response response = restClient.performRequest(request);
            reponseEntity = response.getEntity();
        } catch (Exception e) {
            throw e;
        } finally {
            if (restClient != null) {
                restClient.close();
            }
        }
    } else // 组织httpclient模式调用(此种模式不推荐使用)
    {
        realUrl = wrapUrl(esConfig, nosqlConfig);
        HttpPost httpPost = new HttpPost(realUrl);
        if (sqltoyContext.isDebug()) {
            logger.debug("httpClient执行URL=[{}],执行的JSON=[{}]", realUrl, JSON.toJSONString(postValue));
        }
        httpPost.setEntity(httpEntity);
        // 设置connection是否自动关闭
        httpPost.setHeader("Connection", "close");
        // 自定义超时
        if (nosqlConfig.getRequestTimeout() != 30000 || nosqlConfig.getConnectTimeout() != 10000 || nosqlConfig.getSocketTimeout() != 180000) {
            httpPost.setConfig(RequestConfig.custom().setConnectionRequestTimeout(nosqlConfig.getRequestTimeout()).setConnectTimeout(nosqlConfig.getConnectTimeout()).setSocketTimeout(nosqlConfig.getSocketTimeout()).build());
        } else {
            httpPost.setConfig(requestConfig);
        }
        CloseableHttpClient client = null;
        try {
            if (StringUtil.isNotBlank(esConfig.getUsername()) && StringUtil.isNotBlank(esConfig.getPassword())) {
                // 凭据提供器
                CredentialsProvider credsProvider = new BasicCredentialsProvider();
                credsProvider.setCredentials(AuthScope.ANY, // 认证用户名和密码
                new UsernamePasswordCredentials(esConfig.getUsername(), esConfig.getPassword()));
                client = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
            } else {
                client = HttpClients.createDefault();
            }
            HttpResponse response = client.execute(httpPost);
            reponseEntity = response.getEntity();
        } catch (Exception e) {
            throw e;
        }
    }
    String result = null;
    if (reponseEntity != null) {
        result = EntityUtils.toString(reponseEntity, nosqlConfig.getCharset());
        if (sqltoyContext.isDebug()) {
            logger.debug("result={}", result);
        }
    }
    if (StringUtil.isBlank(result)) {
        return null;
    }
    // 将结果转换为JSON对象
    JSONObject json = JSON.parseObject(result);
    // 存在错误
    if (json.containsKey("error")) {
        String errorMessage = JSON.toJSONString(json.getJSONObject("error").getJSONArray("root_cause").get(0));
        logger.error("elastic查询失败,endpoint:[{}],错误信息:[{}]", nosqlConfig.getEndpoint(), errorMessage);
        throw new DataAccessException("ElasticSearch查询失败,错误信息:" + errorMessage);
    }
    return json;
}
Also used : HttpPost(org.apache.http.client.methods.HttpPost) CloseableHttpClient(org.apache.http.impl.client.CloseableHttpClient) BasicCredentialsProvider(org.apache.http.impl.client.BasicCredentialsProvider) HttpEntity(org.apache.http.HttpEntity) HashMap(java.util.HashMap) RestClient(org.elasticsearch.client.RestClient) Request(org.elasticsearch.client.Request) HttpResponse(org.apache.http.HttpResponse) BasicCredentialsProvider(org.apache.http.impl.client.BasicCredentialsProvider) CredentialsProvider(org.apache.http.client.CredentialsProvider) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException) UsernamePasswordCredentials(org.apache.http.auth.UsernamePasswordCredentials) Response(org.elasticsearch.client.Response) HttpResponse(org.apache.http.HttpResponse) StringEntity(org.apache.http.entity.StringEntity) JSONObject(com.alibaba.fastjson.JSONObject) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Example 10 with DataAccessException

use of org.sagacity.sqltoy.exception.DataAccessException in project sagacity-sqltoy by chenrenfei.

the class DataSetResult method getFirstColumn.

/**
 * @TODO 提供查询单列场景下直接返回一维集合
 * @param distinct 是否去重
 * @return
 */
public List getFirstColumn(boolean distinct) {
    List result = new ArrayList();
    if (this.rows == null || this.rows.isEmpty()) {
        return result;
    }
    Object rowTmp = this.rows.get(0);
    Object cell;
    if (rowTmp instanceof List) {
        for (Object row : this.rows) {
            cell = ((List) row).get(0);
            if (distinct) {
                if (!result.contains(cell)) {
                    result.add(cell);
                }
            } else {
                result.add(cell);
            }
        }
        return result;
    } else if (rowTmp.getClass().isArray()) {
        for (Object row : this.rows) {
            cell = ((Object[]) row)[0];
            if (distinct) {
                if (!result.contains(cell)) {
                    result.add(cell);
                }
            } else {
                result.add(cell);
            }
        }
        return result;
    }
    throw new DataAccessException("切取集合的单列值的前提是返回结果是List<List> 和List<Object[]>类型场景!");
}
Also used : ArrayList(java.util.ArrayList) List(java.util.List) ArrayList(java.util.ArrayList) DataAccessException(org.sagacity.sqltoy.exception.DataAccessException)

Aggregations

DataAccessException (org.sagacity.sqltoy.exception.DataAccessException)40 Connection (java.sql.Connection)24 DataSourceCallbackHandler (org.sagacity.sqltoy.callback.DataSourceCallbackHandler)24 ArrayList (java.util.ArrayList)19 SqlToyConfig (org.sagacity.sqltoy.config.model.SqlToyConfig)17 List (java.util.List)13 ShardingModel (org.sagacity.sqltoy.config.model.ShardingModel)13 QueryExecutorExtend (org.sagacity.sqltoy.model.inner.QueryExecutorExtend)12 QueryExecutor (org.sagacity.sqltoy.model.QueryExecutor)9 QueryResult (org.sagacity.sqltoy.model.QueryResult)9 SqlToyResult (org.sagacity.sqltoy.config.model.SqlToyResult)6 HashMap (java.util.HashMap)5 Serializable (java.io.Serializable)4 NoSqlConfigModel (org.sagacity.sqltoy.config.model.NoSqlConfigModel)4 HashSet (java.util.HashSet)3 ExecutorService (java.util.concurrent.ExecutorService)3 EntityMeta (org.sagacity.sqltoy.config.model.EntityMeta)3 FieldMeta (org.sagacity.sqltoy.config.model.FieldMeta)3 Type (java.lang.reflect.Type)2 ResultSet (java.sql.ResultSet)2