HttpConnectionPoolUtil
这段代码是一个工具类 `HttpConnectionPoolUtil`,用于创建和管理基于连接池的 `HttpClient` 实例。让我们逐步解释其主要功能:
1. **静态常量**:
- 定义了连接超时时间、套接字超时时间、连接池最大连接数、每个路由的最大连接数、空闲连接超时时间等常量。
2. **`setRequestConfig` 方法**:
- 设置请求的配置信息,包括连接请求超时时间、连接超时时间和套接字超时时间。
3. **`getHttpClient` 方法**:
- 根据给定的 URL 获取相应的 `HttpClient` 实例。
- 如果在连接池中已经存在与给定 URL 对应的 `HttpClient` 实例,则直接返回。
- 如果不存在,则创建一个新的 `HttpClient` 实例,并将其加入连接池中。
4. **`createHttpClient` 方法**:
- 创建一个新的 `HttpClient` 实例,并设置连接管理器、重试处理器等。
- 这里使用了连接池管理器 `PoolingHttpClientConnectionManager`,并注册了 `http` 和 `https` 协议的连接工厂。
- 还设置了重试处理器,用于处理请求失败时的重试逻辑。
5. **`setPostParams` 方法**:
- 设置 `HttpPost` 请求的参数,将参数转换为 `NameValuePair` 列表,并设置到 `HttpPost` 实例中。
6. **`closeConnectionPool` 方法**:
- 关闭连接池中所有的 `HttpClient` 实例和相关资源,包括连接、连接管理器和定时任务执行器。
这个工具类主要用于创建和管理基于连接池的 `HttpClient` 实例,提供了便捷的方法来发送 HTTP 请求,并且能够有效地复用连接以提高性能。每次创建CloseableHttpClient 后 , 开辟一个执行定时任务的多线程,定时处理过期的连接和空闲的连接。这样在 http 调用后,可以不加 response.close() 避免连接的重复创建和销毁
public class HttpConnectionPoolUtil {
private static final Logger logger = LoggerFactory.getLogger(HttpConnectionPoolUtil.class);
private static final int CONNECT_TIMEOUT = 20000;
private static final int SOCKET_TIMEOUT = 120000;
private static final int MAX_CONN = 400;
private static final int Max_PRE_ROUTE = 100;
private static final int MAX_ROUTE = 400;
private static final int IDEL_TIMEOUT = 5000;
private static final Map<String, Object[]> clinets = new ConcurrentHashMap();
private static final Object syncLock = new Object();
public HttpConnectionPoolUtil() {
}
public static void setRequestConfig(HttpRequestBase httpRequestBase) {
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(20000).setConnectTimeout(20000).setSocketTimeout(120000).build();
httpRequestBase.setConfig(requestConfig);
}
public static CloseableHttpClient getHttpClient(String url) {
String hostName = url.split("/")[2];
int port = 80;
if (hostName.contains(":")) {
String[] args = hostName.split(":");
hostName = args[0];
port = Integer.parseInt(args[1]);
}
String key = hostName + ":" + port;
Object[] httpClients = (Object[])clinets.get(key);
if (httpClients == null || httpClients.length == 0) {
synchronized(syncLock) {
if (clinets.get(key) == null) {
Object[] clis = createHttpClient(hostName, port);
CloseableHttpClient httpClient = (CloseableHttpClient)clis[0];
final PoolingHttpClientConnectionManager manager = (PoolingHttpClientConnectionManager)clis[1];
ScheduledExecutorService monitorExecutor = Executors.newScheduledThreadPool(1);
monitorExecutor.scheduleAtFixedRate(new TimerTask() {
public void run() {
manager.closeExpiredConnections();
manager.closeIdleConnections(5000L, TimeUnit.MILLISECONDS);
}
}, 100L, 30L, TimeUnit.MILLISECONDS);
clinets.put(key, new Object[]{httpClient, manager, monitorExecutor});
}
}
}
return (CloseableHttpClient)((Object[])clinets.get(key))[0];
}
public static Object[] createHttpClient(String host, int port) {
ConnectionSocketFactory plainSocketFactory = PlainConnectionSocketFactory.getSocketFactory();
LayeredConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactory.getSocketFactory();
Registry<ConnectionSocketFactory> registry = RegistryBuilder.create().register("http", plainSocketFactory).register("https", sslSocketFactory).build();
PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(registry);
manager.setMaxTotal(400);
manager.setDefaultMaxPerRoute(100);
HttpRequestRetryHandler handler = new HttpRequestRetryHandler() {
public boolean retryRequest(IOException e, int i, HttpContext httpContext) {
if (i > 3) {
HttpConnectionPoolUtil.logger.error("retry has more than 3 time, give up request");
return false;
} else if (e instanceof NoHttpResponseException) {
HttpConnectionPoolUtil.logger.error("receive no response from server, retry");
return true;
} else if (e instanceof SSLHandshakeException) {
HttpConnectionPoolUtil.logger.error("SSL hand shake exception");
return false;
} else if (e instanceof InterruptedIOException) {
HttpConnectionPoolUtil.logger.error("InterruptedIOException");
return false;
} else if (e instanceof UnknownHostException) {
HttpConnectionPoolUtil.logger.error("server host unknown");
return false;
} else if (e instanceof ConnectTimeoutException) {
HttpConnectionPoolUtil.logger.error("Connection Time out");
return false;
} else if (e instanceof SSLException) {
HttpConnectionPoolUtil.logger.error("SSLException");
return false;
} else {
HttpClientContext context = HttpClientContext.adapt(httpContext);
HttpRequest request = context.getRequest();
return !(request instanceof HttpEntityEnclosingRequest);
}
}
};
CloseableHttpClient client = HttpClients.custom().setConnectionManager(manager).setRetryHandler(handler).build();
return new Object[]{client, manager};
}
private static void setPostParams(HttpPost httpPost, Map<String, String> params) {
List<NameValuePair> nvps = new ArrayList();
Set<String> keys = params.keySet();
Iterator var4 = keys.iterator();
while(var4.hasNext()) {
String key = (String)var4.next();
nvps.add(new BasicNameValuePair(key, (String)params.get(key)));
}
try {
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
} catch (UnsupportedEncodingException var6) {
var6.printStackTrace();
}
}
public static void closeConnectionPool() {
Iterator var0 = clinets.keySet().iterator();
while(var0.hasNext()) {
String key = (String)var0.next();
Object[] objs = (Object[])clinets.get(key);
CloseableHttpClient client = (CloseableHttpClient)objs[0];
PoolingHttpClientConnectionManager manager = (PoolingHttpClientConnectionManager)objs[1];
ScheduledExecutorService monitorExecutor = (ScheduledExecutorService)objs[2];
try {
client.close();
} catch (Exception var7) {
var7.printStackTrace();
}
manager.close();
monitorExecutor.shutdown();
}
clinets.clear();
}
}
定时任务线程池 ThreadPoolTaskScheduler
使用 @Scheduled(cron = "0 0 19 * * ?") 注解
启动类上加上@EnableScheduling
通过配置类 返回ThreadPoolTaskScheduler ,使多个定时任务在多线程环境下执行。(定时任务相关)
@Configuration
public class ScheduleConfig {
/**
* 此处方法名为Bean的名字,方法名无需固定
* 因为是按TaskScheduler接口自动注入
* @return
*/
@Bean
public TaskScheduler taskScheduler(){
// Spring提供的定时任务线程池类
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
//设定最大可用的线程数目
taskScheduler.setPoolSize(8);
return taskScheduler;
}
}
// 定时触发任务
@Scheduled(cron = "${scheduling.cbr-fdx.cron}")
public void pushSms() {
log.info("给承办人发短信定时任务启动");
// 生成发短信记录,同步到外网发短信
try {
ajFsdxService.pushSmsRecord();
} catch (Exception e) {
log.error("定时任务出错了", e);
}
}
异步线程池 ThreadPoolTaskExecutor
启动类上加上@EnableAsync
异步执行的方法上加上@Async 注解 (调用方与被调用方在同一个类中,确实会导致Async注解失效)
配置异步执行的线程池 通过配置类 返回ThreadPoolTaskExecutor
@Component
@Slf4j
public class ExecutorConfig {
@Bean({"sendMessagePool"})
public Executor otherTaskExecutor() {
int corePoolSize = 8;
log.info("初始化发送短信异步线程池,核心线程大小:{}", corePoolSize);
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(corePoolSize);
executor.setKeepAliveSeconds(60);
executor.setAllowCoreThreadTimeOut(true);
executor.setThreadNamePrefix("sendAsyncPool-");
executor.initialize();
return executor;
}
}
@Async("sendMessagePool")
@Transactional()
public void sendMseeage(TyywMessage tyywMessage, Integer relationshipId) {
QueryWrapper<CaseInfo> wrapper = new QueryWrapper<>();
wrapper.eq("case_number", tyywMessage.getBmsah());
List<CaseInfo> caseInfos = caseInfoMapper.selectList(wrapper);
if (CollectionUtils.isNotEmpty(caseInfos)) {
CaseInfo caseInfo = caseInfos.get(0);
QueryWrapper<CaseSuspect> wrapper1 = new QueryWrapper<>();
wrapper1.eq("bmsah", tyywMessage.getBmsah());
List<CaseSuspect> caseSuspects = caseSuspectMapper.selectList(wrapper1);
if (CollectionUtils.isNotEmpty(caseSuspects)) {
for (CaseSuspect caseSuspect : caseSuspects) {
QueryWrapper<SupectRelationship> wrapper2 = new QueryWrapper<>();
wrapper2.eq("zrrid", caseSuspect.getXyrbh());
if (Objects.nonNull(relationshipId)) {
wrapper2.eq("id", relationshipId);
}
List<SupectRelationship> list = supectRelationshipMapper.selectList(wrapper2);
if (CollectionUtils.isNotEmpty(list)) {
// 0009000900001->嫌疑人,0009000900002->被害人
for (SupectRelationship supectRelationship : list) {
String lawyerString = "";
// 如果是发送给律师,等待10分钟
if (Constants.DLLS.equals(supectRelationship.getRelationship())) {
SysUser cbrUser = userService.getUserByDwbmAndRybm(caseInfo.getOrgCode(), caseInfo.getUndertakerId());
if (cbrUser == null) {
lawyerString = getLawerString(caseInfo, null);
} else {
if (StringUtils.isBlank(cbrUser.getDhhm2())) {
lawyerString = getLawerString(caseInfo, cbrUser);
} else {
lawyerString = "承办人:"+ cbrUser.getRealName() + ",联系电话:" + cbrUser.getDhhm2() + "。";
}
}
try {
Thread.sleep(tyywConfig.getSmsWaitTime() * 60 * 1000);
} catch (InterruptedException e) {
log.error("休眠出错了", e);
}
}
QueryWrapper<SmsRecord> wrapper4 = new QueryWrapper<>();
wrapper4.eq("phone", supectRelationship.getPhone());
wrapper4.eq("lcjdbh", tyywMessage.getLcjdbh());
wrapper4.eq("lxbm", tyywMessage.getAjlx());
wrapper4.eq("bmsah", caseInfo.getCaseNumber());
SmsRecord smsr = smsRecordMapper.selectOne(wrapper4);
if (smsr == null) {
QueryWrapper<SmsTemplate> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("case_type", tyywMessage.getAjlx());
queryWrapper.eq("lcjdbh", tyywMessage.getLcjdbh());
SmsTemplate smsTemplate = smsTemplateMapper.selectOne(queryWrapper);
Map<String, String> map = new HashMap<>();
map.put("dwbm", DwEnums.getDwmc(caseSuspect.getCbdwBm()).getDwmc());
map.put("suspect", caseSuspect.getXm());
if (StringUtils.isBlank(caseInfo.getYsdwmc())) {
log.error("移送单位为空,案件为:{}", JSON.toJSONString(caseInfo));
return;
}
map.put("ysdwmc", caseInfo.getYsdwmc());
if (StringUtils.isNotEmpty(tyywMessage.getSddwmc())) {
map.put("sddwmc", tyywMessage.getSddwmc());
}
map.put("caseaction", caseInfo.getCauseOfAction());
LocalDateTime dateTime = tyywMessage.getTime();
map.put("year", String.valueOf(dateTime.getYear()));
map.put("month", String.valueOf(dateTime.getMonthValue()));
map.put("day", String.valueOf(dateTime.getDayOfMonth()));
map.put("lawyer", lawyerString);
String content = getText(map, smsTemplate.getContent());
String param = "action=send" + "&account=" + smsParam.getAccount() +
"&password=" + smsParam.getPassword() + "&mobile=" + supectRelationship.getPhone() + "&content=" + content + "&extno=" +
smsParam.getExtno() + "&rt=json";
SmsRecord smsRecord = new SmsRecord();
SupectRelationship ispush = new SupectRelationship();
ispush.setIspush("0");
ispush.setId(supectRelationship.getId());
log.info("案件【{}】,手机号:{},短信内容:{}", tyywMessage.getBmsah(), supectRelationship.getPhone(), content);
supectRelationshipMapper.updateById(ispush);
smsRecord.setPhone(supectRelationship.getPhone());
smsRecord.setContent(Base64.encode(content));
smsRecord.setSendtime(LocalDateTime.now());
smsRecord.setMessageid(tyywMessage.getId());
smsRecord.setRelationshipid(supectRelationship.getId());
smsRecord.setIssend("1");
smsRecord.setLcjdbh(tyywMessage.getLcjdbh());
smsRecord.setLxbm(tyywMessage.getAjlx());
smsRecord.setBmsah(caseInfo.getCaseNumber());
smsRecord.setParam(Base64.encode(param));
smsRecordMapper.insert(smsRecord);
TyywMessage tyywMessage1 = new TyywMessage();
tyywMessage1.setId(tyywMessage.getId());
tyywMessage1.setInform("0");
tyywMessageMapper.updateById(tyywMessage1);
SmsRecordHistory smsRecordHistory = new SmsRecordHistory();
smsRecordHistory.setBmsah(caseInfo.getCaseNumber());
smsRecordHistory.setPhone(supectRelationship.getPhone());
smsRecordHistory.setCjsj(LocalDateTime.now());
smsRecordHistory.setZhxgsj(LocalDateTime.now());
smsRecordHistory.setDwbm(caseInfo.getOrgCode());
smsRecordHistory.setDwmc(caseInfo.getOrgName());
smsRecordHistory.setSendtime(LocalDateTime.now());
smsRecordHistory.setRelationshipid(supectRelationship.getId());
smsRecordHistory.setDxnr(content);
smsHistoryService.save(smsRecordHistory);
}
}
}
}
}
}
}
拦截器
配置自定义拦截器,实现HandlerInterceptor接口,重写preHandle 方法。(preHandle中可做token校验)
/**
* 添加拦截器
*/
@Component
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//如果不是映射到方法直接放行
if(!(handler instanceof HandlerMethod)){
return true;
}
HandlerMethod handlerMethod = (HandlerMethod)handler;
Method method = handlerMethod.getMethod();
if (method.isAnnotationPresent(PassToken.class)) { //方法上面是否有注解?
PassToken passToken = method.getAnnotation(PassToken.class);
if (passToken.value()){
return true;
}else {
HashMap<String,String> hashMap = new HashMap<>();
String token = request.getHeader("token");
try {
boolean ver= TokenUtil.verify(token) ;
if (ver){
return true;
}else{
hashMap.put("msg","token无效");
hashMap.put("code","401");
}
}catch (SignatureVerificationException e){
e.printStackTrace();
hashMap.put("msg","签名不一致");
}catch (TokenExpiredException e){
e.printStackTrace();
hashMap.put("msg","令牌过期异常");
}catch (AlgorithmMismatchException e) {
e.printStackTrace();
hashMap.put("msg", "算法不匹配异常");
}catch (InvalidClaimException e){
e.printStackTrace();
hashMap.put("msg","失效的claim异常");
}catch (Exception e){
e.printStackTrace();
hashMap.put("msg","token无效");
hashMap.put("code","401");
}
String resultJson = JSON.toJSONString(hashMap);
response.setContentType("application/json;charset=utf-8");
response.getWriter().print(resultJson);
return false;
}
}
HashMap<String,String> hashMap = new HashMap<>();
String token = request.getHeader("token");
try {
boolean ver= TokenUtil.verify(token);
if (ver){
return true;
}else {
hashMap.put("msg","token无效");
hashMap.put("code","401");
}
}catch (SignatureVerificationException e){
e.printStackTrace();
hashMap.put("msg","签名不一致");
}catch (TokenExpiredException e){
e.printStackTrace();
hashMap.put("msg","令牌过期异常");
}catch (AlgorithmMismatchException e) {
e.printStackTrace();
hashMap.put("msg", "算法不匹配异常");
}catch (InvalidClaimException e){
e.printStackTrace();
hashMap.put("msg","失效的claim异常");
}catch (Exception e){
e.printStackTrace();
hashMap.put("msg","token无效");
hashMap.put("code","401");
}
String resultJson = JSON.toJSONString(hashMap);
response.setContentType("application/json;charset=utf-8");
response.getWriter().print(resultJson);
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
@Configuration
public class TokenWebMvcConfigurer implements WebMvcConfigurer {
@Resource
private JwtInterceptor jwtInterceptor;
/**
* 配置跨域请求
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
//定义哪些URL接受跨域
registry.addMapping("/**")
//定义哪些origin可以跨域请求
.allowedOrigins("*")
//定义接受的跨域请求方法
.allowedMethods("POST", "GET", "PUT", "PATCH", "OPTIONS", "DELETE")
.exposedHeaders("Set-Token")
.allowCredentials(true)
.allowedHeaders("*")
.maxAge(3600);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/user/login")
.excludePathPatterns("/swagger-ui.html")
.excludePathPatterns("/configuration/ui")
.excludePathPatterns("/configuration/security")
.excludePathPatterns("/v2/api-docs")
.excludePathPatterns("/error")
.excludePathPatterns("/webjars/**")
.excludePathPatterns("/**/favicon.ico")
.excludePathPatterns("/doc.html")
.excludePathPatterns("/cbrsms/list")
.excludePathPatterns("/service-worker.js")
.excludePathPatterns("/swagger-resources")
.excludePathPatterns("/swagger-resources/**")
.excludePathPatterns("/doc.html");
}
}
WebMvcConfigurer
配置全局的跨域请求和拦截器
@Configuration
public class TokenWebMvcConfigurer implements WebMvcConfigurer {
@Resource
private JwtInterceptor jwtInterceptor;
/**
* 配置跨域请求
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
//定义哪些URL接受跨域
registry.addMapping("/**")
//定义哪些origin可以跨域请求
.allowedOrigins("*")
//定义接受的跨域请求方法
.allowedMethods("POST", "GET", "PUT", "PATCH", "OPTIONS", "DELETE")
.exposedHeaders("Set-Token")
.allowCredentials(true)
.allowedHeaders("*")
.maxAge(3600);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/user/login")
.excludePathPatterns("/swagger-ui.html")
.excludePathPatterns("/configuration/ui")
.excludePathPatterns("/configuration/security")
.excludePathPatterns("/v2/api-docs")
.excludePathPatterns("/error")
.excludePathPatterns("/webjars/**")
.excludePathPatterns("/**/favicon.ico")
.excludePathPatterns("/doc.html")
.excludePathPatterns("/cbrsms/list")
.excludePathPatterns("/service-worker.js")
.excludePathPatterns("/swagger-resources")
.excludePathPatterns("/swagger-resources/**")
.excludePathPatterns("/doc.html");
}
}
@RestControllerAdvice
全局异常处理器,用于捕获和处理应用程序中发生的各种异常。它使用了Spring框架的@RestControllerAdvice
注解,表示这是一个全局异常处理器,并且将异常信息返回给客户端
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
/**
* 处理自定义的业务异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value = BizException.class)
public Result bizExceptionHandler(HttpServletRequest req, BizException e){
log.error("发生业务异常!原因是:{}",e.getErrorMsg());
return Result.error(e.getErrorCode(),e.getErrorMsg());
}
/**
* 处理空指针的异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value = NullPointerException.class)
public Result exceptionHandler(HttpServletRequest req, NullPointerException e){
log.error("发生空指针异常!原因是:",e);
return Result.error(ExceptionEnum.INTERNAL_SERVER_ERROR);
}
/**
* 处理类型转换异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value = NumberFormatException.class)
public Result exceptionHandler(HttpServletRequest req, NumberFormatException e){
log.error("发生类型转换异常!原因是:",e);
return Result.error(ExceptionEnum.PARAMS_NOT_CONVERT);
}
/**
* 参数格式异常处理
*/
@ExceptionHandler(value = IllegalArgumentException.class)
public Result badRequestException(HttpServletRequest req, IllegalArgumentException ex) {
log.error("参数格式不合法:{}", ex.getMessage());
return Result.error(ExceptionEnum.PARAMS_ILEGAL);
}
/**
* 参数信息不合法
*/
@ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
public Result exceptionHandler(HttpServletRequest req, MethodArgumentTypeMismatchException ex) {
log.error("参数格式不合法:{}", ex.getMessage());
return Result.error(ExceptionEnum.PARAMS_ILEGAL);
}
/**
* 处理其他异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value = Exception.class)
public Result exceptionHandler(HttpServletRequest req, Exception e){
log.error("未知异常!原因是:",e);
return Result.error(ExceptionEnum.INTERNAL_SERVER_ERROR);
}
}
MyBatisPlusConfig
SelectPage用于分页,在Mybatis-Plus中分页有两种:一种是逻辑分页或叫内存分页,另一个是物理分页。内存分页就是把数据全部查询出来放到内容中,返回你想要的一部分数据,当数据量非常庞大时,这种方法就行不通了,因为太耗内容,所以一般采用物理分页,需要SpringMVC中加入物理分页配置:
@Configuration
public class MybatisPlusConfig {
/**
* Map下划线自动转驼峰
*/
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return i -> i.setObjectWrapperFactory(new MybatisMapWrapperFactory());
}
/**
* 分页插件
*
* @return PaginationInterceptor
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
// return new PaginationInterceptor();
PaginationInterceptor page = new PaginationInterceptor();
page.setDbType(DbType.DM);
return page;
}
/**
* 公共字段赋值
*
* @return PaginationInterceptor
*/
@Bean
public MyMetaObjectHandler myMetaObjectHandler() {
return new MyMetaObjectHandler();
}
/**
* 逻辑删除
* https://baomidou.gitee.io/mybatis-plus-doc/#/logic-delete
*
* @return LogicSqlInjector
*/
// @Bean
// public ISqlInjector sqlInjector() {
// return new LogicSqlInjector();
// }
/**
* 乐观锁
* https://baomidou.gitee.io/mybatis-plus-doc/#/optimistic-locker-plugin
*
* @return OptimisticLockerInterceptor
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
/**
* 数据权限插件
*
* @return DataScopeInterceptor
*/
@Bean
public DataScopeInterceptor dataScopeInterceptor() {
return new DataScopeInterceptor();
}
}
#mybatis
mybatis-plus:
mapper-locations: classpath:mapper/**/*.xml
#实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: com.tbo.modules.*.entity
check-config-location: true
configuration:
#是否开启自动驼峰命名规则(camel case)映射
map-underscore-to-camel-case: true
#全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存
cache-enabled: false
call-setters-on-nulls: true
#配置JdbcTypeForNull, oracle数据库必须配置
jdbc-type-for-null: 'null'
#MyBatis 自动映射时未知列或未知属性处理策略 NONE:不做任何处理 (默认值), WARNING:以日志的形式打印相关警告信息, FAILING:当作映射失败处理,并抛出异常和详细信息
# auto-mapping-unknown-column-behavior: warning
# 打印SQL日志
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
banner: false
db-config:
#主键类型 0:"数据库ID自增", 1:"未设置主键类型",2:"用户输入ID (该类型可以通过自己注册自动填充插件进行填充)", 3:"全局唯一ID (idWorker), 4:全局唯一ID (UUID), 5:字符串全局唯一ID (idWorker 的字符串表示)";
id-type: UUID
#字段验证策略 IGNORED:"忽略判断", NOT_NULL:"非NULL判断", NOT_EMPTY:"非空判断", DEFAULT 默认的,一般只用于注解里(1. 在全局里代表 NOT_NULL,2. 在注解里代表 跟随全局)
field-strategy: NOT_EMPTY
#数据库大写下划线转换
capital-mode: true
#逻辑删除值
logic-delete-value: 0
#逻辑未删除值
logic-not-delete-value: 1
public class Query<T> extends LinkedHashMap<String, Object> {
private static final long serialVersionUID = 1L;
/**
* mybatis-plus分页参数
*/
private Page<T> page;
/**
* 当前页码
*/
private int currPage = 1;
/**
* 每页条数
*/
private int limit = 10;
private static final String ASC = "asc";
public Query(Map<String, Object> params) {
String strPage = "page";
String strLimit = "limit";
this.putAll(params);
//分页参数
if (params.get(strPage) != null) {
currPage = Integer.parseInt((String) params.get("page"));
}
if (params.get(strLimit) != null) {
limit = Integer.parseInt((String) params.get("limit"));
}
this.put("offset", (currPage - 1) * limit);
this.put("page", currPage);
this.put("limit", limit);
String sidx = (String) params.get("sidx");
//默认升序
Boolean asc = true;
if (!StringUtils.isNullOrEmpty(params.get(ASC))) {
asc =Boolean.valueOf(params.get("asc").toString());
}
//mybatis-plus分页
this.page = new Page<>(currPage, limit);
//排序
if (StringUtils.isNotBlank(sidx)) {
if (asc) {
this.page.setAsc(sidx);
} else {
this.page.setDesc(sidx);
}
}
}
public Page<T> getPage() {
return page;
}
public int getCurrPage() {
return currPage;
}
public int getLimit() {
return limit;
}
}