在工作中,我們經(jīng)常有這樣的業(yè)務(wù)情況,實(shí)體間通過(guò)id實(shí)現(xiàn)數(shù)據(jù)業(yè)務(wù)上的關(guān)聯(lián),比如訂單和用戶,訂單的創(chuàng)建人id、商品id等,在頁(yè)面查詢時(shí)我們需要將對(duì)應(yīng)的id信息轉(zhuǎn)換成對(duì)應(yīng)的中文描述,比如用戶中文名稱,商品中文名稱等。如果是單條數(shù)據(jù)的展示還好,但是設(shè)計(jì)到列表查詢,如何高效、優(yōu)雅地實(shí)現(xiàn)這個(gè)效果呢?
現(xiàn)在接口返回的數(shù)據(jù)基本都是JSON格式,比如spring中使用了jackson,在controller層對(duì)結(jié)果進(jìn)行json序列化,而我們要做的就是在序列化的過(guò)程中,實(shí)現(xiàn)id的轉(zhuǎn)換
由于需要對(duì)訂單實(shí)體中的創(chuàng)建人id進(jìn)行轉(zhuǎn)換
public interface UserConvert { String USER_CACHE = "USER_CACHE"; String userId(); default ConvertItem getUserConvert(){ if( userId() == null ){ return null; } return new ConvertItem(userId(), USER_CACHE); }}
基于上面UserConvert的處理,基于緩存實(shí)現(xiàn),同時(shí)支持一個(gè)實(shí)體中多個(gè),比如商品名稱、商品分類等
public class UserConvertProvider extends CacheItemConvertAdapter { private static String name = UserConvert.USER_CACHE; public UserConvertProvider() { super(name, User.class); } @Override public boolean support(ConvertItem convertItem) { return convertItem != null && convertItem.getName().equals(name); } @Override public String convert(ConvertItem convertItem) { if( convertItem == null ){ return null; } User user = (User) fromCache(convertItem.getId()); return user != null ? user.getCaption() : null; }}
該實(shí)現(xiàn)依賴緩存,需要優(yōu)先對(duì)需要轉(zhuǎn)換的數(shù)據(jù)進(jìn)行緩存,因此示例中添加了緩存示例
public void init(){ Cache cache = cacheManager.getCache(UserConvert.USER_CACHE); if( cache != null ){ cache.put("u1", new User("u1","Tom")); }}
實(shí)體中需要通過(guò)實(shí)現(xiàn)接口UserConvert,這樣對(duì)多個(gè)數(shù)據(jù)項(xiàng)轉(zhuǎn)換時(shí)可以繼續(xù)擴(kuò)展
public class Order implements UserConvert { private String id; private String name; private LocalDateTime createTime = LocalDateTime.now(); /** * 創(chuàng)建用戶 */ private String creator; @Override public String userId() { return creator; }}
可以看到,在輸出json中,多了一列userConvert,也就是接口中定義的get*方法
{ "id": "1", "name": "測(cè)試訂單", "createTime": "2024-05-08T21:55:51.5747507", "creator": "u1", "userConvert": "Tom"}
上面說(shuō)的,主要實(shí)現(xiàn)基于緩存,在web查詢結(jié)果進(jìn)行json序列化時(shí),依賴于jackson的擴(kuò)展,對(duì)輸出結(jié)果匹配的類型進(jìn)行轉(zhuǎn)換。
@EnableCaching@Configurationpublic class JacksonCustomConfiguration{ @Bean public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer(){ return jacksonObjectMapperBuilder -> configureMapperBuilder(jacksonObjectMapperBuilder); } private void configureMapperBuilder(Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder) { jackson2ObjectMapperBuilder.serializers(convertSerializer()); } @Bean public ItemConvertSerializer convertSerializer(){ return new ItemConvertSerializer(ConvertItem.class); }}
@Getter@Setterpublic class ConvertItem { private String id; private String text; private String name; public ConvertItem() { } public ConvertItem(String id, String name) { this.id = id; this.name = name; }}
public interface ItemConvertAdapter { /** * @param convertItem * @return */ boolean support(ConvertItem convertItem); /** * * @param convertItem * @return */ String convert(ConvertItem convertItem);}
public class ItemConvertSerializer extends StdSerializer<ConvertItem> implements ApplicationContextAware { private List<ItemConvertAdapter> itemConvertAdapters; public ItemConvertSerializer(Class<ConvertItem> t) { super(t); } @Override public void serialize(ConvertItem value, JsonGenerator gen, SerializerProvider provider) throws IOException { String text = ""; if(!CollectionUtils.isEmpty(itemConvertAdapters)){ for (ItemConvertAdapter itemConvertAdapter : itemConvertAdapters) { if( itemConvertAdapter.support(value) ){ text = itemConvertAdapter.convert(value); break; } } } gen.writeString(text); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { Map<String, ItemConvertAdapter> itemConvertAdapterMap = BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ItemConvertAdapter.class, true, false); if( !itemConvertAdapterMap.isEmpty() ){ itemConvertAdapters = new ArrayList<>(itemConvertAdapterMap.values()); itemConvertAdapters.sort(OrderComparator.INSTANCE); } }}
本文鏈接:http://www.www897cc.com/showinfo-26-88739-0.html一招教你解決頁(yè)面中關(guān)聯(lián)id的轉(zhuǎn)換
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com
上一篇: React 中的國(guó)際化優(yōu)秀實(shí)踐
下一篇: 怪不得這么多人學(xué) React!