mybatis-plus IdWorker生成的Id和返回給前臺的不一致的解決
問題描述
今天在公司項目中修改id的生成策略為mybatis-plus自帶的IdWorker策略時,發現返回給前臺的id竟然和數據庫不一致。費解得很吶。
package net.mshome.twisted.tmall.entity; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; import java.time.LocalDateTime; /** * 數據庫實體類的父類,必需字段 * * @author [email protected] * @date 2019/9/6 */ @Data @NoArgsConstructor @AllArgsConstructor public class BaseEntity implements Serializable { private static final long serialVersionUID = 236424297319280526L; /** * 數據表主鍵,此處采用mybatis-plus自帶的IdType.ID_WORKER策略 */ @TableId(value = "id", type = IdType.ID_WORKER) protected Long id; /** * 數據創建時間 */ @TableField(fill = FieldFill.INSERT) protected LocalDateTime createTime; /** * 數據更新時間 */ @TableField(fill = FieldFill.INSERT_UPDATE) protected LocalDateTime updateTime; }
- @TableId(value = “id”, type = IdType.ID_WORKER)表示通過mybatis-plus自帶的優化版本的SnowFlake算法生成主鍵。
- 關於主鍵生成方式,可以看看這個類 com.baomidou.mybatisplus.core.toolkit.IdWorker
問題原因
mybatis-plus的ID_WORKER策略會生成一個Long型的很長長長長的數字,這個數字傳到前臺之後,超過瞭js中數字的最大范圍,具體表現為最後兩位始終為 0。
解決辦法
很容易想到,超過瞭js數字最大范圍,那直接轉成String類型就完瞭。
方案一(適合BaseEntity方式)
package net.mshome.twisted.tmall.entity; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; import java.time.LocalDateTime; /** * 數據庫實體類的父類,必需字段 * * @author [email protected] * @date 2019/9/6 */ @Data @NoArgsConstructor @AllArgsConstructor public class BaseEntity implements Serializable { private static final long serialVersionUID = 236424297319280522L; /** * 數據表主鍵 */ @TableId(value = "id", type = IdType.ID_WORKER) @JsonSerialize(using = ToStringSerializer.class) protected Long id; /** * 數據創建時間 */ @TableField(fill = FieldFill.INSERT) protected LocalDateTime createTime; /** * 數據更新時間 */ @TableField(fill = FieldFill.INSERT_UPDATE) protected LocalDateTime updateTime; }
添加 @JsonSerialize(using = ToStringSerializer.class)將結果轉換成String。
此方案適合有baseEntity的時候,避免每個entity都要單獨維護,很麻煩。
方案二(全局處理-兩種方式)
package net.mshome.twisted.tmall.configuration; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; /** * 系統通用簡單配置 * * @author [email protected] * @date 2019/10/16 */ @Configuration public class TmallConfiguration { /** * 方式一:此方式可以靈活配置任意類型的序列化反序列化 */ @Bean public Jackson2ObjectMapperBuilderCustomizer builderCustomizer() { DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); DateTimeFormatter dateTimeSerializeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); DateTimeFormatter dateTimeDeserializeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); return builder -> { // 所有Long類型轉換成String到前臺 builder.serializerByType(Long.class, ToStringSerializer.instance); builder.serializerByType(LocalDate.class, new LocalDateSerializer(dateFormatter)); builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeSerializeFormatter)); builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeDeserializeFormatter)); }; } /** * * 方式二:采用objectMapper註入 */ @Bean public ObjectMapper objectMapper (Jackson2ObjectMapperBuilder builder) { ObjectMapper objectMapper = builder.createXmlMapper(false).build(); SimpleModule simpleModule = new SimpleModule(); // 直接將所有的Long類型轉換為String simpleModule.addSerializer(Long.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); objectMapper.registerModule(simpleModule); return objectMapper; } }
直接將所有的Long類型轉換為String給前臺展示。後臺用Long接收前臺傳入的數字String也可以的,Spring會自動給我們轉換。
到此這篇關於mybatis-plus IdWorker生成的Id和返回給前臺的不一致的解決的文章就介紹到這瞭,更多相關mybatis-plus IdWorker生成Id內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- java Long類型轉為json後數據損失精度的處理方式
- SpringBoot雪花算法主鍵ID傳到前端後精度丟失問題的解決
- SpringBoot主鍵ID傳到前端後精度丟失的問題解決
- SpringBoot全局配置long轉String丟失精度的問題解決
- Mybatis-Plus自動填充更新操作相關字段的實現