月度记录-6月

198 阅读3分钟

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计算还是上移为好。