SQL语法

Mysql Mysql分页 select * from stu limit m, n; //m = (startPage-1)*pageSize,n = pageSize 第一个参数值m表示起始行,第二个参数表示取多少行(页面大小) mysql从0开始计数行数 Oracle Oralce分页 select * from ( select rownum rn,a.* from table_name a where rownum <= x //结束行,x = startPage*pageSize ) where rn >= y; //起始行,y = (startPage-1)*pageSize+1 创建索引 create index index_name(idx_****) on table table_name(column1_name,column2_name); oracle只查第一条数据 select * from (select * from <table> order by <key> desc) where rownum=1; oracle触发器……

阅读全文

微信开发

微信商户平台-现金红包 微信商户平台-企业付款到零钱 微信公众号开发-授权 接口配置信息修改 例如:编写一个公网接口 http://1b51z57431.51mypc.cn/tokenAuth 点击修改接口配置信息的时候,腾讯会给http://1b51z57431.51mypc.cn/tokenAuth 发送一个get请求,包含参数echostr,此时需要将echostr原路返回,就能够 修改接口配置信成功 @GetMapping(value = "/tokenAuth") public String tokenAuth(HttpServletRequest httpServletRequest){ Map<String, String> param = Request2Map.toMap(httpServletRequest); return param.get("echostr"); } 修改JS安全域名 将http://1b51z57431.51mypc.cn设置为安全域名即可 设置网页帐号-网页授权获取用户基本信息 将1b51z57431.51mypc.cn填入即可 获取授权code 拼装并请求:https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx23007a86f39ac469&redirect_uri=http%3A%2F%2F1b51z57431.51mypc.cn%2Fauthorization&response_type=code&scope=snsapi_base&state=123#wechat_redirect H5平台demo【https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx0d453bb3d089f6f9&redirect_uri=http%3A%2F%2Ffanxx4.natapp1.cc%2Fww_h5_dx%2F%23%2Fard%3Ftoken%3D12345&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect】 微信会回调到:http://1b51z57431.51mypc.cn/authorization?code=001NOmD91cWL6N1S1lF911BoD91NOmDO&state=123 回调会带入授权code 将获取到的授权code生成授权链接 静默授权: https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx23007a86f39ac469&redirect_uri=http%3A%2F%2F1b51z57431.51mypc.cn%2Fauthorization&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect 会得到openid,access_token等参数 非静默授权-用户确认授权:https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx23007a86f39ac469&redirect_uri=http%3A%2F%2F1b51z57431.51mypc.cn%2Fauthorization_userinfo&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect 会得到头像昵称等数据 公众号菜单栏配置 打开https://mp.weixin.qq.com/debug/cgi-bin/apiinfo 接口类型选择-基础支持 设置appid和appsecret获取access_token 选择自定义菜单-自定义菜单创建接口/menue/create填入access_token并填入body为下: { "button":[ { "type":"click", "name":"测试", "key":"V1001_TODAY_MUSIC" }, { "name":"营销服务", "sub_button":[ { "type":"view", "name":"百度", "url":"http://www.……

阅读全文

全局异常处理

