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);
}
}
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);
}
}
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;
}
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;
}
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[]>类型场景!");
}
Aggregations