Java开发遇到的系列问题

发表于
3

突然想到要记录下之前遇到的开发问题,目前只想起这些,后续想起来了再补充

一、分页查询相关

使用分页查询数据时,如果数据结果(比如查询指定状态的数据)会动态变化,则不能使用limit A,B的方式(比如:select * from table_name where status = 1 limit 0,5)。

比如:共有13条数据,1、2、3...13

第一次查询(limit 0,5):1、2、3、4、5

第一次查询结束后,库中第3条数据status从1变成2,此时符合条件的只有12条数据:1、2、4、5、6、7、8、9、10、11、12、13

第二次查询(limit 5,5):7、8、9、10、11

这样就会漏掉第6条数据。

优化方式就是使用不变的值进行排序+where条件限制

比如唯一自增逐渐id:

第一次查询:select * from table_name where id > 0 and status = 1 limit 5,结果返回:1、2、3、4、5

第一次查询结束后,库中第3条数据status从1变成2。

第二次查询时,id使用最后获取的id作为参数:select * from table_name where id > 5 and status = 1 limit 5,结果为:6、7、8、9、10

二、金额计算相关

  1. 金额相关计算逻辑(加减乘除等),不能直接用long(即使单位为分,计算过程也会丢失小数位)、int(同long类型)、float(小数精度丢失,比如:4.999999999这种)、double(同float)等,可以用BigDecimal替代,避免丢失精度。

  2. 使用BigDecimal时,如果需要比较是否相等,不能使用equals()方法,该方法会比较精度(比如2和2.0比较返回false),而是使用compareTo()方法判断返回值是否等于0。

  3. 将小数转换为BigDecimal时,不能直接使用构造函数new BigDecimal(double),而是先将小数转为String(或者直接使用BigDecimal.valueOf())。

三、类型转换相关

  1. 将long类型长数字返回给前端时(JSON序列化),一定要注意序列化为字符串,不能直接返回数字,否则可能会导致精度丢失。

  2. 查询数据库数据时,要注意类型是否匹配,尤其是当表经过数仓二次加工后(比如某个字段平时用的都是bigint类型,但是数仓加工后的字段变成了varchar),这种情况如果代码查询条件中使用的还是Long类型,那么就可能会出现精度丢失的情况(即使数字较小,没有精度丢失,也会导致其他问题,比如索引失效)。需要转换为String再作为条件查询。


0
下一篇 RSSHub + FreshRSS搭建私人RSS订阅