acme_lin 2017-03-24 03:00 采纳率: 0%
浏览 854

反范式数据表与实体类设计问题

商品有多张商品图片,一对多关系。

项目中采用单表设计,沿用太久,原因就不追溯了,也没有动改它结构的念头。

忽略其它字段,product表包含img1Path、img2Path、img3Path……img10Path,对应的product实体类也包含这10个成员变量。(path即图片链接,字符串)

目前img1Path到img10Path都可能为空,需要遍历;也没有采用数据传输对象,用map返回。

所以页面需要带一张图片的商品时,原本业务代码大概如下:

Product p = productService.get(productId);
Map<String, Object> pMap = new HashMap<String, Object>();
pMap.put("name", p.getName());
// ……其它字段
pMap.put("imgPath", p.getImg1Path() != null ? p.getImg1Path() :
         p.getImg2Path() != null ? p.getImg2Path() :
            p.getImg3Path() != null ? p.getImg3Path() :
               p.getImg4Path() != null ? p.getImg4Path() :
                  p.getImg5Path() != null ? p.getImg5Path() :
                     p.getImg6Path() != null ? p.getImg6Path() :
                        p.getImg7Path() != null ? p.getImg7Path() :
                           p.getImg8Path() != null ? p.getImg8Path() :
                              p.getImg9Path() != null ? p.getImg9Path() :
                                 p.getImg10Path() != null ? p.getImg10Path() :  null);

这样复用性差,我把抽取getImgPath(Product product)方法到service层:

public String getImgPath(p) {
    return p.getImg1Path() != null ? p.getImg1Path() :
         p.getImg2Path() != null ? p.getImg2Path() :
            p.getImg3Path() != null ? p.getImg3Path() :
               p.getImg4Path() != null ? p.getImg4Path() :
                  p.getImg5Path() != null ? p.getImg5Path() :
                     p.getImg6Path() != null ? p.getImg6Path() :
                        p.getImg7Path() != null ? p.getImg7Path() :
                           p.getImg8Path() != null ? p.getImg8Path() :
                              p.getImg9Path() != null ? p.getImg9Path() :
                                 p.getImg10Path() != null ? p.getImg10Path() :  null;
}

上面的业务代码可以改写为:

Product p = productService.get(productId);
Map<String, Object> pMap = new HashMap<String, Object>();
pMap.put("name", p.getName());
// ……其它字段
pMap.put("imgPath", productService.getImgPath(p));

有些字段字段通过实体类的方法获取,有些通过业务层的方法获取,不优雅。


其实能不能这样做,在product实体类中增加一个成员变量imgPath(数据表没有与之对应的imgPath字段)。

该成员变量无set方法,有get方法,如下:

public class Product {
    private String img1Path;
    // ……
    private String img10Path;
    private String imgPath;
    public String getImgPath() {
        this.imgPath = this.img1Path != null ? this.img1Path :
            this.i2Path != null ? this.img2Path :
                this.img3Path != null ? this.img3Path :
                   this.img4Path != null ? this.img4Path :
                      this.img5Path != null ? this.img5Path :
                         this.img6Path != null ? this.img6Path :
                            this.img7Path != null ? this.img7Path :
                               this.img8Path != null ? this.img8Path :
                                  this.img9Path != null ? this.img9Path :
                                     this.img10Path != null ? this.img10Path :  null;
        return this.imgPath;
    }
}

上面的业务代码可以改写为:

Product p = productService.get(productId);
Map<String, Object> pMap = new HashMap<String, Object>();
pMap.put("name", p.getName());
// ……其它字段
pMap.put("imgPath", p.getImgPath());

甚至这个pMap也不封装了,直接返回p对象,模板引擎通过p.imgPath获取这个一个图片路径(突然想到,自己先去试一下)。

实体类这样写,是否更方便、合理?




验证了一下上面突如其来的猜想,结果如下:
public class Product {
    private String img1Path;
    // ……
    private String img10Path;
    public String getImgPath() {
        return this.img1Path != null ? this.img1Path :
            this.i2Path != null ? this.img2Path :
                this.img3Path != null ? this.img3Path :
                   this.img4Path != null ? this.img4Path :
                      this.img5Path != null ? this.img5Path :
                         this.img6Path != null ? this.img6Path :
                            this.img7Path != null ? this.img7Path :
                               this.img8Path != null ? this.img8Path :
                                  this.img9Path != null ? this.img9Path :
                                     this.img10Path != null ? this.img10Path :  null;
    }
}

即不需要添加字段,可以直接添加一个get方法,方法名与本来想添加的字段字段名一致。

例如字段为:xxXxx,则添加的方法为:getXxXxx()。

后台把product放到json里返回到js(项目用的是AvalonJS 1.5),js可以通过product.xxXxx直接拿到数据。这跟之前用过的freemarker类似,.xxXxx取值调用的是getXxXxx()方法。

  • 写回答

2条回答 默认 最新

  • p0程序员 2017-03-24 03:28
    关注

    完全可以呀,这个只是只涉及实体内部属性而已

    评论

报告相同问题?

悬赏问题

  • ¥15 opencv 无法读取视频
  • ¥15 用matlab 实现通信仿真
  • ¥15 按键修改电子时钟,C51单片机
  • ¥60 Java中实现如何实现张量类,并用于图像处理(不运用其他科学计算库和图像处理库))
  • ¥20 5037端口被adb自己占了
  • ¥15 python:excel数据写入多个对应word文档
  • ¥60 全一数分解素因子和素数循环节位数
  • ¥15 ffmpeg如何安装到虚拟环境
  • ¥188 寻找能做王者评分提取的
  • ¥15 matlab用simulink求解一个二阶微分方程,要求截图