本文仅为个人开发日常笔记,对于他人可能并无意义,故设置权限,不公开了
******************************************************
*************************************************************
***********************************************************
2022-09-30
关于一个定时任务类ScheduledThreadPoolExecutor的使用
可以了解为什么用这个
定时任务ScheduledThreadPoolExecutor的使用详解_峥嵘life的博客-CSDN博客_scheduledthreadpoolexecutor使用
*************************************************************
2022-05-17
maven jar包冲突,如何找到并解决
Maven中关于jar包冲突的2种排查方案及3种解决方式_洒家肉山大魔王的博客-CSDN博客_maven查看jar包冲突
*************************************************************
2022-02-08
nginx 在匹配到路径时候,他的转发路径proxy_pass 加/与不加/ 的区别
*************************************************************
2022-02-07
关于idea - mybatis的日志输出
一般情况下,debug级别下,Slf4jLog 本身会输出
使用了插件后
所以,调节下日志级别即可,插件用不用无所谓。
*************************************************************
2021-11-27
参考 浅析@ResponseBodyAdvice的理解以及实际应用 - 古兰精 - 博客园 https://www.cnblogs.com/goloving/p/15045736.html
@ResponseBodyAdvice的理解
在 Controller 执行 return 之后,在 response 返回给客户端之前,执行的对 response 的一些处理,可以实现对 response 数据的一些统一封装或者加密等操作。
该接口一共有两个方法:
(1)supports —— 判断是否要执行beforeBodyWrite方法,true为执行,false不执行 —— 通过supports方法,我们可以选择哪些类或哪些方法要对response进行处理,其余的则不处理。
(2)beforeBodyWrite —— 对 response 处理的具体执行方法。
如:
*************************************************************
2021-11-21
@MapperScan 与@Mapper
1.1 mybatis 需要为dao接口生产实现类
1.2 如果你对dao接口单纯的挂个@Repository, 是会报找不到bean(也就是没生成bean),必须配合@MapperScan来扫描到,变成bean
1.3 也可以直接给dao接口挂@Mapper,这样就可以被扫描到.但是每个都的挂,不如上面可以统一指定扫描路径
追更: @Repository 这个注解加不加都可以,不影响使用,重要的是Mapper注解
***********************************************************
2021-11-13
关于springboot+maven打包
1. 先把总模块pom文件中打包类型 jar--> pom
2. 其他模块(除启动模块)pom全部删除掉没用的配置,比如maven的打包配置
3. 启动模块留下打包的配置,并加上著启动类的配置
4. 对着总模块点击打包。
5. 然后会发现每个模块都有了jar包,你只需要拿到包含主启动类的模块,
java -jar 运行就行
*********************************************************
2021-09-30
用post方式发送文件
import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients;
public static void postSendFile() throws IOException { CloseableHttpClient httpClient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost("http://118.31.16.208:9182/v2/document/createbyfile"); Map<String, Object> headers = getStringObjectMap(); for (Map.Entry<String, Object> entry : headers.entrySet()) { httpPost.setHeader(entry.getKey(), entry.getValue().toString()); } MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.addTextBody("title", "2021-9-30mch1"); File f = new File("E:\\tempData\\9327968\\FileRecv\\1632897145152.html"); builder.addBinaryBody( "file", new FileInputStream(f), ContentType.APPLICATION_OCTET_STREAM, f.getName() ); HttpEntity multipart = builder.build(); httpPost.setEntity(multipart); CloseableHttpResponse response = httpClient.execute(httpPost); HttpEntity responseEntity = response.getEntity(); InputStream content = responseEntity.getContent(); String s = streamToString(content); System.out.println(s); }
***************************************************************
2021-07-31
今天发现新装的mysql,插入汉字时候会乱码。
第一反应以为tomcat造成的,结果配了没效果。
然后看了看数据库连接也没问题 :
public static final String Jdbc_Local_Url = "jdbc:mysql://192.168.1.20:3306/machao_dianli?useOldAliasMetadataBehavior=true&useUnicode=true&characterEncoding=utf-8";
最后折腾半天,终于发现,新装的mysql 默认是 latin1
你在数据表甚至可以看见的(当然你现在看到的是我改完后,正常的)
好了,修改办法,参考:
**************************************************************
2021-07-30
Spring-boot表单无法以put或delete方式提交的
在配置文件中添加: spring.mvc.hiddenmethod.filter.enabled=true
Spring-boot表单无法以put或delete方式提交的_燕某的博客-CSDN博客
***************************************************************
2021-07-30
关于redis设置密码的若干事项
1. 设置密码 参考redis 安装启动及设置密码<windows> - 孙猴子 - 博客园
设置完后,注意启动时候,要指定配置文件
1.1 window: 建redis-server.exe 的快捷方式, 右键快捷方式属性,在目标后面增加redis.windows.conf, 这里就是关键,你虽然修改了.conf文件,但是exe却没有使用这个conf,所以我们需要手动指定一下exe按照修改后的conf运行,就OK了。
1.2 linux : 我没试 但是 应该是在命令行后加参数
/usr/local/bin/redis-server /etc/redis.conf
1.3 客户端的启动:不能再双击图标了, 需要cmd命令行
redis-cli.exe -h 127.0.0.1 -p 6379 -a 123456(你的密码)
2. 本人项目是与springboot, shiro 集合的框架
主要是改了
@Bean
public RedisManager redisManager() {
RedisManager redisManager = new RedisManager();
redisManager.setHost(redisHost + ":" + redisPort);
redisManager.setPassword(redisPassword);
return redisManager;
}
*************************************************************
关于fastJson一些注意
json
1. 反斜杠 报错, 也就是你json字符串(包含反斜杠) ---》 对象,集合时候,他会报错
最简单解决办法
str.replace("\\", "/");
2. 丢失字段
比如 你原先有5个字段,json字符串---》对象,集合, 就剩下3个了。
解决:是因为它过滤掉了值为null等的字段,
参考
https://blog.csdn.net/github_39557053/article/details/86609985
---------------------------------------------------------
java里url编码解析
因为在jsp中对中文进行了编码的时候用的是UTF-8的编码方式,而在servlet中调用request.getParameter();方法的时候使用服务器指定的编码格式自动解码一次,所以前台编码一次后台解码一次而解码和编码的方式不用所以造成了乱码的出现。
写这个也没啥意思,主要是想表达,明白url方式下,浏览器会以一种特殊规则来编码,主要字母,汉字,以ASCII码 进行编码。详情参考:https://blog.csdn.net/nuanxin_520/article/details/78596817?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-6&spm=1001.2101.3001.424
有时候,你加密一次,系统会再加密一次,然后系统传到后端时候,会自动解密一次,你再解密一次,即可。
---------------------------------------------------
某天,遇到一个比较奇怪的问题。
前端给后端传数据的时候,好像当时是表单post提交
打比方,假如你传个name = "张三,李四"
你会发现后台收到的是一个集合, 里面有2个元素[张三、李四]
有时候也有特效: 当时有个Android开发,传集合,怎么都传不了,改成逗号分割传值,就解决了
**************************************************************
sql注入
这是个项目sql拼接语句 " SELECT * FROM a where name = " + name
尝试看看sql如何注入,
我们想删除表, 拼接了个 name =" ' ' ;delete from a where id =12 " =====》 SELECT * FROM a where name =' ' ;delete from a where id =12;(题外话,以上语句你可以直接执行成功的,在命令行或者navicat 等等)
.......这里还做了大量类似的拼接
现在用的jdbc执行的语句。 发现,貌似每一条语句内只能执行一个,如果像上面,执行完查询,紧接着执行删除,总是失败的,可能是框架就是这样子设计的 。
最后,只能尝试对单条语句进行改造,
拼接个 name =" ' ' or 1=1 " ,
再者 加个 -- ,代表注释后面语句,name =" ' ' or 1=1 -- "
*************************************************************
2021-4-20
阿里手册:事务场景中,抛出异常被 catch 后,如果需要回滚,一定要注意手动回滚事务
刚看到,并不很理解。 后来查阅后,才意识到这句话意思。
在spring框架下,事务注解@Transacitonal 需要满足方法抛出异常了,才能触发。
而异常会分几种:error这个属于系统报错,不需要人为处理;
checked 异常 ,(例如找不见文件之类的,必须手动加上try..canth.等,或者你也可以throws,但是你的上一层还是得try,.处理。否则编译不过)
RuntimeException异常 ,也就是平常开发遇到的几乎所有异常,空指针... 这个系统不会要求你写try...。
绕回来,因为RuntimeException异常会自动 throw,所以也就能触发@Transacitonal,
虽然检查异常也能做到抛出,但大部分时间,你都会try.. , 虽然上图你也可以指定checked 异常 类,但是个人猜测,估计是为了前后统一,干脆就直接定死:RuntimeException异常 才可以回滚
(@Transacitonal 参考
@Transactional 详解_愿我如星君如月 ... 夜夜流光相皎洁 ...-CSDN博客_@transactional
一口气说出 6种@Transactional注解的失效场景 - xulijun137 - 博客园
)
综上所述, @Transacitonal 是spring aop切面的实现,也就是代理。 当你抛出(运行时)异常,就会触发它。
从上面话中可知, 首先,你的可以代理,所以自调用(子类事务)会失效,非public会失效。 其次抛异常,如果被你catch了,自然也不会触发,当然你可以在catch里也抛出个异常触发。
tips: 手动回滚,只需要写这行代码: TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
更多可参考自己文章: 关于注解
**************************************************
2021-4-6
发现了一个可以直接获得request的方法,也即是容器本身RequestContextHolder
在很多地方都可以直接引用,获得的request ,可以用在任意地方
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
*****************************************************************
2021-4-1
1. mvc下错误码406的处理:
1.1 在接口上打上@ResponseBody,未正常但会json,报了406,初步认为是默认没有配置转换json
1.2 xml配置上加上了从其他项目抄来的jackson转换配置bean, 问题来了!!! 点击可以点进去,启动却一直报未定义,找不见
1.3 去网上找攻略,再次重新加入了Jackson单独的jar包,jackson-databind。
1.4 问题解决了,然后关于1.2的那个配置,现在也不报错了。 删掉它,项目也是可以正常返回json。
1.5 结论:个人感觉,可能是这个jackson-databind里面告诉了项目该如何绑定,如何转换,起了一个引导调和作用。
但是想起这个1.2报的错,可能有点让人误导,有时候报的错,并不是就是那种错,其实是其他原因,结果误导你走向另一个方向
攻略 :https://www.jb51.net/article/174072.htm
************************************************************
2019.8.8
1. war 与 jar区别
同一个项目打的
把一个java程序打成jar包 - CSDN博客 https://blog.csdn.net/qq_38571398/article/details/78883623
*************************************************
2019.7.25
功能 1.显示列表页(分页,模糊搜索)
2.增加数据
3.删除数据
一.
1. 插入数据时候报错,长度出错
原先使用的其他方法生成id,长度短
后来改成了uuid 32位 所以报错
最终把数据库 30---32位长度解决问题
2.怎么刷新进入页面就有列表
首先先写个ajax获取数据;
然后 $(document).ready(function(){xxxxx}),xx位置 调用ajax方法
3.删除之后怎么显示列表
删除之后同样调用ajax方法
4.增加之后,出了个问题,(代码如下图)刷新页面太快 导致alert刚一出来 就立马没了
alert("添加成功");
setTimeout("location.reload()","2000");
把刷新放入这个延时方法内,2000ms后刷新
二.
1.常用方法
String 判断空
1.1if (id == null || id.isEmpty()) {
return new Response().failure("参数异常");
}
1.2 isNotEmpty(str)等价于 str != null && str.length > 0。它可以包含空格 下面不可以
isNotBlank(str) 等价于 str != null && str.length > 0 && str.trim().length > 0。
if(StringUtils.isNotBlank(p_name)){
cond += " and p_name like '%"+p_name+"%'";
}
2.一般增删改查方法内,可能要从session中获取一些信息id,name。。。
也常常通过session获取权限
Map userMap = (Map)session.getAttribute(Constants.userMap);
if(userMap==null) {
resMap.put("status", "413");
return resMap;
}
3.
2019.7.29
功能 1.显示列表页(复杂,表里大量字段数字要换成名称,连表查询连了一堆表)
一.
1.数据库datatime类型 去了前台成毫秒数
SQL语句里转换格式:
"DATE_FORMAT(ht.cdate,'%Y-%m-%d %H:%i:%s') cdate, "
2.搜索栏里输入英语字母可以,汉字不行 (后记,get方法才存在该问题,换成post,因为get实在url上传的参数)
ajax传送date时 字段加上双引号
data:{"realname":encodeURI(renyuan),
3.前台get方式过来的数据,乱码
加上这个
data:{"realname":encodeURI(renyuan),
后端 URLDecoder.decode(realname, "utf-8");
二,
1.建议大量sql语句 拆分出共同的 然后组合起来:
String sqlbase = " SELE
sql5 = sqlbase + " and ht.zz_mq_divid =? " + conddivi + orderBy;
这样代码更好看 也可以减少出错
2.有时候也可以自己组建一个视图,从中查询
join (SELECT zz_divi_name,zz_divi_id from zz_mp_meiqi_vote GROUP BY zz_divi_name )ss on ht.zz_mq_divid = ss.zz_divi_id
2019.10.15
配合同事共同开发
1.代码细节出问题,复制过来的细节处没修改,
一句一句,逐行审查代码
2.代码尽可能自己测试完
3.
2019.10.29
SELECT name FROM `hero` GROUP BY sex ORDER BY cdate desc;
1.首先说明order by
不要以为order by 是对--分组--排好序,然后你就能获得时间最大的那行记录的 name
order by 是对最后的结果!!!进行排序。
意味着 是对分完组,挑选完获得name后 ,对各组的name 所对应的cdate 进行排序
2.懂了order by ,你就知道name 并不是他那一组最大的cdate的那一行记录。
而是有规律的随机的一个,依我的测试,每次给的都是id最靠前(最小)的那个。
2019.11.27
1.对上一个10.29的一个总结,如果你一个订单对应好几个修改记录,然后你要拿最新的。
你可以加一个状态字段。比如flag,默认为1,如果你插入 某订单新的修改记录了,就把之前的都变为0
2.
2019.12.9
1. 用自定义uuid(business_key)查询一个任务
Task task = activitiService.findTaskByVariableValue(uniqueId);
底层其实是:
Task task = processEngine.getTaskService().createTaskQuery()
.processVariableValueEquals("objId", value)
.singleResult();
************************************************************************************************
************************************************************************************************
sql优化
2.复合索引的优势:
使用多个字段,查询更高效,所以尽量使用复合索引
mysql的两种索引方法(Innodb和MyISAM默认的索引是Btree索引):
2.1.
HASH(用于对等比较,如"="和" <=>") //<=> 安全的比对 ,用与对null值比较,语义类似is null()
2.2.
BTREE(用于非对等比较,比如范围查询)>,>=,<,<=、BETWEEN、Like
3.应尽量避免在 where 子句中使用!=或<>操作符,以及 null 值判断,以及使用 or 来连接条件,否则将引擎放弃使用索引而进行全表扫描。
4.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引
5.很多时候用 exists 代替 in 是一个好的选择:
select num from a where num in(select num2 from b)
用下面的语句替换:
select num from a where exists(select 1 from b where num2=a.num)
6.
测试结果:
order by的字段不在where条件不在select中???? 有排序操作
order by的字段不在where条件但在select中???? 有排序操作
order by的字段在where条件但不在select中???? 无排序操作
order by的字段在where条件但不在select中(倒序)???? 无排序操作
结论:
当order by 字段出现在where条件中时,才会利用索引而无需排序操作。其他情况,order by不会出现排序操作。
这个结论不仅对order by有效,对其他需要排序的操作也有效。比如group by 、union 、distinct等。
7.并不是所有索引对查询都有效,sql是根据表中数据进行查询优化的,当索引lie(索引字段)有大量重复数据的时候,sql查询可能不会去利用索引。
如一表中字段 sex、male、female 几乎各一半。那么即使在sex上创建了索引对查询效率也起不了多大作用。
并非索引创建越多越好。索引固然可以提高相应的查询效率,但是同样会降低insert以及update的效率。因为在insert或是update的时候有可能会重建索引或是修改索引。
所以索引怎样创建需要慎重考虑,视情况而定。一个表中所以数量最好不要超过6个。若太多,则需要考虑一些不常用的列上创建索引是否有必要。
8.设计表时要注意:
表字段避免null值出现,null值很难查询优化且占用额外的索引空间,推荐默认数字0代替null。
尽量使用INT而非BIGINT,如果非负则加上UNSIGNED(这样数值容量会扩大一倍),当然能使用TINYINT、SMALLINT、MEDIUM_INT更好。
使用枚举或整数代替字符串类型
尽量使用TIMESTAMP而非DATETIME
单表不要有太多字段,建议在20以内
用整型来存IP
9.
对于TIMESTAMP,它把客户端插入的时间从当前时区转化为UTC(世界标准时间)进行存储。查询时,将其又转化为客户端当前时区进行返回。
而对于DATETIME,不做任何改变,基本上是原样输入和输出。
TIMESTAMP和DATETIME除了存储范围和存储方式不一样,没有太大区别。当然,对于跨时区的业务,TIMESTAMP更为合适
可见,使用timestamp来存储日期时间数据不但保证了数据类型的大小同INT类型一样,同时可以显示为日期时间格式,这在给我们使用数据带来了很多的方便。
int类型占用4字节,datetime占用8字节,timestamp占用4字节;
所以强烈建议大家,使用timestamp类型来存储日期数据而不要再使用INT类型
tips:1.使用order by null来取消排序-- 效率提升5%
2. 添加了user_id索引 提升1000倍
**********************************************************************************
-------------------------
**************************************************************************
**************************************************************************