当前位置:首页 > 科技  > 软件

一招教你解决页面中关联id的转换

来源: 责编: 时间:2024-05-17 09:02:59 279观看
导读在工作中,我们经常有这样的业务情况,实体间通过id实现数据业务上的关联,比如订单和用户,订单的创建人id、商品id等,在页面查询时我们需要将对应的id信息转换成对应的中文描述,比如用户中文名称,商品中文名称等。如果是单条数

在工作中,我们经常有这样的业务情况,实体间通过id实现数据业务上的关联,比如订单和用户,订单的创建人id、商品id等,在页面查询时我们需要将对应的id信息转换成对应的中文描述,比如用户中文名称,商品中文名称等。如果是单条数据的展示还好,但是设计到列表查询,如何高效、优雅地实现这个效果呢?2kN28资讯网——每日最新资讯28at.com

现在接口返回的数据基本都是JSON格式,比如spring中使用了jackson,在controller层对结果进行json序列化,而我们要做的就是在序列化的过程中,实现id的转换2kN28资讯网——每日最新资讯28at.com

使用方式

定义实体转换接口

由于需要对订单实体中的创建人id进行转换2kN28资讯网——每日最新资讯28at.com

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的处理,基于缓存实现,同时支持一个实体中多个,比如商品名称、商品分类等2kN28资讯网——每日最新资讯28at.com

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;    }}

需要转换的数据缓存

该实现依赖缓存,需要优先对需要转换的数据进行缓存,因此示例中添加了缓存示例2kN28资讯网——每日最新资讯28at.com

public void init(){    Cache cache = cacheManager.getCache(UserConvert.USER_CACHE);    if( cache != null ){        cache.put("u1", new User("u1","Tom"));    }}

实体定义

实体中需要通过实现接口UserConvert,这样对多个数据项转换时可以继续扩展2kN28资讯网——每日最新资讯28at.com

public class Order implements UserConvert {    private String id;    private String name;    private LocalDateTime createTime = LocalDateTime.now();    /**     * 创建用户     */    private String creator;    @Override    public String userId() {        return creator;    }}

实现效果

可以看到,在输出json中,多了一列userConvert,也就是接口中定义的get*方法2kN28资讯网——每日最新资讯28at.com

{    "id": "1",    "name": "测试订单",    "createTime": "2024-05-08T21:55:51.5747507",    "creator": "u1",    "userConvert": "Tom"}

实现原理

上面说的,主要实现基于缓存,在web查询结果进行json序列化时,依赖于jackson的扩展,对输出结果匹配的类型进行转换。2kN28资讯网——每日最新资讯28at.com

@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);    }}
  1. 在配置文件中基于Jackson2ObjectMapperBuilderCustomizer对jackson进行扩展
  2. 定义ItemConvertSerializer对ConvertItem类型的属性进行处理,该类主要继承于StdSerializer
  3. 在ItemConvertSerializer中基于ConvertItem的name属性来匹配对应的缓存并进行转换
  4. 注意开启spring缓存*@EnableCaching*
  5. 最后基于spring特性,定义*/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports*来实现自动注入配置
  • ConvertItem示例
@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;    }}
  • ItemConvertAdapter扩展适配器,主要于ConvertItem搭配扩展
public interface ItemConvertAdapter {    /**     * @param convertItem     * @return     */    boolean support(ConvertItem convertItem);    /**     *     * @param convertItem     * @return     */    String convert(ConvertItem convertItem);}
  • ItemConvertSerializer示例
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);        }    }}

优缺点

  • 使用了jackson序列化的扩展,如果使用其他序列化工具,需要单独支持。
  • 依赖于数据缓存,一般针对通用数据才有数据转换的需要,比如用户、部门数据等,一般这些数据更适合缓存。

本文链接:http://www.28at.com/showinfo-26-88739-0.html一招教你解决页面中关联id的转换

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: React 中的国际化优秀实践

下一篇: 怪不得这么多人学 React!

标签:
  • 热门焦点
  • K60 Pro官方停产 第三方瞬间涨价

    虽然没有官方宣布,但Redmi的一些高管也已经透露了,Redmi K60 Pro已经停产且不会补货,这一切都是为了即将到来的K60 Ultra铺路,属于厂家的正常操作。但有意思的是该机在停产之后
  • MIX Fold3包装盒泄露 新机本月登场

    小米的全新折叠屏旗舰MIX Fold3将于本月发布,近日该机的真机包装盒在网上泄露。从图上来看,新的MIX Fold3包装盒在外观设计方面延续了之前的方案,变化不大,这也是目前小米旗舰
  • 对标苹果的灵动岛 华为带来实况窗功能

    继苹果的灵动岛之后,华为也在今天正式推出了“实况窗”功能。据今天鸿蒙OS 4.0的现场演示显示,华为的实况窗可以更高效的展现出实时通知,比如锁屏上就能看到外卖、打车、银行
  • 红魔电竞平板评测:大屏幕硬实力

    前言:三年的疫情因为要上网课的原因激活了平板市场,如今网课的时代已经过去,大家的生活都恢复到了正轨,这也就意味着,真正考验平板电脑生存的环境来了。也就是面对着这种残酷的
  • 小米平板5 Pro 12.4简评:多专多能 兼顾影音娱乐的大屏利器

    疫情带来了网课,网课盘活了安卓平板,安卓平板市场虽然中途停滞了几年,但好的一点就是停滞的这几年行业又有了新的发展方向,例如超窄边框、高刷新率、多摄镜头组合等,这就让安卓
  • 天猫精灵Sound Pro体验:智能音箱没有音质?来听听我的

    这几年除了手机作为智能生活终端最主要的核心之外,第二个可以成为中心点的产品是什么?——是智能音箱。 手机在执行命令的时候有两种操作方式,手和智能语音助手,而智能音箱只
  • 一文搞定Java NIO,以及各种奇葩流

    大家好,我是哪吒。很多朋友问我,如何才能学好IO流,对各种流的概念,云里雾里的,不求甚解。用到的时候,现百度,功能虽然实现了,但是为什么用这个?不知道。更别说效率问题了~下次再遇到,
  • 雅柏威士忌多款单品价格大跌,泥煤顶流也不香了?

    来源 | 烈酒商业观察编 | 肖海林今年以来,威士忌市场开始出现了降温迹象,越来越多不断暴涨的网红威士忌也开始悄然回归市场理性。近日,LVMH集团旗下苏格兰威士忌品牌雅柏(Ardbeg
  • 疑似小米14外观设计图曝光:后置相机模组变化不大

    下半年的大幕已经开启,而谁将成为下半年手机圈的主角就成为了大家关注的焦点,其中被传有望拿下新一代骁龙8 Gen3旗舰芯片的小米14系列更是备受大家瞩
Top