首页
友链
统计
留言
关于
Search
1
Java生成二维码——基于Google插件
125 阅读
2
Java使用poi-tl动态生成word和pdf
122 阅读
3
网站声明
98 阅读
4
利用Spring的InitializingBean优雅的实现策略模式
88 阅读
5
循环单链表及其实现
82 阅读
默认分类
Java
C语言
数据库技术
Linux
前端
其他
登录
/
注册
Search
标签搜索
C语言
数据结构
Java
Spring
数据库技术
MySQL
Hadoop
MapReduce
大数据
easyExcel
POI
MybatisPlus
AOP
SpringMVC
IDEA
工厂模式
策略模式
设计模式
LiXiangrong
累计撰写
57
篇文章
累计收到
151
条评论
首页
栏目
默认分类
Java
C语言
数据库技术
Linux
前端
其他
页面
友链
统计
留言
关于
搜索到
57
篇与
的结果
2024-01-03
AOP实现防止前端请求重复提交
1.防止重复提交注解package com.risesun.common.core.annotation; import java.lang.annotation.*; /** * @Author LiXiangrong * @Description 防止重复提交注解 * @Date 2023/04/03 9:04:15 **/ @Inherited @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RepeatSubmit { /** * 防重复操作限时标记数值(存储redis限时标记数值) */ String value() default "value" ; /** * 防重复操作过期时间(借助redis实现限时控制) */ long expireSeconds() default 10; }2.AOP实现防止请求重复提交package com.risesun.business.aspect; import cn.hutool.crypto.digest.DigestUtil; import cn.hutool.json.JSONUtil; import com.risesun.common.core.annotation.RepeatSubmit; import com.risesun.common.core.constant.TokenConstants; import lombok.extern.slf4j.Slf4j; 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.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.util.Objects; import java.util.concurrent.TimeUnit; /** * @Author LiXiangrong * @Description AOP实现防止请求重复提交 * @Date 2023/04/03 8:41:04 **/ @Slf4j @Component @Aspect public class NoRepeatSubmitAspect { @Autowired private RedisTemplate redisTemplate; private final String SIGN = "submit duplication"; private final String PREFIX = "PREVENT_DUPLICATION_PREFIX:"; /** * @Author LiXiangrong * @Description 定义切点 * @Date 2023/04/03 8:53:11 * @Return void **/ @Pointcut("@annotation(com.risesun.common.core.annotation.RepeatSubmit)") public void preventDuplication() {} /** * @Author LiXiangrong * @Description 环绕方法 * @Date 2023/04/03 8:52:50 * @Param pjp * @Return java.lang.Object **/ @Around("NoRepeatSubmitAspect.preventDuplication()") public Object around(ProceedingJoinPoint pjp) throws Throwable { // 获取请求信息 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); // 获取执行方法 Method method = ((MethodSignature) pjp.getSignature()).getMethod(); //获取防重复提交注解 RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); // 获取authorization以及方法标记,生成redisKey和redisValue String authorization = request.getHeader(TokenConstants.AUTHENTICATION); String url = request.getRequestURI(); // 通过前缀 + url + token + 函数参数签名 来生成redis上的 key String redisKey = PREFIX.concat(url).concat(authorization).concat(getMethodSign(method, pjp.getArgs())); // 判断redisTemplate是否存在标记,如果没有,则是首次提交该请求,需要把设置标记并且正常返回 if (!redisTemplate.hasKey(redisKey) && Objects.nonNull(annotation)) { // 这个值只是为了标记,不重要 String redisValue = redisKey.concat(annotation.value()).concat(SIGN); // 设置防重复操作的限时标记(前置通知) redisTemplate.opsForValue().set(redisKey, redisValue, annotation.expireSeconds(), TimeUnit.SECONDS); try { // 正常执行方法并返回 ProceedingJoinPoint类型参数可以决定是否执行目标方法, // 环绕通知必须要有返回值,返回值即为目标方法的返回值 return pjp.proceed(); } catch (Throwable throwable) { //确保方法执行异常实时释放限时标记(异常后置通知) redisTemplate.delete(redisKey); throw throwable; } } else { throw new RuntimeException("数据正在处理,请勿重复提交!"); } } /** * @Author LiXiangrong * @Description 获取方法签名生成方法标记,采用数字签名算法SHA1对方法签名字符串加签 * @Date 2023/04/03 8:49:45 * @Param method * @Param args * @Return java.lang.String **/ private String getMethodSign(Method method, Object... args) { StringBuilder sb = new StringBuilder(method.toString()); for (Object arg : args) { sb.append(toString(arg)); } return DigestUtil.sha1Hex(sb.toString()); } /** * @Author LiXiangrong * @Description 对参数重写toString方法,避免空参造成的影响 * @Date 2023/04/03 8:50:58 * @Param arg * @Return java.lang.String **/ private String toString(Object arg) { if (Objects.isNull(arg)) { return "null"; } if (arg instanceof Number) { return arg.toString(); } return JSONUtil.toJsonStr(arg); } }
2024年01月03日
45 阅读
0 评论
0 点赞
2024-01-03
MybatisPlus自动填充字段值
package com.risesun.business.hander; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import com.risesun.common.security.utils.SecurityUtils; import java.util.Date; /** * @Author LiXiangrong * @Description 兼容MybatisPlus自动填充字段值 * @Date 2023/06/01 14:33:37 **/ @Component public class MybatisPlusHandler implements MetaObjectHandler { public static final Logger LOGGER = LoggerFactory.getLogger(MybatisPlusHandler.class); @Override public void insertFill(MetaObject metaObject) { LOGGER.info("MybatisPlusHandler开始自动填充创建时间、创建人属性值..."); this.setFieldValByName("createBy", SecurityUtils.getUsername(),metaObject); this.setFieldValByName("createTime",new Date(),metaObject); } @Override public void updateFill(MetaObject metaObject) { LOGGER.info("MybatisPlusHandler开始自动填充更新时间、更新人属性值..."); this.setFieldValByName("updateBy",SecurityUtils.getUsername(),metaObject); this.setFieldValByName("updateTime",new Date(),metaObject); } }
2024年01月03日
7 阅读
0 评论
0 点赞
2024-01-03
Java常用的时间转换和计算方式
// 获取当前时间的若干种方式 Date time1 = new Date(); Date time2 = Calendar.getInstance().getTime(); LocalDateTime time3 = LocalDateTime.now(); System.out.println(ZoneId.systemDefault()); ZonedDateTime time4 = Instant.now().atZone(ZoneId.systemDefault()); System.out.println(time1); System.out.println(time2); System.out.println(time3); System.out.println(time4); // 时间字符串转Date SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date1 = simpleDateFormat.parse("2023-03-17 08:30:00"); Date date2 = simpleDateFormat.parse("2023-03-17 12:31:00"); // Date转成时间字符串 String format = simpleDateFormat.format(date1); System.out.println(format); // 时间字符串转LocalDateTime DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime parse1 = LocalDateTime.parse("2023-03-17 08:30:00", formatter); LocalDateTime parse2 = LocalDateTime.parse("2023-03-17 12:31:00", formatter); // LocalDateTime转成时间字符串 LocalDateTime localDateTimeNow = LocalDateTime.now(); String format1 = localDateTimeNow.format(formatter); System.out.println(format1); // 比较两个日期相差多少小时,date2 < date1则返回负数 System.out.println(Duration.between(date1.toInstant(), date2.toInstant()).toHours()); // 比较两个日期相差多少分钟,date2 < date1则返回负数 System.out.println(Duration.between(date1.toInstant(), date2.toInstant()).toMinutes()); // 比较两个日期相差多少小时,date2 < date1则返回负数 System.out.println(Duration.between(parse1,parse2).toHours()); System.out.println(ChronoUnit.HOURS.between(parse1, parse2)); System.out.println(date1.before(date2)); // Java常用比较两个时间差有四个类:Period、Duration、ChronoUnit、Until(通常用Period和Duration) // Period类计算只有年、月、日,Duration类计算只有日、时、分、秒、毫秒 // ChronoUnit类计算有年、月、周、日、时、分、秒、毫秒,Until同ChronoUnit类一样 // 某时间距离当天结束还有多久 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime parse1 = LocalDateTime.parse("2023-03-23 16:00:00", formatter); LocalDateTime midnight = parse1.plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0); long seconds = ChronoUnit.MINUTES.between(parse1,midnight); System.out.println(formatter.format(parse1)+"距离当天结束剩余分钟数:" + seconds); // 判断两个时间段是否有交集 // 判断用户正在报名的活动时间段与已经报名的活动时间段是否有交集 if (!oldStartTime.after(newStartTime) && !newEndTime.after(oldEndTime) || !oldStartTime.after(newStartTime) && !newStartTime.after(oldEndTime)) { return AjaxResult.error("你已经报名或正在参加活动!"); }
2024年01月03日
42 阅读
0 评论
0 点赞
2024-01-03
MySQL笔记
1.group_concat函数支持order by内部排序,例如:# 按照id倒序拼接img SELECT GROUP_CONCAT(img ORDER BY id DESC) FROM `thumb_table`;2.Mysql 给查询出的结果集添加自增序号SELECT (@rownum:=@rownum+1) 自增序号别名, 结果集字段 FROM 结果集, (SELECT @rownum:=0) AS 任意别名 SELECT @rownum:=@rownum+1 AS rownum, A.* FROM ( SELECT U.* FROM `users` U ORDER BY U.`id` DESC ) A, (SELECT @rownum:=0) B补充: 如果是在MyBatis中使用上述查询时,变量i的的初始值0,可以使用传参的方式(${})进行设置。3.mysql日期加一天select DATE_ADD('2022-02-24 09:03:36',INTERVAL 1 DAY);4.距离计算函数<select id="selectBtFirmList" parameterType="com.risesun.business.domain.BtFirm" resultMap="BtFirmResult"> select id, dept_id, firm_name, firm_photo, firm_address, credit_code, principal, firm_tel, firm_phone,firm_intro, firm_info, firm_lng, firm_lat, release_status, release_time, order_num, deleted, create_by,create_time, update_by, update_time <if test="firmLng != null and firmLng != '' and firmLat != null and firmLat != ''"> ,round(st_distance_sphere(point(#{firmLng},#{firmLat}), point (firm_lng,firm_lat))/1000,2) distance </if> from bt_firm <where> <if test="firmName != null and firmName != ''"> and firm_name like concat('%', #{firmName}, '%')</if> <if test="releaseStatus != null and releaseStatus != ''"> and release_status = #{releaseStatus}</if> <if test="firmIds != null and firmIds.size > 0"> <foreach collection="firmIds" item="id" open="and id in (" separator="," close=")"> #{id} </foreach> </if> </where> order by order_num ASC, <if test="firmLng != null and firmLng != '' and firmLat != null and firmLat != ''"> distance ASC, </if> update_time DESC </select>5.mysql中查询使用 != 不等于会过滤掉null的情况及其原因分析和解决在写 SQL 条件语句时经常用到 不等于 != 的筛选条件。此时要注意此条件会将字段为 Null 的数据也当做满足不等于的条件而将数据筛选掉。(也就是说会忽略过滤掉为 null 的数据,导致数据不准确)。二、解决方案 要查出第三列只需将 SQL 改为如下语句 即可。SELECT * FROM A WHERE B1 != 1 OR B1 is Null 上面这种方法最通俗,网上也最多,但是我总是感觉效率太低。目前我使用的方法是:SELECT * FROM A WHERE IFNULL(B1,'') != 1<if test="voluntaryType != null and voluntaryType == '0'.toString()"> and IFNULL(voluntary_type,'') != '1'</if> <if test="voluntaryType != null and voluntaryType == '1'.toString()"> and voluntary_type = #{voluntaryType}</if>
2024年01月03日
44 阅读
0 评论
0 点赞
2024-01-03
开放本地MySQL数据库局域网远程访问
1.关闭防火墙(控制面板\系统和安全\Windows Defender 防火墙);2.修改数据库user表字段把本地数据库的mysql数据库的user表User字段为root的Host值由localhost改为%;3.刷新权限:flush privileges;
2024年01月03日
7 阅读
0 评论
0 点赞
1
...
9
10
11
12