Commit 9fba3e63 by yuwei

2.0.0项目初始化

parent 5a195cbf
...@@ -47,7 +47,7 @@ public class MD5Util { ...@@ -47,7 +47,7 @@ public class MD5Util {
public static void main(String[] args) { public static void main(String[] args) {
try { try {
String value = "1214826565321543682"; String value = "1214835832967581698";
MD5Util mt = new MD5Util(); MD5Util mt = new MD5Util();
System.out.println("加密前的字符:" + value); System.out.println("加密前的字符:" + value);
System.out.println("加密后的字符:" + mt.encode(value)); System.out.println("加密后的字符:" + mt.encode(value));
......
...@@ -37,6 +37,11 @@ public class PageUtil implements Serializable { ...@@ -37,6 +37,11 @@ public class PageUtil implements Serializable {
public PageUtil(Integer pageNum, Integer pageSize) { public PageUtil(Integer pageNum, Integer pageSize) {
this.pageNum = pageNum; this.pageNum = pageNum;
this.pageSize = pageSize; this.pageSize = pageSize;
if (this.pageSize > 0) {
this.pageSize = this.pageSize > DEFAULT_MAX_COUNT ? DEFAULT_MAX_COUNT : this.pageSize;
} else {
this.pageSize = 20;
}
} }
public Integer getOffset() { public Integer getOffset() {
......
...@@ -51,6 +51,14 @@ public interface DbQuery { ...@@ -51,6 +51,14 @@ public interface DbQuery {
int count(String sql); int count(String sql);
/** /**
* 获取总数带查询参数
*
* @param sql
* @return
*/
int count(String sql, Object[] args);
/**
* 查询结果列表 * 查询结果列表
* *
* @param sql * @param sql
......
...@@ -81,9 +81,14 @@ public class DbQueryTemplate implements DbQuery { ...@@ -81,9 +81,14 @@ public class DbQueryTemplate implements DbQuery {
@Override @Override
public PageResult<Map<String, Object>> queryByPage(String sql, Object[] args, long offset, long size) { public PageResult<Map<String, Object>> queryByPage(String sql, Object[] args, long offset, long size) {
int total = count(sql); int total = count(sql, args);
String pageSql = dbDialect.buildPaginationSql(sql, offset, size); String pageSql = dbDialect.buildPaginationSql(sql, offset, size);
List<Map<String, Object>> records = jdbcTemplate.queryForList(pageSql, args); List<Map<String, Object>> records = jdbcTemplate.queryForList(pageSql, args);
return new PageResult<>(total, records); return new PageResult<>(total, records);
} }
@Override
public int count(String sql, Object[] args) {
return jdbcTemplate.queryForObject(dbDialect.count(sql), args, Integer.class);
}
} }
...@@ -12,6 +12,7 @@ import org.springframework.cache.interceptor.KeyGenerator; ...@@ -12,6 +12,7 @@ import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*; import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
...@@ -51,31 +52,39 @@ public class RedisConfig extends CachingConfigurerSupport { ...@@ -51,31 +52,39 @@ public class RedisConfig extends CachingConfigurerSupport {
@Bean @Bean
@ConditionalOnBean(name = "redisTemplate") @ConditionalOnBean(name = "redisTemplate")
public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) { public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//spring cache注解序列化配置 //spring cache注解序列化配置
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
//默认缓存过期时间
.entryTtl(Duration.ofMinutes(30))
//key序列化方式 //key序列化方式
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getKeySerializer())) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
//value序列化方式 //value序列化方式
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
//不缓存null值 //不缓存null值
.disableCachingNullValues() .disableCachingNullValues();
//默认缓存过期时间
.entryTtl(Duration.ofMinutes(30));
//设置一个初始化的缓存名称set集合 //设置一个初始化的缓存名称set集合
Set<String> cacheNames = new HashSet<>(); // Set<String> cacheNames = new HashSet<>();
// cacheNames.add("user"); // cacheNames.add("user");
//对每个缓存名称应用不同的配置,自定义过期时间 //对每个缓存名称应用不同的配置,自定义过期时间
Map<String, RedisCacheConfiguration> configMap = new HashMap<>(); // Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
// configMap.put("user", redisCacheConfiguration.entryTtl(Duration.ofMinutes(30))); // configMap.put("user", redisCacheConfiguration.entryTtl(Duration.ofMinutes(30)));
RedisCacheManager redisCacheManager = RedisCacheManager.builder(redisTemplate.getConnectionFactory()) RedisCacheManager redisCacheManager = RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(redisCacheConfiguration) .cacheDefaults(redisCacheConfiguration)
.transactionAware() // .transactionAware()
//注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置 //注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置
.initialCacheNames(cacheNames) // .initialCacheNames(cacheNames)
.withInitialCacheConfigurations(configMap) // .withInitialCacheConfigurations(configMap)
.build(); .build();
return redisCacheManager; return redisCacheManager;
} }
......
...@@ -19,6 +19,7 @@ spring: ...@@ -19,6 +19,7 @@ spring:
predicates: predicates:
- Path=/auth/** - Path=/auth/**
filters: filters:
- StripPrefix=1
- name: Hystrix - name: Hystrix
args: args:
name: authFallback name: authFallback
......
...@@ -3,6 +3,7 @@ package cn.datax.gateway.config; ...@@ -3,6 +3,7 @@ package cn.datax.gateway.config;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.cloud.gateway.config.GatewayProperties; import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource; import springfox.documentation.swagger.web.SwaggerResource;
...@@ -25,15 +26,17 @@ public class SwaggerProvider implements SwaggerResourcesProvider { ...@@ -25,15 +26,17 @@ public class SwaggerProvider implements SwaggerResourcesProvider {
@Override @Override
public List<SwaggerResource> get() { public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>(); List<SwaggerResource> resources = new ArrayList<>();
Set<String> routes = new HashSet<>(); List<String> routes = new ArrayList<>();
//取出gateway的route //取出gateway的route
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId())); routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
//结合配置的route-路径(Path),和route过滤,只获取有效的route节点 //结合配置的route-路径(Path),和route过滤,只获取有效的route节点
gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())) gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId()))
.forEach(routeDefinition -> routeDefinition.getPredicates().stream() .forEach(routeDefinition -> routeDefinition.getPredicates().stream()
.filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName())) .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
.filter(predicateDefinition -> !"datax-auth".equalsIgnoreCase(routeDefinition.getId()))
.forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(), .forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),
"/" + routeDefinition.getId() + API_URI)))); predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
.replace("/**", API_URI)))));
return resources; return resources;
} }
......
package cn.datax.gateway.filter; package cn.datax.gateway.filter;
import cn.datax.gateway.config.SwaggerProvider;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
...@@ -11,17 +12,15 @@ import org.springframework.web.server.ServerWebExchange; ...@@ -11,17 +12,15 @@ import org.springframework.web.server.ServerWebExchange;
public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory { public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {
private static final String HEADER_NAME = "X-Forwarded-Prefix"; private static final String HEADER_NAME = "X-Forwarded-Prefix";
private static final String URI = "/v2/api-docs";
@Override @Override
public GatewayFilter apply(Object config) { public GatewayFilter apply(Object config) {
return (exchange, chain) -> { return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest(); ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath(); String path = request.getURI().getPath();
if (!StringUtils.endsWithIgnoreCase(path,URI)) { if (!StringUtils.endsWithIgnoreCase(path, SwaggerProvider.API_URI)) {
return chain.filter(exchange); return chain.filter(exchange);
} }
String basePath = path.substring(0, path.lastIndexOf(URI)); String basePath = path.substring(0, path.lastIndexOf(SwaggerProvider.API_URI));
ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build(); ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
ServerWebExchange newExchange = exchange.mutate().request(newRequest).build(); ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
return chain.filter(newExchange); return chain.filter(newExchange);
......
...@@ -27,11 +27,6 @@ ...@@ -27,11 +27,6 @@
<artifactId>springfox-swagger-ui</artifactId> <artifactId>springfox-swagger-ui</artifactId>
<version>${swagger2.version}</version> <version>${swagger2.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>${swagger-bootstrap.version}</version>
</dependency>
<!--feign 依赖--> <!--feign 依赖-->
<dependency> <dependency>
<groupId>io.github.openfeign</groupId> <groupId>io.github.openfeign</groupId>
......
...@@ -6,9 +6,9 @@ import org.springframework.cloud.openfeign.FeignClient; ...@@ -6,9 +6,9 @@ import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(contextId = "dataSourceServiceFeign", value = "datax-service-data-market", fallbackFactory = DataSourceServiceFeignFallbackFactory.class) @FeignClient(contextId = "dataSourceServiceFeign", value = "datax-service-data-factory", fallbackFactory = DataSourceServiceFeignFallbackFactory.class)
public interface DataSourceServiceFeign { public interface DataSourceServiceFeign {
@GetMapping("/dataSource/{id}") @GetMapping("/inner/dataSource/{id}")
R getDataSourceById(@PathVariable("id") String id); R getDataSourceById(@PathVariable("id") String id);
} }
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.datax.service.data.factory.api.feign.factory.DataSourceServiceFeignFallbackFactory,\
cn.datax.service.data.factory.api.feign.fallback.DataSourceServiceFeignFallbackImpl
...@@ -12,7 +12,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients; ...@@ -12,7 +12,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableDataMybatis @EnableDataMybatis
@EnableDataRedis @EnableDataRedis
@EnableDataLog @EnableDataLog
@EnableFeignClients(basePackages = {"cn.datax.service.system.api.feign"}) @EnableFeignClients(basePackages = {"cn.datax.service.data.factory.api.feign"})
@SpringCloudApplication @SpringCloudApplication
public class DataFactoryApplication { public class DataFactoryApplication {
......
package cn.datax.service.data.factory.config; package cn.datax.service.data.factory.config;
import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
...@@ -19,7 +18,6 @@ import java.util.List; ...@@ -19,7 +18,6 @@ import java.util.List;
@Configuration @Configuration
@EnableSwagger2 @EnableSwagger2
@EnableSwaggerBootstrapUI
public class SwaggerConfig { public class SwaggerConfig {
/** /**
......
package cn.datax.service.data.factory.controller;
import cn.datax.common.base.BaseController;
import cn.datax.common.core.R;
import cn.datax.common.security.annotation.DataInner;
import cn.datax.service.data.factory.api.entity.DataSourceEntity;
import cn.datax.service.data.factory.mapstruct.DataSourceMapper;
import cn.datax.service.data.factory.service.DataSourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/inner")
public class InnerController extends BaseController {
@Autowired
private DataSourceService dataSourceService;
@Autowired
private DataSourceMapper dataSourceMapper;
@DataInner
@GetMapping("/dataSource/{id}")
public R getDataSourceById(@PathVariable String id) {
DataSourceEntity dataSourceEntity = dataSourceService.getById(id);
return R.ok().setData(dataSourceMapper.toVO(dataSourceEntity));
}
}
...@@ -12,10 +12,15 @@ import cn.datax.service.data.factory.service.DataSourceService; ...@@ -12,10 +12,15 @@ import cn.datax.service.data.factory.service.DataSourceService;
import cn.datax.service.data.factory.mapstruct.DataSourceMapper; import cn.datax.service.data.factory.mapstruct.DataSourceMapper;
import cn.datax.common.base.BaseServiceImpl; import cn.datax.common.base.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
...@@ -30,6 +35,7 @@ import java.util.stream.Collectors; ...@@ -30,6 +35,7 @@ import java.util.stream.Collectors;
* @author yuwei * @author yuwei
* @since 2020-03-14 * @since 2020-03-14
*/ */
@CacheConfig(cacheNames = "data:factory:sources")
@Service @Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DataSourceServiceImpl extends BaseServiceImpl<DataSourceDao, DataSourceEntity> implements DataSourceService { public class DataSourceServiceImpl extends BaseServiceImpl<DataSourceDao, DataSourceEntity> implements DataSourceService {
...@@ -50,6 +56,7 @@ public class DataSourceServiceImpl extends BaseServiceImpl<DataSourceDao, DataSo ...@@ -50,6 +56,7 @@ public class DataSourceServiceImpl extends BaseServiceImpl<DataSourceDao, DataSo
dataSourceDao.insert(dataSource); dataSourceDao.insert(dataSource);
} }
@CachePut(key = "#p0.id")
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateDataSource(DataSourceDto dataSourceDto) { public void updateDataSource(DataSourceDto dataSourceDto) {
...@@ -57,6 +64,13 @@ public class DataSourceServiceImpl extends BaseServiceImpl<DataSourceDao, DataSo ...@@ -57,6 +64,13 @@ public class DataSourceServiceImpl extends BaseServiceImpl<DataSourceDao, DataSo
dataSourceDao.updateById(dataSource); dataSourceDao.updateById(dataSource);
} }
@Cacheable(key = "#id", unless = "#result == null")
@Override
public DataSourceEntity getById(Serializable id) {
return super.getById(id);
}
@CacheEvict(key = "#id")
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteDataSourceById(String id) { public void deleteDataSourceById(String id) {
......
...@@ -27,11 +27,6 @@ ...@@ -27,11 +27,6 @@
<artifactId>springfox-swagger-ui</artifactId> <artifactId>springfox-swagger-ui</artifactId>
<version>${swagger2.version}</version> <version>${swagger2.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>${swagger-bootstrap.version}</version>
</dependency>
<!--feign 依赖--> <!--feign 依赖-->
<dependency> <dependency>
<groupId>io.github.openfeign</groupId> <groupId>io.github.openfeign</groupId>
......
...@@ -61,6 +61,8 @@ public class DataApiDto implements Serializable { ...@@ -61,6 +61,8 @@ public class DataApiDto implements Serializable {
private ExecuteConfig executeConfig; private ExecuteConfig executeConfig;
@ApiModelProperty(value = "请求参数") @ApiModelProperty(value = "请求参数")
@Valid @Valid
@NotEmpty(message = "请求参数不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
@Size(min = 1, message="请求参数长度不能少于{min}位")
private List<ReqParam> reqParams; private List<ReqParam> reqParams;
@ApiModelProperty(value = "返回参数") @ApiModelProperty(value = "返回参数")
@Valid @Valid
......
...@@ -7,6 +7,7 @@ import lombok.Data; ...@@ -7,6 +7,7 @@ import lombok.Data;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
...@@ -21,7 +22,7 @@ public class ExecuteConfig implements Serializable { ...@@ -21,7 +22,7 @@ public class ExecuteConfig implements Serializable {
private String sourceId; private String sourceId;
@ApiModelProperty(value = "配置方式") @ApiModelProperty(value = "配置方式")
@NotBlank(message = "配置方式不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) @NotNull(message = "配置方式不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private Integer configType; private Integer configType;
@ApiModelProperty(value = "选择表") @ApiModelProperty(value = "选择表")
......
...@@ -27,8 +27,12 @@ public class ReqParam implements Serializable { ...@@ -27,8 +27,12 @@ public class ReqParam implements Serializable {
@NotBlank(message = "描述不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) @NotBlank(message = "描述不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private String remark; private String remark;
@ApiModelProperty(value = "操作符")
@NotNull(message = "操作符不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private Integer whereType;
@ApiModelProperty(value = "数据类型") @ApiModelProperty(value = "数据类型")
@NotBlank(message = "数据类型不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) @NotNull(message = "数据类型不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private Integer dataType; private Integer dataType;
@ApiModelProperty(value = "示例值") @ApiModelProperty(value = "示例值")
......
...@@ -6,6 +6,7 @@ import io.swagger.annotations.ApiModelProperty; ...@@ -6,6 +6,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
@ApiModel(value = "返回参数信息Model") @ApiModel(value = "返回参数信息Model")
...@@ -23,7 +24,7 @@ public class ResParam implements Serializable { ...@@ -23,7 +24,7 @@ public class ResParam implements Serializable {
private String remark; private String remark;
@ApiModelProperty(value = "数据类型") @ApiModelProperty(value = "数据类型")
@NotBlank(message = "数据类型不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class}) @NotNull(message = "数据类型不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private Integer dataType; private Integer dataType;
@ApiModelProperty(value = "示例值") @ApiModelProperty(value = "示例值")
......
...@@ -50,7 +50,7 @@ public class DataApiEntity extends DataScopeBaseEntity { ...@@ -50,7 +50,7 @@ public class DataApiEntity extends DataScopeBaseEntity {
private String remark; private String remark;
/** /**
* 请求方式 * 请求类型
*/ */
private String reqMethod; private String reqMethod;
......
...@@ -11,7 +11,6 @@ public class SqlParseVo implements Serializable { ...@@ -11,7 +11,6 @@ public class SqlParseVo implements Serializable {
private static final long serialVersionUID=1L; private static final long serialVersionUID=1L;
private String sqlText;
private List<ReqParam> reqParams; private List<ReqParam> reqParams;
private List<ResParam> resParams; private List<ResParam> resParams;
} }
...@@ -12,7 +12,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients; ...@@ -12,7 +12,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableDataMybatis @EnableDataMybatis
@EnableDataRedis @EnableDataRedis
@EnableDataLog @EnableDataLog
@EnableFeignClients(basePackages = {"cn.datax.service.system.api.feign"}) @EnableFeignClients(basePackages = {"cn.datax.service.data.factory.api.feign"})
@SpringCloudApplication @SpringCloudApplication
public class DataMarketApplication { public class DataMarketApplication {
......
...@@ -59,6 +59,11 @@ public class ApiInterceptor implements HandlerInterceptor { ...@@ -59,6 +59,11 @@ public class ApiInterceptor implements HandlerInterceptor {
HttpServletResponse.SC_FORBIDDEN, R.error("API不存在")); HttpServletResponse.SC_FORBIDDEN, R.error("API不存在"));
return false; return false;
} }
if (!request.getMethod().equals(dataApiEntity.getReqMethod())){
ResponseUtil.makeResponse(response, MediaType.APPLICATION_JSON_VALUE,
HttpServletResponse.SC_FORBIDDEN, R.error("API请求类型不对"));
return false;
}
String deny = dataApiEntity.getDeny(); String deny = dataApiEntity.getDeny();
deny = Optional.ofNullable(deny).orElse(""); deny = Optional.ofNullable(deny).orElse("");
List<String> denyList = Arrays.asList(deny.split(",")); List<String> denyList = Arrays.asList(deny.split(","));
...@@ -108,7 +113,7 @@ public class ApiInterceptor implements HandlerInterceptor { ...@@ -108,7 +113,7 @@ public class ApiInterceptor implements HandlerInterceptor {
log.setCallerDate(LocalDateTime.now()); log.setCallerDate(LocalDateTime.now());
log.setTime(System.currentTimeMillis()); log.setTime(System.currentTimeMillis());
log.setStatus(DataConstant.TrueOrFalse.TRUE.getKey()); log.setStatus(DataConstant.TrueOrFalse.TRUE.getKey());
ThreadUtil.set(log); ThreadUtil.getInstance().set(log);
return true; return true;
} }
...@@ -119,9 +124,9 @@ public class ApiInterceptor implements HandlerInterceptor { ...@@ -119,9 +124,9 @@ public class ApiInterceptor implements HandlerInterceptor {
@Override @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
ThreadUtil.get().setTime(System.currentTimeMillis() - ThreadUtil.get().getTime()); ThreadUtil.getInstance().get().setTime(System.currentTimeMillis() - ThreadUtil.getInstance().get().getTime());
log.info("调用消耗时间:" + ThreadUtil.get().getTime()); log.info("调用消耗时间:" + ThreadUtil.getInstance().get().getTime());
log.info("调用日志:" + ThreadUtil.get()); log.info("调用日志:" + ThreadUtil.getInstance().get());
ThreadUtil.remove(); ThreadUtil.getInstance().remove();
} }
} }
package cn.datax.service.data.market.config; package cn.datax.service.data.market.config;
import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
...@@ -19,7 +18,6 @@ import java.util.List; ...@@ -19,7 +18,6 @@ import java.util.List;
@Configuration @Configuration
@EnableSwagger2 @EnableSwagger2
@EnableSwaggerBootstrapUI
public class SwaggerConfig { public class SwaggerConfig {
/** /**
......
...@@ -2,13 +2,13 @@ package cn.datax.service.data.market.controller; ...@@ -2,13 +2,13 @@ package cn.datax.service.data.market.controller;
import cn.datax.common.base.BaseController; import cn.datax.common.base.BaseController;
import cn.datax.common.core.R; import cn.datax.common.core.R;
import cn.datax.common.database.core.PageResult;
import cn.datax.service.data.market.service.ApiService; import cn.datax.service.data.market.service.ApiService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map; import java.util.Map;
@RestController @RestController
...@@ -19,7 +19,7 @@ public class ApiController extends BaseController { ...@@ -19,7 +19,7 @@ public class ApiController extends BaseController {
@RequestMapping(value = "/v1/**", method = {RequestMethod.GET, RequestMethod.POST}) @RequestMapping(value = "/v1/**", method = {RequestMethod.GET, RequestMethod.POST})
public R apiV1(){ public R apiV1(){
List<Map<String, Object>> list = apiService.v1(); PageResult<Map<String, Object>> pageResult = apiService.v1();
return R.ok().setData(list); return R.ok().setData(pageResult);
} }
} }
package cn.datax.service.data.market.controller;
import cn.datax.common.base.BaseController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/inner")
public class InnerController extends BaseController {
}
package cn.datax.service.data.market.enums; package cn.datax.service.data.market.enums;
public enum ConfigEnum { public enum ConfigType {
FORM(1, "表引导模式"), FORM(1, "表引导模式"),
SCRIPT(2, "脚本模式"); SCRIPT(2, "脚本模式");
...@@ -9,7 +9,7 @@ public enum ConfigEnum { ...@@ -9,7 +9,7 @@ public enum ConfigEnum {
private final String val; private final String val;
ConfigEnum(Integer key, String val) { ConfigType(Integer key, String val) {
this.key = key; this.key = key;
this.val = val; this.val = val;
} }
......
package cn.datax.service.data.market.enums;
public enum WhereType {
EQUALS(1, "=", "等于"),
NOT_EQUALS(2, "!=", "不等于"),
LIKE(3, "LIKE", "全模糊查询"),
LIKE_LEFT(4, "LIKE_LEFT", "左模糊查询"),
LIKE_RIGHT(5, "LIKE_RIGHT", "右模糊查询"),
GREATER_THAN(6, ">", "大于"),
GREATER_THAN_EQUALS(7, ">=", "大于等于"),
LESS_THAN(8, "<", "小于"),
LESS_THAN_EQUALS(9, "<=", "小于等于"),
IN(10, "IN", "IN");
private final Integer type;
private final String key;
private final String desc;
WhereType(Integer type, String key, String desc) {
this.type = type;
this.key = key;
this.desc = desc;
}
public static WhereType getWhereType(Integer whereType) {
for (WhereType type : WhereType.values()) {
if (type.type == whereType) {
return type;
}
}
return EQUALS;
}
}
package cn.datax.service.data.market.service; package cn.datax.service.data.market.service;
import java.util.List; import cn.datax.common.database.core.PageResult;
import java.util.Map; import java.util.Map;
public interface ApiService { public interface ApiService {
List<Map<String, Object>> v1(); PageResult<Map<String, Object>> v1();
} }
...@@ -4,6 +4,7 @@ import cn.datax.common.core.R; ...@@ -4,6 +4,7 @@ import cn.datax.common.core.R;
import cn.datax.common.database.DataSourceFactory; import cn.datax.common.database.DataSourceFactory;
import cn.datax.common.database.DbQuery; import cn.datax.common.database.DbQuery;
import cn.datax.common.database.constants.DbQueryProperty; import cn.datax.common.database.constants.DbQueryProperty;
import cn.datax.common.database.core.PageResult;
import cn.datax.common.exception.DataException; import cn.datax.common.exception.DataException;
import cn.datax.common.utils.PageUtil; import cn.datax.common.utils.PageUtil;
import cn.datax.common.utils.ThrowableUtil; import cn.datax.common.utils.ThrowableUtil;
...@@ -13,6 +14,7 @@ import cn.datax.service.data.factory.api.feign.DataSourceServiceFeign; ...@@ -13,6 +14,7 @@ import cn.datax.service.data.factory.api.feign.DataSourceServiceFeign;
import cn.datax.service.data.market.api.entity.DataApiEntity; import cn.datax.service.data.market.api.entity.DataApiEntity;
import cn.datax.service.data.market.dao.DataApiDao; import cn.datax.service.data.market.dao.DataApiDao;
import cn.datax.service.data.market.service.ApiService; import cn.datax.service.data.market.service.ApiService;
import cn.datax.service.data.market.utils.SqlBuilderUtil;
import cn.datax.service.data.market.utils.ThreadUtil; import cn.datax.service.data.market.utils.ThreadUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
...@@ -20,8 +22,8 @@ import lombok.extern.slf4j.Slf4j; ...@@ -20,8 +22,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
@Slf4j @Slf4j
@Service @Service
...@@ -37,10 +39,15 @@ public class ApiServiceImpl implements ApiService { ...@@ -37,10 +39,15 @@ public class ApiServiceImpl implements ApiService {
private DataApiDao dataApiDao; private DataApiDao dataApiDao;
@Override @Override
public List<Map<String, Object>> v1() { public PageResult<Map<String, Object>> v1() {
DataApiEntity dataApiEntity = dataApiDao.selectById(ThreadUtil.get().getId()); // 缓存取数据
// redisTemplate.opsForValue().get("myCache::userName")
DataApiEntity dataApiEntity = dataApiDao.selectById(ThreadUtil.getInstance().get().getApiId());
R result = dataSourceServiceFeign.getDataSourceById(dataApiEntity.getExecuteConfig().getSourceId()); R result = dataSourceServiceFeign.getDataSourceById(dataApiEntity.getExecuteConfig().getSourceId());
if(result == null || !result.isSuccess() || ObjectUtil.isEmpty(result.getData())){ if(result == null || !result.isSuccess() || ObjectUtil.isEmpty(result.getData())){
ThreadUtil.getInstance().get().setStatus(0);
ThreadUtil.getInstance().get().setMsg("API调用查询数据源{"+dataApiEntity.getExecuteConfig().getSourceId()+"}出错");
throw new DataException("API调用查询数据源出错"); throw new DataException("API调用查询数据源出错");
} }
DataSourceEntity dataSource = JSON.parseObject(JSON.toJSONString(result.getData()), DataSourceEntity.class); DataSourceEntity dataSource = JSON.parseObject(JSON.toJSONString(result.getData()), DataSourceEntity.class);
...@@ -48,17 +55,34 @@ public class ApiServiceImpl implements ApiService { ...@@ -48,17 +55,34 @@ public class ApiServiceImpl implements ApiService {
DbQueryProperty dbQueryProperty = new DbQueryProperty(dataSource.getDbType(), dbSchema.getHost(), DbQueryProperty dbQueryProperty = new DbQueryProperty(dataSource.getDbType(), dbSchema.getHost(),
dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName()); dbSchema.getUsername(), dbSchema.getPassword(), dbSchema.getPort(), dbSchema.getDbName());
DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty); DbQuery dbQuery = dataSourceFactory.createDbQuery(dbQueryProperty);
try { // 接收参数
// 分页查询 Map<String, Object> params = JSON.parseObject(ThreadUtil.getInstance().get().getCallerParams());
PageUtil pageUtil = new PageUtil(1, 20); // 分页参数
Integer pageNum = (Integer) Optional.ofNullable(params.get("pageNum")).orElse(1);
Integer pageSize = (Integer) Optional.ofNullable(params.get("pageSize")).orElse(20);
PageUtil pageUtil = new PageUtil(pageNum, pageSize);
Integer offset = pageUtil.getOffset(); Integer offset = pageUtil.getOffset();
List<Map<String, Object>> list = dbQuery.queryList(dataApiEntity.getSqlText()); SqlBuilderUtil.SqlFilterResult sqlFilterResult;
return list; try {
sqlFilterResult = SqlBuilderUtil.getInstance().applyFilters(dataApiEntity.getExecuteConfig().getSqlText(), params);
} catch (Exception e) {
log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e));
ThreadUtil.getInstance().get().setStatus(0);
ThreadUtil.getInstance().get().setMsg(e.getMessage());
throw new DataException("API调用动态构造SQL语句出错");
}
Object[] args = new Object[] {};
Map<String, Object> acceptedFilters = sqlFilterResult.getAcceptedFilters();
args = acceptedFilters.values().toArray();
try {
PageResult<Map<String, Object>> pageResult = dbQuery.queryByPage(sqlFilterResult.getSql(), args, offset, pageSize);
pageResult.setPageNum(pageNum).setPageSize(pageSize);
return pageResult;
} catch (Exception e) { } catch (Exception e) {
log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e)); log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e));
ThreadUtil.get().setStatus(0); ThreadUtil.getInstance().get().setStatus(0);
ThreadUtil.get().setMsg(e.getMessage()); ThreadUtil.getInstance().get().setMsg(e.getMessage());
throw new DataException("API调用出错"); throw new DataException("API调用查询结果集出错");
} }
} }
} }
...@@ -5,11 +5,12 @@ import cn.datax.common.utils.ThrowableUtil; ...@@ -5,11 +5,12 @@ import cn.datax.common.utils.ThrowableUtil;
import cn.datax.service.data.market.api.dto.*; import cn.datax.service.data.market.api.dto.*;
import cn.datax.service.data.market.api.entity.DataApiEntity; import cn.datax.service.data.market.api.entity.DataApiEntity;
import cn.datax.service.data.market.api.vo.SqlParseVo; import cn.datax.service.data.market.api.vo.SqlParseVo;
import cn.datax.service.data.market.enums.ConfigEnum; import cn.datax.service.data.market.enums.ConfigType;
import cn.datax.service.data.market.service.DataApiService; import cn.datax.service.data.market.service.DataApiService;
import cn.datax.service.data.market.mapstruct.DataApiMapper; import cn.datax.service.data.market.mapstruct.DataApiMapper;
import cn.datax.service.data.market.dao.DataApiDao; import cn.datax.service.data.market.dao.DataApiDao;
import cn.datax.common.base.BaseServiceImpl; import cn.datax.common.base.BaseServiceImpl;
import cn.datax.service.data.market.utils.SqlBuilderUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.ExpressionVisitorAdapter; import net.sf.jsqlparser.expression.ExpressionVisitorAdapter;
...@@ -48,7 +49,7 @@ import java.util.stream.Collectors; ...@@ -48,7 +49,7 @@ import java.util.stream.Collectors;
* @since 2020-03-31 * @since 2020-03-31
*/ */
@Slf4j @Slf4j
@CacheConfig(cacheNames = {"apis"}) @CacheConfig(cacheNames = "data:market:apis")
@Service @Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntity> implements DataApiService { public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntity> implements DataApiService {
...@@ -77,21 +78,14 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit ...@@ -77,21 +78,14 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit
private DataApiEntity shareCode(DataApiDto dataApiDto) { private DataApiEntity shareCode(DataApiDto dataApiDto) {
DataApiEntity dataApi = dataApiMapper.toEntity(dataApiDto); DataApiEntity dataApi = dataApiMapper.toEntity(dataApiDto);
Integer configType = dataApi.getExecuteConfig().getConfigType(); Integer configType = dataApi.getExecuteConfig().getConfigType();
if (ConfigEnum.FORM.getKey() == configType) { if (ConfigType.FORM.getKey() == configType) {
try { try {
dataApi.setSqlText(sqlBuild(dataApi)); dataApi.getExecuteConfig().setSqlText(sqlJdbcNamedParameterBuild(dataApi));
} catch (JSQLParserException e) { } catch (JSQLParserException e) {
log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e)); log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e));
throw new DataException("SQL语法有问题,解析出错"); throw new DataException("SQL语法有问题,解析出错");
} }
} else if (ConfigEnum.SCRIPT.getKey() == configType) { } else if (ConfigType.SCRIPT.getKey() == configType) {}
try {
dataApi.setSqlText(sqlJdbcNamedParameterParse(dataApi.getExecuteConfig().getSqlText()));
} catch (JSQLParserException e) {
log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e));
throw new DataException("SQL语法有问题,解析出错");
}
}
return dataApi; return dataApi;
} }
...@@ -110,9 +104,12 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit ...@@ -110,9 +104,12 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit
@Override @Override
public SqlParseVo sqlParse(SqlParseDto sqlParseDto) { public SqlParseVo sqlParse(SqlParseDto sqlParseDto) {
String sql = sqlParseDto.getSqlText();
sql = sql.replace(SqlBuilderUtil.getInstance().MARK_KEY_START, "");
sql = sql.replace(SqlBuilderUtil.getInstance().MARK_KEY_END, "");
Statement stmt; Statement stmt;
try { try {
stmt = CCJSqlParserUtil.parse(sqlParseDto.getSqlText()); stmt = CCJSqlParserUtil.parse(sql);
} catch (JSQLParserException e) { } catch (JSQLParserException e) {
log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e)); log.error("全局异常信息ex={}, StackTrace={}", e.getMessage(), ThrowableUtil.getStackTrace(e));
throw new DataException("SQL语法有问题,解析出错"); throw new DataException("SQL语法有问题,解析出错");
...@@ -165,10 +162,10 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit ...@@ -165,10 +162,10 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit
} }
}); });
SqlParseVo sqlParseVo = new SqlParseVo(); SqlParseVo sqlParseVo = new SqlParseVo();
sqlParseVo.setSqlText(stmt.toString());
List<ReqParam> reqParams = variables.stream().map(s -> { List<ReqParam> reqParams = variables.stream().map(s -> {
ReqParam reqParam = new ReqParam(); ReqParam reqParam = new ReqParam();
reqParam.setParamName(s); reqParam.setParamName(s);
reqParam.setNullable(0);
return reqParam; return reqParam;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
sqlParseVo.setReqParams(reqParams); sqlParseVo.setReqParams(reqParams);
...@@ -181,14 +178,11 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit ...@@ -181,14 +178,11 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit
return sqlParseVo; return sqlParseVo;
} }
private String sqlBuild(DataApiEntity dataApi) throws JSQLParserException { private String sqlJdbcNamedParameterBuild(DataApiEntity dataApi) throws JSQLParserException {
Table table = new Table(dataApi.getExecuteConfig().getTableName()); Table table = new Table(dataApi.getExecuteConfig().getTableName());
String[] resParams = dataApi.getResParams().stream().map(s -> s.getParamName()).toArray(String[]::new); String[] resParams = dataApi.getResParams().stream().map(s -> s.getParamName()).toArray(String[]::new);
Select select = SelectUtils.buildSelectFromTableAndExpressions(table, resParams); Select select = SelectUtils.buildSelectFromTableAndExpressions(table, resParams);
final StringBuilder sb = new StringBuilder(select.toString()); return SqlBuilderUtil.getInstance().buildHql(select.toString(), dataApi.getReqParams());
sb.append(" ").append("WHERE").append(" ");
dataApi.getReqParams().stream().forEach(s -> sb.append(s.getParamName()).append(" = ? And "));
return sb.substring(0, sb.length() - 5);
} }
private String sqlJdbcNamedParameterParse(String sqlText) throws JSQLParserException { private String sqlJdbcNamedParameterParse(String sqlText) throws JSQLParserException {
......
package cn.datax.service.data.market.utils;
import cn.datax.common.exception.DataException;
import com.alibaba.fastjson.JSON;
import org.springframework.util.Assert;
import java.util.*;
/**
* 带参数sql处理工具类
*/
public class NamedParameterUtil {
public static void main(String[] args) {
String json = "{\"id\": \"1214835832967581698\", \"age\": \"12\"}";
Map<String, Object> params = JSON.parseObject(json);
System.out.println(params);
// String sql = "select * from user where 1 = 1 ${ and id = :id } ${and name = :name}";
// int start = sql.indexOf("${");
// int end = sql.indexOf("}", start);
// String key = sql.substring(start + 2, end);
// System.out.println(key);
// Map<String, Object> params = new HashMap<>();
// params.put("name", "yuwei");
// params.put("id", "123");
// params.put("age", 12);
// ParsedSql parsedSql = NamedParameterUtil.parseSqlStatement(key);
// System.out.println(parsedSql);
// String actualSql = NamedParameterUtil.substituteNamedParams(parsedSql, params);
// Map<String, Object> acceptedFilters = NamedParameterUtil.buildValueArray(parsedSql, params);
// System.out.println(actualSql);
// System.out.println(acceptedFilters);
// SqlBuilderUtil.SqlFilterResult sqlFilterResult = SqlBuilderUtil.getInstance().applyFilters(sql, params);
// System.out.println(sqlFilterResult.getSql());
// Object[] array = new Object[] {};
// array = sqlFilterResult.getAcceptedFilters().values().toArray();
// Arrays.stream(array).forEach(s -> System.out.println(s));
}
private NamedParameterUtil() {}
/**
* 定义特殊字符(增加最后的最定义的'}')
*/
private static final char[] PARAMETER_SEPARATORS =
new char[] {'"', '\'', ':', '&', ',', ';', '(', ')', '|', '=', '+', '-', '*', '%', '/', '\\', '<', '>', '^', '}'};
/**
* 对带参数sql的统计式封装,便于后续肢解拼装
* @param originalSql
* @return
*/
public static ParsedSql parseSqlStatement(String originalSql) {
Assert.notNull(originalSql, "SQL must not be null");
ParsedSql parsedSql = new ParsedSql(originalSql);
Set<String> namedParameters = new HashSet();
char[] sqlchars = originalSql.toCharArray();
int namedParamCount = 0;
int unNamedParamCount = 0;
int totalParamCount = 0;
int i = 0;
while (i < sqlchars.length) {
char statement = sqlchars[i];
if (statement == ':') {
int j = i + 1;
while (j < sqlchars.length && !isSeparatorsChar(sqlchars[j])) {
j++;
}
if (j - i > 1) {
String paramName = originalSql.substring(i + 1, j);
if (!namedParameters.contains(paramName)) {
namedParameters.add(paramName);
namedParamCount++;
}
parsedSql.addParamNames(paramName, i, j);
totalParamCount++;
}
i = j - 1;
} else if (statement == '?') {
unNamedParamCount++;
totalParamCount++;
}
i++;
}
parsedSql.setNamedParamCount(namedParamCount);
parsedSql.setUnnamedParamCount(unNamedParamCount);
parsedSql.setTotalParamCount(totalParamCount);
return parsedSql;
}
/**
* 获得不带参数的sql,即替换参数为?
* @param parsedSql
* @param params
* @return
*/
public static String substituteNamedParams(ParsedSql parsedSql, Map<String, Object> params){
String original = parsedSql.getOriginalSql();
StringBuffer actual = new StringBuffer("");
int lastIndex = 0;
List<String> paramNames = parsedSql.getParamNames();
for (int i = 0; i < paramNames.size(); i++) {
int[] indexs = parsedSql.getParamIndexs(i);
int startIndex = indexs[0];
int endIndex = indexs[1];
String paramName = paramNames.get(i);
actual.append(original.substring(lastIndex, startIndex));
if (params != null && params.containsKey(paramName)) {
actual.append("?");
} else{
actual.append("?");
}
lastIndex = endIndex;
}
actual.append(original.subSequence(lastIndex, original.length()));
return actual.toString();
}
/**
* 获得sql所需参数K,V
* @param parsedSql
* @param params
* @return
*/
public static LinkedHashMap<String, Object> buildValueArray(ParsedSql parsedSql, Map<String, Object> params){
List<String> paramNames = parsedSql.getParamNames();
LinkedHashMap<String, Object> acceptedFilters = new LinkedHashMap<>(parsedSql.getTotalParamCount());
if (parsedSql.getNamedParamCount() > 0 && parsedSql.getUnnamedParamCount() > 0) {
throw new DataException("parameter方式与?方式不能混合!");
}
for (int i = 0; i < paramNames.size(); i++) {
String keyName = paramNames.get(i);
if (params.containsKey(keyName)) {
acceptedFilters.put(keyName, params.get(keyName));
}
}
return acceptedFilters;
}
private static boolean isSeparatorsChar(char statement){
if (Character.isWhitespace(statement)) {
return true;
}
for (int i = 0; i < PARAMETER_SEPARATORS.length; i++) {
if (statement == PARAMETER_SEPARATORS[i]) {
return true;
}
}
return false;
}
}
package cn.datax.service.data.market.utils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* 此类封装NamedParameterSql
*/
public class ParsedSql implements Serializable {
private static final long serialVersionUID=1L;
private String originalSql;
//参数名
private List<String> paramNames = new ArrayList<>();
//参数在sql中对应的位置
private List<int[]> paramIndexs = new ArrayList<>();
//统计参数个数(不包含重复)
private int namedParamCount;
//统计sql中?的个数
private int unnamedParamCount;
private int totalParamCount;
public ParsedSql(String originalSql){
this.originalSql = originalSql;
}
public List<String> getParamNames() {
return paramNames;
}
public void addParamNames(String paramName,int startIndex,int endIndex) {
paramNames.add(paramName);
paramIndexs.add(new int[]{startIndex,endIndex});
}
public int[] getParamIndexs(int position) {
return paramIndexs.get(position);
}
public String getOriginalSql() {
return originalSql;
}
public int getNamedParamCount() {
return namedParamCount;
}
public void setNamedParamCount(int namedParamCount) {
this.namedParamCount = namedParamCount;
}
public int getUnnamedParamCount() {
return unnamedParamCount;
}
public void setUnnamedParamCount(int unnamedParamCount) {
this.unnamedParamCount = unnamedParamCount;
}
public int getTotalParamCount() {
return totalParamCount;
}
public void setTotalParamCount(int totalParamCount) {
this.totalParamCount = totalParamCount;
}
@Override
public String toString() {
return "ParsedSql{" +
"originalSql='" + originalSql + '\'' +
", paramNames=" + paramNames +
", paramIndexs=" + paramIndexs +
", namedParamCount=" + namedParamCount +
", unnamedParamCount=" + unnamedParamCount +
", totalParamCount=" + totalParamCount +
'}';
}
}
package cn.datax.service.data.market.utils;
import cn.datax.service.data.market.api.dto.ReqParam;
import cn.datax.service.data.market.enums.WhereType;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 用于动态构造sql语句
* ${ segment... } 为一个条件代码块
*
* String sql = "select * from user where 1=1
* ${ and username = :username }
* ${ and password = :password }
* ${ and age = :age }"
*
* Map filters = new HashMap();
* filters.put("username", "yuwei");
* filters.put("age", "12");
* filters.put("id", "123");
*
* SqlFilterResult result = SqlBuilderUtil.applyFilters(sql, filters);
*
* result.getSql()结果
* select * from user where 1=1 and username=:username and age=:age
*
* result.getAcceptedFilters()结果
* {username=yuwei}
* {age=12}
*/
@Slf4j
public class SqlBuilderUtil {
private SqlBuilderUtil() {}
private static volatile SqlBuilderUtil instance;
public static SqlBuilderUtil getInstance() {
if(instance == null) {
synchronized (SqlBuilderUtil.class) {
if(instance == null) {
instance = new SqlBuilderUtil();
}
}
}
return instance;
}
/**
* 空格
*/
private final String SPACE = " ";
/**
* 冒号占位符
*/
private final String COLON = ":";
/**
* 问号占位符
*/
private final String MARK = "?";
/**
* where关键字
*/
private final String WHERE_SQL = "WHERE";
/**
* AND连接符
*/
private final String WHERE_AND = "AND";
/**
* where 1=1条件
*/
private final String WHERE_INIT = WHERE_SQL + " 1 = 1";
/**
* 条件代码块标记开始
*/
public String MARK_KEY_START = "${";
/**
* 条件代码块标记结束
*/
public String MARK_KEY_END = "}";
/**
* 拼接命名参数sql
* @param sql
* @param params
* @return
*/
public String buildHql(String sql, List<ReqParam> params){
Assert.notNull(sql, "SQL must not be null");
return buildHql(new StringBuffer(sql), params);
}
private String buildHql(StringBuffer sql, List<ReqParam> params){
if(CollUtil.isEmpty(params)){
return sql.toString();
}
sql.append(SPACE).append(WHERE_INIT);
for (int i = 0; i < params.size(); i++) {
ReqParam reqParam = params.get(i);
sql.append(SPACE).append(MARK_KEY_START).append(WHERE_AND).append(SPACE).append(reqParam.getParamName()).append(SPACE).append(WhereType.getWhereType(reqParam.getWhereType())).append(SPACE).append(COLON).append(reqParam.getParamName()).append(MARK_KEY_END);
}
return sql.toString();
}
/**
* 根据入参动态构造sql语句
* @param sql
* @param filters
* @return
*/
public SqlFilterResult applyFilters(String sql, Map<String, Object> filters){
Assert.notNull(sql, "SQL must not be null");
return applyFilters(new StringBuffer(sql), filters);
}
private SqlFilterResult applyFilters(StringBuffer sql, Map<String, Object> filters){
LinkedHashMap<String, Object> acceptedFilters = new LinkedHashMap<>();
for (int i = 0, end = 0, start = sql.indexOf(MARK_KEY_START); ((start = sql.indexOf(MARK_KEY_START, end)) >= 0); i++) {
end = sql.indexOf(MARK_KEY_END, start);
// 封装该条件代码块中的NamedParameterSql
ParsedSql parsedSql = getSegmentParsedSql(sql, start, end);
if (CollUtil.isEmpty(parsedSql.getParamNames())){
throw new IllegalArgumentException("Not key found in segment=" + sql.substring(start, end + MARK_KEY_END.length()));
}
// 判断输入参数filters中是否存在查询参数
if (isAcceptedKeys(filters, parsedSql.getParamNames())) {
// 动态构造可执行的sql语句,去掉条件代码块两边的${ }标记符
if (log.isDebugEnabled()) {
log.debug("The filter namedParameters=" + parsedSql.getParamNames() + " is accepted on segment=" + sql.substring(start, end + MARK_KEY_END.length()));
}
// 下面方法2选1可以获取条件代码块
// String segment = sql.substring(start + MARK_KEY_START.length(), end);
// String segment = parsedSql.getOriginalSql();
// 转换命名参数:为?
String segment = NamedParameterUtil.substituteNamedParams(parsedSql, filters);
// 获取传参中包含命名参数的数据
LinkedHashMap<String, Object> linkAcceptedFilters = NamedParameterUtil.buildValueArray(parsedSql, filters);
acceptedFilters.putAll(linkAcceptedFilters);
sql.replace(start, end + MARK_KEY_END.length(), segment);
end = start + segment.length();
} else {
// 抛弃该条件代码块
if (log.isDebugEnabled()) {
log.debug("The filter namedParameters=" + parsedSql.getParamNames() + " is removed from the query on segment=" + sql.substring(start, end + MARK_KEY_END.length()));
}
sql.replace(start, end + MARK_KEY_END.length(), "");
end = start;
}
}
return new SqlFilterResult(sql.toString(), acceptedFilters);
}
/**
* 验证入参,并过滤值为空的入参
*/
private boolean isAcceptedKeys(Map<String, Object> filters, List<String> keys) {
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
Object value = getProperty(filters, key);
if (!isValuePopulated(value, true)) {
return false;
}
}
return true;
}
/**
* 封装该条件代码块中的NamedParameterSql
*/
private ParsedSql getSegmentParsedSql(StringBuffer sql, int start, int end) {
String segment = sql.substring(start + MARK_KEY_START.length(), end);
ParsedSql parsedSql = NamedParameterUtil.parseSqlStatement(segment);
return parsedSql;
}
/**
* 获取参数值
* @param filters
* @param key
* @return
*/
private Object getProperty(Map<String, Object> filters, String key) {
if (MapUtil.isEmpty(filters))
return null;
return filters.get(key);
}
/**
* 验证参数值是否空
* @param value
* @param isRemoveEmpty
* @return
*/
private boolean isValuePopulated(Object value, boolean isRemoveEmpty) {
if (value == null) {
return false;
}
if (isRemoveEmpty) {
return ObjectUtil.isNotEmpty(value);
} else {
return true;
}
}
public class SqlFilterResult implements Serializable {
private static final long serialVersionUID=1L;
private String sql;
private Map<String, Object> acceptedFilters;
public SqlFilterResult(String sql, Map<String, Object> acceptedFilters) {
this.setSql(sql);
this.setAcceptedFilters(acceptedFilters);
}
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
public Map<String, Object> getAcceptedFilters() {
return acceptedFilters;
}
public void setAcceptedFilters(Map<String, Object> acceptedFilters) {
this.acceptedFilters = acceptedFilters;
}
@Override
public String toString() {
return "SqlFilterResult{" +
"sql='" + sql + '\'' +
", acceptedFilters=" + acceptedFilters +
'}';
}
}
}
...@@ -4,17 +4,32 @@ import cn.datax.service.data.market.api.dto.ApiLogDto; ...@@ -4,17 +4,32 @@ import cn.datax.service.data.market.api.dto.ApiLogDto;
public class ThreadUtil { public class ThreadUtil {
private ThreadUtil() {}
private static volatile ThreadUtil instance;
public static ThreadUtil getInstance() {
if(instance == null) {
synchronized (ThreadUtil.class) {
if(instance == null) {
instance = new ThreadUtil();
}
}
}
return instance;
}
private final static ThreadLocal<ApiLogDto> logHolder = new ThreadLocal<>(); private final static ThreadLocal<ApiLogDto> logHolder = new ThreadLocal<>();
public static void set(ApiLogDto log){ public void set(ApiLogDto log){
logHolder.set(log); logHolder.set(log);
} }
public static void remove(){ public void remove(){
logHolder.remove(); logHolder.remove();
} }
public static ApiLogDto get(){ public ApiLogDto get(){
return logHolder.get(); return logHolder.get();
} }
} }
...@@ -27,11 +27,6 @@ ...@@ -27,11 +27,6 @@
<artifactId>springfox-swagger-ui</artifactId> <artifactId>springfox-swagger-ui</artifactId>
<version>${swagger2.version}</version> <version>${swagger2.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>${swagger-bootstrap.version}</version>
</dependency>
<!--feign 依赖--> <!--feign 依赖-->
<dependency> <dependency>
<groupId>io.github.openfeign</groupId> <groupId>io.github.openfeign</groupId>
......
package cn.datax.service.system.config; package cn.datax.service.system.config;
import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
...@@ -19,7 +18,6 @@ import java.util.List; ...@@ -19,7 +18,6 @@ import java.util.List;
@Configuration @Configuration
@EnableSwagger2 @EnableSwagger2
@EnableSwaggerBootstrapUI
public class SwaggerConfig { public class SwaggerConfig {
/** /**
......
package cn.datax.service.system.controller;
import cn.datax.common.base.BaseController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/inner")
public class InnerController extends BaseController {
}
...@@ -21,8 +21,6 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; ...@@ -21,8 +21,6 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
...@@ -39,7 +37,6 @@ import java.util.stream.Collectors; ...@@ -39,7 +37,6 @@ import java.util.stream.Collectors;
* @author yuwei * @author yuwei
* @since 2019-09-04 * @since 2019-09-04
*/ */
@CacheConfig(cacheNames = {"users"})
@Service @Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class UserServiceImpl extends BaseServiceImpl<UserDao, UserEntity> implements UserService { public class UserServiceImpl extends BaseServiceImpl<UserDao, UserEntity> implements UserService {
...@@ -132,7 +129,6 @@ public class UserServiceImpl extends BaseServiceImpl<UserDao, UserEntity> implem ...@@ -132,7 +129,6 @@ public class UserServiceImpl extends BaseServiceImpl<UserDao, UserEntity> implem
userDao.updateUserPassword(passwordEncode, userPasswordDto.getId()); userDao.updateUserPassword(passwordEncode, userPasswordDto.getId());
} }
@Cacheable(key = "#username")
@Override @Override
public UserInfo getUserByUsername(String username) { public UserInfo getUserByUsername(String username) {
UserInfo userInfo = new UserInfo(); UserInfo userInfo = new UserInfo();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment