1. @JsonSerialize(using = ToStringSerializer.class)
数据传到前端,所有id都变成一样的了,但是在postman显示正常。经过排查发现,js中Number类型最大值(9007199254740992),只有16位,而我们的id是18位的,这就导致后两位都是0,而前边都一样。出现了所有id都相同,那个诡异的bug。
找到原因之后,解决起来就很简单了,只需要在实体类字段上,加上这个注解即可。(每个都加还是比较繁琐,其实可以考虑统一处理...)
2. list.toArray(new String[0]);
转换集合为数组,list.toArray(new String[list.size()]) 还是 list.toArray(new String[0])
jdk6之前,建议预先设置大小。jdk6之后这个方法得到了优化,传入空数组效果更好。
3. mysql 排序操作order by field(字段名,排序值1,排序值2,...)
使用这个操作可以很方便的按照需求排序。例如数据库type,存了123456,现在要按照164523排序,用这个方法直接就可以完成需求。
4. 地理围栏,判断某个坐标是否在一个区域内
package com.example.demo1;
import org.apache.commons.lang3.StringUtils;
import java.awt.*;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class GetGeneralPath {
private GetGeneralPath() {}
// 某地的坐标围栏,可以通过高德地图获取。
private static final String zb = "***";
private static final Map<String,GeneralPath> generalPathMap = new ConcurrentHashMap<>();
public static Boolean IsAt(Point2D.Double point) {
if (point != null) {
if (generalPathMap.get("generalPath") != null) {
GeneralPath path = generalPathMap.get("generalPath");
return path.contains(point);
} else {
GeneralPath path1 = method();
return path1.contains(point);
}
}
return false;
}
private static GeneralPath method() {
// 将区域各顶点的横纵坐标放到一个点集合里面
List<Point2D.Double> pointList = new ArrayList<Point2D.Double>();
String[] split = zb.split(";");
for (String s : split) {
if (StringUtils.isNoneBlank(s)) {
String[] strings = s.split(",");
Point2D.Double point = new Point2D.Double(Double.parseDouble(strings[0]), Double.parseDouble(strings[1]));
pointList.add(point);
}
}
// 返回GeneralPath对象
GeneralPath generalPath = new GeneralPath();
Point2D.Double first = pointList.get(0);
// 通过移动到指定坐标(以双精度指定),将一个点添加到路径中
generalPath.moveTo(first.x, first.y);
pointList.remove(0);
for (Point2D.Double d : pointList) {
// 通过绘制一条从当前坐标到新指定坐标(以双精度指定)的直线,将一个点添加到路径中。
generalPath.lineTo(d.x, d.y);
}
// 将几何多边形封闭
generalPath.lineTo(first.x, first.y);
generalPath.closePath();
// 看看集合里面有没有,如果没有就放进去
generalPathMap.putIfAbsent("generalPath", generalPath);
return generalPath;
}
}
5. 通过类加载器的getResourceAsStream()读取jar包中文件
遇到需要读取jar包中文件的需求,平常方式读不出来,需采用如下方式:
InputStream inputStream = this.getClass.getClassLoader().getResourceAsStream(filepath)
注意:filePath是相对路径 && 项目打成jar包之后路径会变,jar包class,就是/。例如class目录下的yml配置文件,相对路径就是 /application.yml
6. @Param("name”) String name
这是mybatis提供的Dao层注解,作用是用于传递参数,从而与sql中的参数相对应,无需设置parameterType。当然参数太多不要用,看起来很捞
如果不加,就是匿名参数,按照参数顺序引用。可读性低,不推荐使用。
报错:BindingException: Parameter 'gender' not found. Available parameters are [arg1, arg0, param1, param2]
7. Map merge()方法:
hashmap.merge(key, value, remappingFunction)
如果key对应的value不存在,就是put(key,value);
如果key已经存在,就按照remappingFunction重新计算value,例如:oldValue + newValue
举个栗子:采用下面这种方式,可以有效减少冗余代码
list.forEach(type -> {map.merge(type, 1, Integer::sum);});
8. mysql 数字转字符串
SELECT CAST(ID AS CHAR); 将id转成char类型(解决前端16位长度截取)
9. 涉及到敏感信息,一定要小心,涉及到用户隐私信息,不要记录操作日志
10. CPU计算上移
在58到家mysql军规看到的:高并发互联网业务,禁止使用存储过程、视图、触发器、Event
解读:高并发大数据的互联网业务,架构设计思路是“解放数据库的CPU,将计算转移到服务层”,并发量大的情况下,这些功能很可能会将数据库拖死,业务逻辑放到服务层上具备更好的拓展性,能够很轻易地实现“增加机器就能增加性能”。数据库擅长存储,CPU计算还是上移为好。