首页
友链
统计
留言
关于
Search
1
Java使用poi-tl动态生成word和pdf
744 阅读
2
springboot整合easyExcel导出excel
305 阅读
3
实现MyBatis拦截器自动填充创建、更新时间等字段属性值
288 阅读
4
Java生成二维码——基于Google插件
282 阅读
5
配置Windows11系统环境下MapReduce本地调试样例
278 阅读
默认分类
Java
C语言
数据库技术
Linux
前端
其他
登录
/
注册
Search
标签搜索
C语言
数据结构
Java
Spring
数据库技术
MySQL
工具分享
Hadoop
MapReduce
大数据
easyExcel
POI
MybatisPlus
AOP
SpringMVC
IDEA
工厂模式
策略模式
设计模式
LiXiangrong
累计撰写
58
篇文章
累计收到
10
条评论
首页
栏目
默认分类
Java
C语言
数据库技术
Linux
前端
其他
页面
友链
统计
留言
关于
搜索到
58
篇与
的结果
2024-01-05
顺序表及其实现
#include <stdio.h> #include <stdlib.h> typedef int dataType; #define MAX_SIZE 100 // 2.2.2 顺序表(顺序存储的线性表) typedef struct { dataType a[MAX_SIZE]; int size; }seqList; // 1.顺序表的初始化/置空表 void init(seqList *slt) { slt->size = 0; } // 2.在顺序表尾部追加值为x的元素 void append(seqList *slt,dataType x) { if(slt->size == MAX_SIZE) { printf("顺序表是满的,无法追加!\n"); exit(1); } slt->a[slt->size++] = x; } // 3.判断顺序表是否为空 int empty(seqList slt) { return !slt.size; } // 4.打印顺序表各结点的值 void display(seqList slt) { if(empty(slt)) printf("顺序表是空的!\n"); else { for (int i = 0; i < slt.size; i++) printf("%d ",slt.a[i]); printf("\n"); } } // 5.查找顺序表中值为x的结点位置 int find(seqList slt, dataType x) { int i = 0; while (i < slt.size && slt.a[i] != x) i++; return i < slt.size ? i : -1; } // 6.获取顺序表第i个结点的值 dataType get(seqList slt,int i) { if(i < 1 || slt.size < i) { printf("访问越界!\n"); exit(1); } return slt.a[i-1]; } // 7.在顺序表的position位置插入值为x的结点 void insert(seqList *slt, int position,dataType x) { if(slt->size == MAX_SIZE) { printf("顺序表是满的,无法插入!"); exit(1); } if(position < 0 || position > slt->size) { printf("插入的位置非法,无法插入!"); exit(1); } for (int i = slt->size; i > position; i--) slt->a[i] = slt->a[i-1]; slt->a[position] = x; slt->size+=1; // 或slt->size++; } // 8.删除顺序表第position位置的结点 void del(seqList *slt, int position) { if(empty(*slt)) { printf("顺序表是空的,无法删除!"); exit(1); } if(position < 0 || position >= slt->size) { printf("删除的位置非法,无法删除!\n"); exit(1); } for (int i = position; i < slt->size-1; i++) slt->a[i] = slt->a[i+1]; slt->size-=1; // 或slt->size--; } // 9.中点优先递归遍历顺序表 void listOrder(seqList list, int low, int high) { if(low <= high) { int mid = (low+high)/2; printf("%d ",list.a[mid]); listOrder(list,low,mid-1); listOrder(list,mid+1,high); } } // 10.从键盘输入创建顺序表 void scanCreateList(seqList *list) { printf("请输入整数序列,以9999作为结尾:\n"); dataType x; scanf("%d",&x); while (x != 9999 && list->size < MAX_SIZE) { list->a[list->size++] = x; scanf("%d",&x); } } // 11.把顺序表前后两部分位置对调(0-m,m+1-n变为m+1-n,0-m) void divList(seqList *L, int m) { int i, j, x, last = L->size-1; for (i = 1; i <= m; i++) { x = L->a[0]; for (j = 1; j <= last ; j++) L->a[j-1] = L->a[j]; L->a[last] = x; } } int main() { seqList slt; // 定义顺序表 init(&slt); // 初始化顺序表 display(slt); // 打印顺序表 append(&slt,1); append(&slt,2); // 追加元素 display(slt); printf("%d\n",find(slt,2)); // 按值查找 printf("%d\n",get(slt,2)); // 按位查找 insert(&slt,0,3); // 插入元素 display(slt); listOrder(slt,0,slt.size-1); printf("\n"); seqList L; init(&L); scanCreateList(&L); display(L); divList(&L,4); display(L); return 0; }
2024年01月05日
152 阅读
0 评论
0 点赞
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日
107 阅读
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日
62 阅读
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日
100 阅读
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日
106 阅读
0 评论
0 点赞
1
...
9
10
11
12