数据库为字段为BigInt 类型,实体类中使用Long类型接收 ,导致的 精度丢失的问题
1.具体的出错代码
Mysql数据库代码为:
create table t_item
(
item_id int auto_increment
primary key,
book_id int null,
count int default 0 not null,
create_date timestamp default CURRENT_TIMESTAMP null,
order_id bigint null,
user_Id int null,
status int default 0 not null comment ' 0 未完成 1 已完成',
constraint t_item_ibfk_1
foreign key (book_id) references t_book (BOOK_ID),
constraint t_item_ibfk_2
foreign key (order_id) references t_order (order_id)
)
collate = utf8mb4_general_ci;
create index book_id
on t_item (book_id);
create index order_id
on t_item (order_id);
create table t_order
(
order_id bigint not null
primary key,
total double not null,
status tinyint(1) not null comment '0 未支付 1 已支付',
name varchar(20) not null,
mobile varchar(20) not null,
province varchar(20) not null,
city varchar(30) not null,
district varchar(20) not null,
town varchar(30) not null,
address varchar(50) not null,
create_date date null,
user_id int null,
constraint t_order_ibfk_1
foreign key (user_id) references t_user (user_id)
)
collate = utf8mb4_general_ci;
create index user_id
on t_order (user_id);
这里当生成订单生成的订单id 使用的是mybatisPlus 的自动生成的雪花id ,但是当需要根据前端传来的id来查询订单详情时,首先传来的是Long类型的,精度丢失,这里如果去测试,使用数据库生成的订单号去测试的时候,需要将订单号后面加上"L"只有这样才能正确的查询出数据。 具体的解决方式,配置全局的处理
@Configuration
public class JacksonConfig {
@Bean
public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() {
final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.serializationInclusion(JsonInclude.Include.NON_NULL);
final ObjectMapper objectMapper = builder.build();
SimpleModule simpleModule = new SimpleModule();
// Long 转为 String 防止 js 丢失精度
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
// 忽略 transient 关键词属性
objectMapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
return new MappingJackson2HttpMessageConverter(objectMapper);
}
}
这段配置是springMVc 全局的JsoN 数据处理,例如处理数据丢失的问题。
这里是配置的详细解释:
Serialization Inclusion: JsonInclude.Include.NON_NULL 配置使得只有非空属性会被序列化到 JSON 中,这样可以减少传输的数据量并保持响应的简洁性。
Long to String Serializer: 添加了一个自定义模块 SimpleModule 并注册了一个序列化器 ToStringSerializer.instance 给 Long.class。这意味着所有的 Long 类型在被序列化时会自动转换成字符串形式,这样做可以避免在前端 JavaScript 中因 Number 类型精度问题导致的数字不准确。
Propagate Transient Marker: 通过 objectMapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true) 配置,使得当实体类中的属性被标记为 transient 时,Jackson 在序列化和反序列化过程中会忽略这些属性。这有助于保护敏感信息或不需要参与序列化的数据字段。