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
    关注

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

    评论

报告相同问题?

悬赏问题

  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?