通过RestControllerAdvice和ExceptionHandler实现全局异常捕获 起因: 我么希望通过全局统一的异常处理将自定义错误码以json的形式发送给前端。 步骤: 1.定义一个统一结果返回类BaseRspVo import com.shizhongcai.business.common.domain.enums.ErrorCodesEnum; import com.shizhongcai.business.common.exception.BaseException; import lombok.Data; @Data public class BaseRspVo<T> { private boolean success; private String msg; private Integer errorCode; private T data; public BaseRspVo() { } public BaseRspVo (T data){ this.success = true; this.msg= ErrorCodesEnum.SUCCESS.getMsg(); this.errorCode = ErrorCodesEnum.SUCCESS.getCode(); this.data = data; } public BaseRspVo (boolean success, String msg, int errorCode) { this.success = success; this.msg = msg; this.errorCode = errorCode; } public BaseRspVo (boolean success, String msg, int errorCode, T data) { this(success,msg,errorCode); this.……

阅读全文

Caffeine Cache接入

Caffeine Cache接入 Caffeine Cache,目前最快的Java内存框架,堆内存。 接入方式: 1.引入pom文件 <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> 2.编写CaffeineConfig并注入CacheManager import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.caffeine.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.github.benmanes.caffeine.cache.Caffeine; import java.util.concurrent.TimeUnit; @Configuration @EnableCaching public class CaffeineConfig extends CachingConfigurerSupport { @Bean public CacheManager caffeineCacheManager() { CaffeineCacheManager cacheManager = new CaffeineCacheManager(); //定制化缓存Cache cacheManager.setCaffeine(Caffeine.newBuilder() .expireAfterWrite(3, TimeUnit.MINUTES) .initialCapacity(100) .maximumSize(10000)) ; return cacheManager; } } 3.通过注解使用 @Cacheable(cacheNames = "cache name", key = "#patam1+'-'+#param2") public void test(String param1,String param2){ } ……

阅读全文

Filter和Interceptor

#Filter - Filter是javax.servlet包中定义的接口,任何实现Filter接口的类都能称为过滤器。 - 主要用途:字符过滤集、控制权限、防止跨站脚本攻击(XSS)等等。 - 实现: 1. 如果是传统项目,需要在web.xml中配置filter <filter> <description>字符集过滤器</description> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <description>字符集编码</description> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 2. 如果是springBoot项目,可以在定义好自己的filter类之后,需要使用filterRegisterationBean将filter进行注入。 public class MDCFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { } } @Bean public FilterRegistrationBean mdcFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.……

阅读全文

JSR-303参数校验

JSR-303参数校验 步骤 1.创建校验参数类 import lombok.Data; import org.hibernate.validator.constraints.Range; import org.springframework.format.annotation.DateTimeFormat; import javax.validation.constraints.*; import java.util.Date; /** * 参数验证请求参数 * @Author shizhongcai * @Date 2019/11/20 15:35 */ @Data public class ValidatorReqVo{ @NotNull(message = "id不能为空") private Integer id; @NotNull @Future(message = "格式为yyyy-MM-dd,且为将来时间") @DateTimeFormat(pattern = "yyyy-MM-dd") private Date future; @NotNull @DecimalMin(value = "0.1") @DecimalMax(value = "1000") private Double doubleValue; @NotNull @Min(value = 1) @Max(value = 10) private Integer intValue; @NotNull @Range(min = 1,max = 10,message = "最小为1,最大为10") private Integer range; @NotBlank @Email private String email; @NotBlank @Size(min = 10,max = 20,message = "字符串长度在10-20之间") private String strSize; } 2.……

阅读全文

Redis缓存

1.Redis简单介绍 语言开发的内存数据库,除了做KV缓存外还能做分布式锁、延时队列、定时任务等等 2.缓存读写模式/更新策略/处理流程 Cache Aside Pattern(旁路缓存模式) Read/Write Through Pattern(读写穿透) Write Behind Pattern(异步缓存写入) 3.为什么要用 Redis/为什么要用缓存? 简单来说使用缓存主要是为了提高接口响应速度,提升用户体验以及应对更多的用户。 高性能:对于高频数据并且不会经常改变的数据,保证下一次用户访问的数据直接从缓存中读取。 高并发:数据库的 QPS 大概都在 1w 左右(4 核 8g) ,但是使用 Redis 缓存之后很容易达到 10w+, > QPS(Query Per Second):服务器每秒可以执行的查询次数; 4.Redis 常见数据结构以及使用场景分析 4.1 String 普通操作: 127.0.0.1:6379> set key value #设置 key-value 类型的值 OK 127.0.0.1:6379> get key # 根据 key 获得对应的 value "value" 127.0.0.1:6379> exists key # 判断某个 key 是否存在 (integer) 1 127.……

阅读全文

其他

其他一些日常工作中遇到的问题: 其他 1.如果需要在sit环境引入多个配置文件,比如application.yml何application-common.yml,只需要在application.yml中加入spring.profiles.include = common即可。 2.@Scope默认是单例模式,即scope=“singleton”。 另外scope还有prototype、request、session、global session作用域。scope=“prototype”多例 3.@Aspect执行顺序问题 Aspect先执行是随机的,如果需要定义顺序,可以使用@Order注解修饰Aspect类。值越小,优先级越高。 4.获取配置文件中的值 4.1属性获取配置文件的值@Value(“${属性名}”) 4.2将配置文件的属性赋给实体类@ConfigurationProperties(prefix = “my”) 5. ……

阅读全文

基于自定义注解的参数解析器

基于自定义注解的参数解析器 背景 在工作中,常会对接一些第三方应用,通常第三方会采用Rsa+Aes加密来通信,但是每个第三方的加密方式可能不一致。此时得好好规划一下实现方案了。因此我们采用注解+Spring自带了参数解析类,实现自己的参数解析器。 原理 通过HandlerMethodArgumentResolver实现自定义参数解析 实现 步骤1:创建注解,例如创建一个解析Aes加密的注解AesJson import java.lang.annotation.*; @Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AesJson { } 步骤2:创建加密参数实体类对象 传入的JSON数据格式为{“data”:“xxxxxxxxxx”} import lombok.Data; @Data public class AesBaseParams { private String data; } 步骤3:新建AesArgumentResolver类实现HandlerMethodArgumentResolver import com.alibaba.fastjson.JSON; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.MethodParameter; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; import javax.servlet.http.HttpServletRequest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URLDecoder; import java.util.HashMap; import java.util.Map; import java.util.Objects; /** * aes加密算法加密的入参,通过@AesJson注解自动解析 */ public class AesArgumentResolver implements HandlerMethodArgumentResolver { private static final Logger logger = LoggerFactory.……

阅读全文

接口限流-令牌桶限流

guava之令牌桶算法实现接口限流 实现步骤 1.创建注解RateLimit import java.lang.annotation.*; /** * 自定义注解:限流令牌桶注解,用以创建令牌桶以及设定令牌桶大小 */ @Inherited @Documented @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RateLimit { double limitNum() default 20; //默认每秒放入桶中20 } 2.创建令牌桶切面RateLimitAspect import com.google.common.util.concurrent.RateLimiter; import com.shizhongcai.business.common.annotation.RateLimit; import com.shizhongcai.business.common.domain.enums.ErrorCodesEnum; import com.shizhongcai.business.common.exception.BaseException; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import java.lang.reflect.Method; import java.util.concurrent.ConcurrentHashMap; /** * 令牌桶切面,桶中无令牌进行服务降级 * */ @Component @Scope @Aspect public class RateLimitAspect { //用来存放不同接口的RateLimiter令牌桶(key为接口名称,value为RateLimiter) //ConcurrentHashMap线程安全 private ConcurrentHashMap<String, RateLimiter> map = new ConcurrentHashMap<>(); //令牌桶 private RateLimiter rateLimiter; @Pointcut("@annotation(com.……

阅读全文