工具类代码

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;
    }
}









Mybatis-Plus详解_mybatisplus-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值