栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

给实体类增加属性无须给表增加字段

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

给实体类增加属性无须给表增加字段

目录

1、问题背景

2、解决方案

3、代码示例

3.1 实体类需要继承一个CostBaseEntity基类

3.2 保存实体类自定义字段

3.3 查询实体类自定义字段

3.4 columnNameAndColumnValueMap属性扁平化

3.4.1 如何接收前端自定义字段

3.4.2 如何向前端输出自定义字段

        3.5 对BaseServiceImpl进行装饰

4、总结

4.1 优点

4.2 缺点


1、问题背景

随着系统的运行,由于需求不断的迭代,业务不断的深入,会发现我们当属对一个实体进行表结构设计满足不了当前、未来的需求,经常需要加字段。从技术手段上说,加字段,涉及到以下步骤:

  1. 给实体类Entity增加新属性(预估耗时3分钟)
  2. 给实体类映射文件xml文件增加新字段与新属性的映射关系(预估耗时3分钟)
  3. 给VO类增加新属性(预估耗时3分钟)
  4. 将字段增加的sql脚本向运维登记,有些甚至需要在客户环境进行执行。(流程很长)

     加字段第1、2、3步,虽然耗时不长,但是需要人参与,有人参与就极其容易出现错误,最重要的加字段要走sql变更流程,这个流程非常长,一次sql变更,要涉及运维,测试上线,流程繁琐,
特别是一些经常加字段的表,就显得问题更为突出。

那么除了给表新增加字段,有没有其他方法,可以解决这个问题。当然有,请继续阅读。

2、解决方案

     我们可以将列转行,将表的逻辑列转换为数据行。fk_fkdzb_ext表结构如下:

我们有业务表fk_fkdzb(付款单主表),例如我们要给fkdzb增加两个字段:扣留款金额,散货码头费,则需要在fk_fkdzb_ext表增加两条数据。

    这个称之为“列转行”方案。

      那么如何做到,让业务层实现无感知,让前端无须修改代码即可做到可以自定义字段的增加?
请仔细阅读下面代码示例:

3、代码示例

3.1 实体类需要继承一个CostBaseEntity基类

 

 

3.2 保存实体类自定义字段

3.3 查询实体类自定义字段

3.4 columnNameAndColumnValueMap属性扁平化

       需要在DTO对象上定义一个Map用来接收自定义字段,加@JsonAnySetter注解为了实现扁平化

    @JsonAnySetter
    private Map columnNameAndColumnValueMap= new HashMap<>();

 实际上自定义字段与表中基本字段使用完全一样,前端是无感知的,完全兼容。

3.4.1 如何接收前端自定义字段
{
    "id": "1525DEB4EDCBD001",
    "fkdzbId": "1525DEB4CB4BD003",
    "enterpriseId": "TeddyPandaX",
    "attrKey": "automobileTransportationFee",
    "attrName": "汽运零担费",
    "attrValue": "30",
    " createdTime": "2022-05-10 11:33:57",
    //新增加字段 dockFee
    "dockFee": "20",
    //新增加字段 cashDiscountInterest
    "cashDiscountInterest": "0"
}

3.4.2 如何向前端输出自定义字段
{
    "id": "1525DEB4EDCBD001",
    "fkdzbId": "1525DEB4CB4BD003",
    "enterpriseId": "TeddyPandaX",
    "attrKey": "automobileTransportationFee",
    "attrName": "汽运零担费",
    "attrValue": "30",
    " createdTime": "2022-05-10 11:33:57",
    //新增加字段 dockFee
    "dockFee": "20",
    //新增加字段 cashDiscountInterest
    "cashDiscountInterest": "0"
}

3.5 对BaseServiceImpl进行装饰

     对底层的insert()方法进行装饰重写,如果实体类继承自CostBaseEntity并且自定义字段map不为空,则需要保存自定义属于到表fk_fkd_ext_column表。

 新增加一个方法selectListWithExtColumn(),可以完成查询实体列表并加载其自定义字段信息

  protected List selectListWithExtColumn(Wrapper wrapper) {
        List list = super.selectList(wrapper);
        this.setExtColumns(list);
        return list;
    }

 
    private void setExtColumns(List list) {
        if (ListUtil.isEmpty(list)) {
            return;
        }
        if (!(list.get(0) instanceof CostBaseEntity)) {
            return;
        }

        String tableName = this.getTableName();
        Set rowIdSet = new HashSet<>();
        for (T entity : list) {
            rowIdSet.add(this.getId(entity));
        }
        Multimap rowIdAndFkFkdExtColumnDTOListMap =
            this.fkFkdExtColumnService.listColumnMetadata(tableName, rowIdSet);
        for (T entity : list) {
            String rowId = getId(entity);
            this.setExtColumns(entity, rowIdAndFkFkdExtColumnDTOListMap.get(rowId));
        }

    }

4、总结

     该方案实际上也是有优点,有缺点的,没有一个完美的方案,该方案解决了一些问题,同时也引起了另一些问题。

4.1 优点

     当需要给表加字段时无须对修改表结构了,无须走sql变更流程

4.2 缺点

    表的可读性要差一些,获取一个表的所有字段信息,需要进行连表查询,效率与性能上要差一些

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/876966.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号