- 博客(173)
- 收藏
- 关注
原创 企微侧边栏开发(内部应用内嵌H5)
公司的业务需要用企业微信和客户进行沟通,而客户的个人信息基本都存储在内部CRM系统中,对于销售来说需要一边看企微,一边去内部CRM系统查询,比较麻烦,希望能在企微增加一个侧边栏展示客户的信息,提升销售的工作效率。
2024-03-28 15:24:34 262
原创 IDEA POM文件配置profile实现不同环境切换
在企业级开发中,为了不影响生产环境的项目运行,一般情况下都会划分生产环境、测试环境、开发环境。不同环境可以配置不同的数据库、redis连接,这样在开发新功能的时候就不会影响线上环境。
2024-03-03 16:05:52 556 1
原创 shell脚本编程快速入门
shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。一般是一种.sh文件,通过"sh 文件名"运行shell脚本编程本质上就是将一群shell命令打包到一个文件中去运行.通过打包命令的方式,让用户不需要每次都输入一堆命令来简化使用流程.
2024-01-15 17:15:50 897
原创 Spring事务失效场景之类内部方法调用及解决方案
在日常开发中,经常有需要使用事务来保证数据一致性的情况。简单点的话直接在方法上面加@Transactional注解就可以了。但这样存在一个问题,在整个业务方法层面加注解会把很多并不需要归入事务的操作也归入到了事务里面,这样会可能会出现大事务的情况,影响系统性能。为了提高系统性能,比较好的一种方案是只把操作数据库的部分代码放到一个方法,给这个小方法加上事务,这样基本不会出现大事务的问题。而要实现这种方案,会碰上很常见的一种事务失效的场景。
2024-01-12 18:15:14 651
原创 异步导入中使用SecurityUtils.getSubject().getPrincipal()获取LoginUser对象导致的缓存删除失败问题
但当异步的时候,就没有set用户信息的过程,线程内的用户信息还是上一次进入Controller用该线程的用户的用户信息。也就存在数据对不上的情况。(其实是因为只有一个用户,用来用去都只有一个用户,各个线程里面存的都是该用户,当然获取到的是一致的)因为新实现的导入都是直接用一个key作为判断是否存在正常导入的依据,并且异步之后删除key用的也是通过传参传入的LoginUser,而校验用的是ThreaLocal,自然不会出现这种问题。再去看半个小时内是否有导入,还真有,再细看过期时间和导入时间,居然还对的上。
2023-12-13 17:52:34 1273
原创 关于静态内部类和普通内部类的访问权限问题
能直接访问外部类的静态属性,不能直接访问外部类的成员属性。因为静态内部类可以直接创建对象,而不用先创建外部类对象。因为有外部类对象的情况下不一定创建了内部类对象,所以外部类对象不可以直接访问内部类的属性,而内部类可以直接访问外部类的成员属性和静态属性。先定义一下直接访问:类名.方式访问静态属性不算直接访问,直接用属性名访问才叫直接访问。外部类无法直接访问静态内部类的属性,因为创建了外部类,静态内部类不一定有创建对象。对于那种只对某个类有用的一些类,就没必要创建成外部类,可以创建成内部类。
2023-12-01 18:05:43 74
原创 springboot整合easy-es实现数据的增删改查
ES是基于倒排索引实现的,倒排索引中每条记录都是一个文档(JSON格式),系统会先对字段数据进行分词,然后给词条建立索引,并映射到文档id。在查询的时候根据输入进行分词,然后根据词条走索引查询文档id,再根据文档id查询文档并放入结果集,最后将结果集返回。
2023-11-29 15:51:49 818
原创 表连接连接条件不当导致查询结果变多
首先,课表连接布置作业表,因为课表里面的课节和老师布置作业是一一对应的。综上,需要用课节id和学员id一起作为连接条件去关联表才行,这样才能定位到哪节课哪个人交的作业。一开始我的设计是课表通过课节id和布置作业关联,再接着用课表里面的课节id和作业的课节id关联进行查询。但实际数据比预期要多,因为一个课节会有多个人交作业,但我只关联了课节,这样不同人的作业都会被查出来。联表的时候需要注意联表的连接条件,因为要查询的一般是主表的信息,所以主表的一条记录对应的连接条件一般情况下只会对应连接表的一条记录匹配。
2023-11-13 11:25:08 172
原创 MySQL | 查询接口性能调优、编码方式不一致导致索引失效
2.而且,因为项目使用的是jeecgboot项目,分页在分页查询之后会先查询总数,拿查总数的SQL来验证。索引的类型现在要么是eq_ref,要么是ref,并且能用主键的基本也是用主键,符合预期了。1.本地运行项目,找到相应的查询接口,利用MbBatis Log插件获取到分页查询的SQL,拿到数据库去运行,18秒,好久。8.ud表好像也有点问题,索引类型不太正常,看了一下表结构,发现也是编码问题,顺便也改了(d表也有一样问题,也改了)。6.两个字段的编码方式不一样,尝试把u表的编码方式改成和hr表一致。
2023-11-10 22:03:12 483
原创 浮点数保留指定位数的小数,小数位自动去掉多余的0
通过DecimalFormat.format可以按照指定的格式格式化数据。//在有小数的情况下留一位小数,默认是四舍五入。
2023-11-08 20:34:34 586
原创 关于注解执行优先级、同优先级情况下执行顺序
如果想要自定义注解按照想要的顺序来执行,可以通过在注解实现类里面使用@Order注解来指定优先级。不设置优先级值。会有一个默认值:2147483647,也就是最小优先级。官方说法:相同优先级值的情况下:我在网上查,GPT的回复是按照注解的声明顺序执行。
2023-11-01 11:38:11 851 3
原创 Spring XML使用CASE WHEN处理SELECT字段
在日常开发中,经常会碰到需要导出的情况。而一些枚举值或者状态一般是定义成整型,这个时候需要对数据进行转换,转换成对应的文本再导出。
2023-11-01 10:16:55 788
原创 Java设置日期时间的毫秒数为0
只有在下午的时候才会凸显两者不同,就像注释说的,下午十点的时候,HOUR_OF_DAY的值是22,而HOUR的值是10。虽然说HOUR代表12小时制,但是也是可以给HOUR设置超过12的值的,效果就是在日期基础上加上所设置的小时数。从数据库取出来的Date对象没有毫秒,而直接创建的Date对象有毫秒,毫秒数不一样导致的两个Date对象不相等。发送时需要验证发送短信任务的预计发送时间和生产者传过来的时间是否一致,一致才发送。这样在存储时间的时候,会把毫秒部分截掉,导致和原来创建的Date对象不相等。
2023-11-01 10:08:06 333
原创 @DateTimeFormat和@JsonFormat注解
DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”)注解用于解析请求接口入参。将入参的字符串按照pattern设置的格式来转换成日期时间对象。@JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd HH:mm:ss”)注解用于将日期时间对象解析成指定的字符串格式返回给用户。在日常开发中,有用到时间类型作为查询参数或者查询结果有时间参数的一般都会见过这两个注解。
2023-11-01 09:59:36 373
原创 IDEA XML文件里写SQL比较大小条件
最近开发的时候,有一个需求的查询需要支持范围查询[a,b),并且查询的结果要求查询的范围含头端点不含尾端点。
2023-10-09 21:40:29 825
原创 Java不定参数使用及一些注意情况
第二个,默认类型为String[],相当于css为空,也就是参数数组为空,相当于没有传入元素,没有传入参数也就不会有参数为空,因此为假。第九个,传入一个容量为0的空字符串数组,因为里面没有元素,也就没有元素为空或空串,因此为假。第四个,传入两个null,多个参数情况下,默认类型是String,两个null,因此为真。第一个,相当于传入了一个null放在参数数组里面,有一个元素,并且为null,因此为真。再加一种情况,传入一个容量不为0的空字符串数组,因为数组里面默认填充null,因此为真。
2023-09-07 20:00:00 825
原创 使用spring自带的发布订阅机制来实现消息发布订阅
注意消息类必须要继承ApplicationEvent类才能作为参数发布消息。因为java调用构造函数的机制就是默认会调用父类的构造函数,而ApplicationEvent类只有一个单参数的构造函数,无法自动调用,每个构造函数都需要显式调用父类的构造函数。监听消息类需要实现ApplicationListener接口,并通过泛型传入要监听的消息类,并重写onApplicationEvent方法。spring内的同一个消息可以有多个监听类,一旦监听到消息,监听该消息的全部监听类都会执行。
2023-08-31 22:45:00 436
原创 springboot整合RabbitMQ
在导入依赖,配置完yml文件之后,系统启动就会自动注入一个rabbitmqTemplate。直接将生产者像其他类作为一个属性注入到类中,然后像普通的对象调用方法那样调用即可。利用配置文件配置的参数去构造框架对象注入容器,后续将对象注入到属性中去使用。
2023-08-24 21:00:00 882
原创 jdk8对象列表使用stream流基于某个字段(或某些条件)实现去重
我们看看单参数的比较器方法实现;如下,可以发现内部实际调用效果类似于(a,b)->a.getXXX.conpareTo(b.getXXX)。另外,HashSet不太适合用来做自定义去重,因为HashSet的去重是通过类的equals和hashCode方法实现的。comparing(比较器)定义的就是去重的所使用的字段,可以使用匿名内部类来写更复杂的去重逻辑。结果:(藏三4因为年龄和第一个一样,就被过滤掉了,并且数据也按照age进行了排序,升序)注解掉代码的执行结果:(符合去重逻辑,每个年龄段只有一个人)
2023-08-22 20:30:00 508
原创 spring异步框架使用教程
这种方法的好处是注解可以跨模块使用,因为线程池对象会被注入容器,整个服务共用。这个时候就需要一个公共的线程池。自定义一个全局的线程池,需要异步操作的就调用。正常来说,A类中注入B类对象,B类中再注入A类对象。因此,建议把异步都放在一个专门的异步类里面,这个类的方法只用来实现异步,方法内部再去调用真正的业务逻辑方法。查了一下,好像是因为异步注解的实现用到了动态代理,而一个类内部方法的调用不会走代理,也就没法实现异步。如果一个类里面有两个方法A、B,方法B添加了异步注解,方法A调用方法B,异步不会生效。
2023-08-21 20:45:00 869
原创 springboot异步文件上传获取输入流提示找不到文件java.io.FileNotFoundException
所以想要在异步方法也能读取到上传的文件,可以在开启异步之前就打开一个输入流,然后通过传参的方式将输入流传到异步方法内。在异步方法内使用完毕再释放输入流。开启bebug模式,在文件上传的时候,系统会字段在本地创建一个临时的缓存文件,在接受请求的方法内调用文件对象获取输入流,也是按照这个地址来创建输入流。个人想法:因为当前文件上传的业务逻辑是调用异步方法,然后直接就返回,估计接收请求的方法在返回之前,如果缓存文件没有正在被使用,框架就会将缓存文件删除。看文件的后缀是一个缓存文件,找不到缓存文件,太奇怪了。
2023-08-18 20:30:00 1626 1
原创 springboot引入校验注解
Pattern(regexp = “1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$”) 被注释的元素必须是符合指定的正则表达式。注解参数:message,当不满足校验条件的时候会抛出ConstraintViolationException异常,异常中会包含该message对应的内容----名字不能为空。@Range(min,max) 被注释的元素大小必须在指定的范围内。
2023-08-16 20:00:00 239
原创 spring文件上传失败,无法解析文件对象 class org.springframework.web.multipart.support.
从异常来看,涉及到fastjson 和multipart,似乎是fastjson 无法解析multipart,然后发生了异常;但我的代码并没有使用json,应该是AOP的代码出现了异常,但我找不到AOP代码在哪。这些代码是项目实现的日志注解,我确实在方法加上了该注解,而这个注解一开始的实现没有考虑到多文件的情况,所以没有过滤掉,加上之后就好了。我根据他们的文件名去搜,还真搜到了,好在文件名的部分一样。从下面代码可以看出,只把单文件过滤掉了,但多文件没有过滤掉,于是我在后面加上了之后再测试就可以了。
2023-08-03 16:11:59 1281 3
原创 不小心把测试分支合到个人分支怎么办
本地确实没有了其他其他人的提交,不过存在一个问题,那就是虽然提交里面没有了测试分支的提交,但点击提交的时候会发现本地有一些不属于个人分支的未提交的修改,这些修改会一直保存在你本地。在idea点击回滚,默认使用的是mixed模式,这种模式下,idea会把不属于当前分支的提交撤销掉,但为了保存自己做的修改,非本分支做的修改也会保存在本地。如果遇到冲突,合并时需要二选一的优先选本地的,因为本地就是你想要的最新的。运行了这个命令之后,不但本地的提交没了,本地保存的其他分支提交的文件也没了。
2023-06-28 21:04:20 364
原创 使用hutool实现entity转map、map转entity,以及entity转entity
在项目开发中,entity的数据结构一般用来传参以及结果响应,但是在某些场景下,map可以实现list无法实现的效果。比如:实现根据不同等级的用户,可以看到的数据的数量不一样。等级低的用户看到的某些字段是经过加密的,并且不同等级加密哪些字段是可以配置的。首先,会把数据都查询出来,然后再根据当前用户角色去查询哪些字段需要加密。比如我们知道age要加密,有了字段名age,但是我们怎么让机器也知道呢?这就是问题了。entity结构的数据,除非用反射机制去获取他的字段名,否则根本没法指定他的字段来更改。
2023-06-16 16:01:17 2812
原创 关于分页查询列表查询语句没有执行问题
不知道为啥前端那边传过来的页码是4,这样如果数据量不足以达到4页的时候,查第四页就没有数据。查看mybatis日志,看到只执行了一个count(1)的语句,统计当前查询的结果数量。最近在调试的时候遇到一个问题,一旦查询的数据量少,查询就没有结果。后面查了一下才发现,是页码的问题。
2023-06-08 23:59:25 354
原创 利用ThreadLocal+AOP切面编程实现RPC日志
最近在稍微学了一下ThreadLocal以及它的使用场景,同时也学了一下AOP相关的内容,刚好做个很常见的RPC日志来练练手。主要思想是通过切面来拦截所有的请求,在请求进入切面的时候,可以用ThreadLocal来存储当前请求的线程专属的日志,比如请求的IP,设备号等等。在进入业务代码之后,可以将请求参数打印一部分,最后请求结束的时候再把请求结果存入ThreadLocal,并打印ThreadLocal内存储的日志内容。ThreadLocal的使用贯穿整个请求的过程。
2023-06-07 22:01:32 834
原创 注入mapper类时出现Inspection ‘Autowiring for bean class‘ options警告
这是自动检查插件在警告我们,没有找到对应类型注入的类,进行自动装配 bean 类时可能会出问题。其实这个问题出现是因为项目使用的jeecg框架生成的mapper文件是没有@Mapper注解的,检查插件检测到了之后,就进行了警告。但是呢,其实我们直接不管它项目跑起来也不会有问题。jeecg框架在设计的时候选择了在MybatisPlusConfig文件去使用@MapperScan注解配置路径来进行全局扫描并给符合条件的类加上mapper注解。
2023-06-02 15:35:09 591
原创 ThreadLocal和局部变量的区别
使用例子:定义一个全局的ThreadLocal,每当用户登录的时候,都会在接口校验登录状态成功之后就把当前登录的用户的ID存进去,这样你就可以在任意一个方法内去使用当前用户的ID。ThreadLocal类似于银行,每个人都可以往里面存数据,通过线程来辨别不同的用户,每个线程就相当于ThreadLocal的一个用户。ThreadLocal为线程提供一个线程级别的储物柜,可以往里面存数据,取数据。数据是专属于线程的。而局部变量,也是专属于线程的。这样来看,两者似乎功能上是一样的,也确实是一样的。
2023-05-27 00:27:06 764
原创 redis管道
利用管道技术可以降低频繁调用redis方法的耗时,把多个redis操作一起提交,提升执行速度。也就是适合批量操作redis的时候使用。
2022-12-21 23:30:56 140
原创 nginx
比如:端口8080的项目设置权重为3,8081的项目权重设置为1,那么8080和8081的请求量比大概就是3:1。可以在nginx服务器设置,在请求域名后面加上一个标志路径,把动态接口和静态资源分开放在不同的项目。静态资源放在CDN,可以提高静态资源访问速度;同时也可以降低项目服务器的负担。通过配置文件可以配置不同服务器的权重,这样可以充分利用不同服务器的性能。正向代理是指代理服务器代理客户端,反向代理指代理服务器代理服务端。
2022-11-23 14:32:08 377
原创 mac idea设置堆大小导致idea无法启动
然后搜索发现idea.vmoptions文件在/Users/xxx/Library/Application\ Support/JetBrains/IntelliJIdea2021.3(xxx代表你的用户名)打开finder文件夹->应用程序->idea app->右键->显示包内容->Contents->然后MaxOS->双击shell脚本(idea)修改idea.vmoptions文件,将堆最大和最小设置为同一个值,然后保存,完成。因为老项目比较大,因此想通过修改堆的大小来本地跑项目,方便调试。
2022-10-10 17:55:02 758
原创 聊聊泛型吧
Java的泛型是由编译器在编译时实行的,编译器内部永远把所有类型T视为Object处理,但是,在需要转型的时候,编译器会根据T的类型自动为我们实行安全的强制转型。验证:可以尝试获取带泛型的Class,不同泛型类型情况下,获取到的Class是一样的,说明Class无法携带泛型。在编译的时候其实会把泛型类型进行擦除,使用的都是Object类型,到需要使用的时候再强制类型转换。比如编译器看到的代码,就是带泛型的,而虚拟机看到的代码,就是直接将泛型替换成Object的。使用extends通配符表示可以读,不能写。
2022-10-09 17:49:00 170
原创 ControllerAdvice,ExceptionHandler异常处理优先级
在类的内部,按照ExceptionHandler注解设定的异常的精确度来确定使用哪个,设置的异常越精确,优先级越高。如果类里面没有可以解决的方法,则继续扫描下一个类,一直到找到进行异常处理,或者没有则不处理。给类加上@ControllerAdvice注解,给方法加上@ExceptionHandler(xxxException.class)注解,该方法可以处理接口抛出的xxxException.使用的时候异常尽量设置精确一点,最好使用自定义异常,同一个异常只捕获一次,防止调用异常处理方法调错。
2022-09-28 00:07:37 1157
原创 java8 新特性 stream
Stream.of(数组对象)创建流,如果数组数据类型是基本类型,那么创建的流内部是数组对象(int[ ]),会有问题。我理解中Stream.of()更像是直接把参数作为一个个的对象去创建流(看解释符合我的猜想),不过参数是字符串数组的时候又会拿数组里面的数据去创建流,真是疑惑。在括号内,是一对多的关系,左边是原理的对象,右边是一个新的流。也就是将一个对象转成一个流(流里面可能包含多个对象),最后再将全部流合在一起,形成一个新的流。根据括号内的条件,符合条件的加入返回的流,不符合的就被过滤掉。
2022-09-01 22:11:34 365
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人