Java开发遇到的系列问题
突然想到要记录下之前遇到的开发问题,目前只想起这些,后续想起来了再补充
一、分页查询相关
使用分页查询数据时,如果数据结果(比如查询指定状态的数据)会动态变化,则不能使用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
。
二、金额计算相关
金额相关计算逻辑(加减乘除等),不能直接用
long
(即使单位为分,计算过程也会丢失小数位)、int
(同long
类型)、float
(小数精度丢失,比如:4.999999999
这种)、double
(同float
)等,可以用BigDecimal
替代,避免丢失精度。使用
BigDecimal
时,如果需要比较是否相等,不能使用equals()
方法,该方法会比较精度(比如2和2.0比较返回false
),而是使用compareTo()
方法判断返回值是否等于0。将小数转换为
BigDecimal
时,不能直接使用构造函数new BigDecimal(double)
,而是先将小数转为String
(或者直接使用BigDecimal.valueOf()
)。
三、类型转换相关
将long类型长数字返回给前端时(JSON序列化),一定要注意序列化为字符串,不能直接返回数字,否则可能会导致精度丢失。
查询数据库数据时,要注意类型是否匹配,尤其是当表经过数仓二次加工后(比如某个字段平时用的都是
bigint
类型,但是数仓加工后的字段变成了varchar
),这种情况如果代码查询条件中使用的还是Long
类型,那么就可能会出现精度丢失的情况(即使数字较小,没有精度丢失,也会导致其他问题,比如索引失效)。需要转换为String
再作为条件查询。
0