基于minio,上传sql文件后,使用通用查询接口查询并返回
基于minio,上传sql文件后,使用通用查询接口查询并返回
controller
/**
* 通用查询
*/
@ApiOperation(value = "通用查询", notes = "通用查询")
@PostMapping({"/smartQuery"})
public R<SmartQueryResultDTO> smartQuery(@RequestBody SmartQueryDTO queryDTO) {
/*
3段参数: 固定存放地址的sql脚本文件名(minio)、数据库名(应用名)、参数对象(个数不定)
思路:
1、获取到sql文件并读取内容
2、拼接成完整sql
3、执行sql
*/
//应用名称(用于匹配数据库名)
String appName = queryDTO.getAppName();
ArgumentAssert.notBlank(appName, "应用名称 不能为空");
//sql文件名
String sqlFileName = queryDTO.getSqlFileName();
ArgumentAssert.notBlank(sqlFileName, "sql文件名 不能为空");
//参数集合(会按顺序传入sql文件)
List<String> paramList = queryDTO.getParamList();
//1、获取到sql文件并读取内容:读取minio中指定bucket下面指定文件名的文件中的内容
QueryFileDTO queryFileDTO = new QueryFileDTO();
queryFileDTO.setBucketName("sqlfile");
queryFileDTO.setObjectName(sqlFileName);
R<String> stringR = fileApi.readFileContext(queryFileDTO);
ArgumentAssert.isTrue(stringR.getIsSuccess(), "远程调用文件服务失败");
String sql = stringR.getData();
log.info("文件中的sql:{}", sql);
//2、拼接成完整sql
if (CollectionUtil.isNotEmpty(paramList)) {
/*for (String param : paramList) {
sql = sql.replaceFirst(CommonConstant.SQL_PARAM, param);
}*/
//先创建一个MessageFormat实例
MessageFormat messageFormat = new MessageFormat(sql);
//再执行format()进行格式化操作
String[] paramArr = paramList.toArray(new String[]{});
sql = messageFormat.format(paramArr);
}
ArgumentAssert.isFalse(sql.contains("{"),
"经过参数替换,sql任然含有未替换的地方,目前的sql:" + sql);
log.info("替换参数后的完整sql:{}", sql);
//3、执行sql
List<Map<String, Object>> list = new ArrayList<>();
if (StringUtils.isNotBlank(sql)) {
ContextUtil.setTenant(appName);
list = commonMaper.queryBySql(sql);
}
SmartQueryResultDTO resultDTO = new SmartQueryResultDTO();
resultDTO.setDataList(list);
resultDTO.setTotal(list.size());
return R.success(resultDTO);
}
参数DTO
package gov.minhang.aqrcode.common.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* 通用查询DTO
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Builder
@ApiModel(value = "SmartQueryDTO", description = "通用查询DTO")
public class SmartQueryDTO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 应用名称(用于匹配数据库名)
*/
@ApiModelProperty(value = "应用名称(用于匹配数据库名)")
private String appName;
/**
* sql文件名
*/
@ApiModelProperty(value = "sql文件名")
private String sqlFileName;
/**
* 参数集合(按顺序传入sql文件)
*/
@ApiModelProperty(value = "参数集合(按顺序传入sql文件)")
private List<String> paramList;
}
Mapper.java
/**
* 根据完整的sql语句进行查询
*/
@Select("${completeSql}")
List<Map<String, Object>> queryBySql(@Param("completeSql") String completeSql);
文件读取Controller
@ApiOperation(value = "读取文本文件中的内容")
@PostMapping({"/readFileContext"})
public R<String> readFileContext(@RequestBody QueryFileDTO dto) {
String result = null;
//获取文件流
InputStream inputStream = fileContext.getFileStream(dto);
if (inputStream != null) {
//转String
result = new BufferedReader(new InputStreamReader(inputStream))
.lines().collect(Collectors.joining(System.lineSeparator()));
}
return this.success(result);
}
文件读取的实现细节
FileContext ----------------------------------------
/**
* 获取文件流
*/
public InputStream getFileStream(QueryFileDTO dto) {
FileStrategy fileStrategy = getFileStrategy(FileStorageType.MIN_IO);
return fileStrategy.getFile(dto);
}
private FileStrategy getFileStrategy(FileStorageType storageType) {
storageType = storageType == null ? fileServerProperties.getStorageType() : storageType;
FileStrategy fileStrategy = contextStrategyMap.get(storageType.name());
ArgumentAssert.notNull(fileStrategy, "请配置正确的文件存储类型");
return fileStrategy;
}
FileStrategy ----------------------------------------
/**
* 获取文件流 (ps:暂时只实现了minio)
*/
InputStream getFile(QueryFileDTO dto);
MinIoFileStrategyImpl ----------------------------------------
/**
* 获取文件流
*/
@Override
public InputStream getFile(QueryFileDTO dto) {
GetObjectArgs build = GetObjectArgs.builder()
.bucket(dto.getBucketName())
.object(dto.getObjectName())
.build();
try {
return minioClient.getObject(build);
} catch (Exception e) {
log.info(e.getMessage(), e);
throw new BizException(e.getMessage());
}
}