2010-08-11 48 views
15

我正在开发一个java webapp,使用jsp/jquery/ejb/jboss。我处于反模式,我想退出

我有一个web表单,使用户能够从数据库中选择100个字段(全部来自不同的不相关的表/对象)的任意组合。然后这些字段通过java servlet输出到excel电子表格。执行的存储过程始终返回所有100个字段。

Web表单在传输对象(TO)中设置100个布尔值以确定是否应该显示数据。然后这个TO被引用以产生电子表格的标题行,并且也针对来自迭代的数据库的每一行。

这一切正常,但它感觉不对。我想不出一个可行的方法,它不会引用100个布尔值(N + 1次)来确定输出电子表格中是否应包含字段。当我说可行时,我的意思是,例如,我不想重写存储过程或创建100个不同的存储过程。

+10

+1对于标题名称 – SethO 2010-08-11 14:53:01

+0

我不清楚你不满意什么。 TO的大小或其用于生成查询的方式? – 2010-08-11 15:40:57

+0

两者都有。 我这样做的方式似乎并不是一个特别优雅或有效的解决方案。 – NimChimpsky 2010-08-11 15:58:16

回答

3

我们的解决方案是在类似的情况下创建一个动态的传输对象。基本上,这是一个Map,而不是一个有许多getter和setter的POJO。

填充和读取此传输对象的代码是简单的迭代。

+0

有趣。那么在这个例子中,关键/价值是什么? 编辑 - 实际上我猜很明显。字段标识符/列名作为键,值将是从数据库返回的数据。 – NimChimpsky 2010-08-11 16:09:38

+1

+1我认为这是一个很好的解决方案。但我不是有100个getter/setter来绘制地图,而是在TO中有一个字段名的枚举类型,而Dictionary 有两个函数bool GetField(FieldEnum e)和void SetField(FieldEnum e,bool b)。 – 2010-08-11 16:30:42

+0

+1在“正常”TO/Bean上选择一个映射通常是一种很好的方法,当你需要很多属性时,将它们分解成不同的对象没有任何逻辑/语义意义。当我有很多参数并且其中一些是可选参数时,我也有时将它用于方法参数。使用枚举字段名称也是一个不错的选择。通常,也可以使用一种方法来封装地图,该方法允许您提供一个默认值,该值在未设置密钥时返回,因此您不需要直接在代码中检查“null”。 – 2010-08-11 18:26:42

0

您可以消除手动领域枚举通过:关于形式负载

  • ,每个可用的电子表格字段,则输出一个布尔控制。可能最好预先添加某种前缀,以免与表单上存在的其他字段发生冲突。

  • 对表单提交,您显示任何包含字段的前缀。

1

而不是使用存储过程,因此您不能在应用程序中动态构建您的选择SQL字符串,然后执行该SQL语句。所以你只需要引用一次布尔值,然后你只返回你需要的列。

0

您必须评估这是否真的更好,但您可以使用一种方法,即使用位数组来存储是否使用这些字段。每个字段将具有对应于单个位的值:

static final FIELD1 = 1; 
static final FIELD2 = 2; 
static final FIELD3 = 4; 
static final FIELD4 = 8; 
static final FIELD5 = 16; 
etc 

选择时,或0时不选择的每个表单字段将具有其比特值的值。在表单提交中,总计字段并提交值。所以如果FIELD1和FIELD3被选中,你会提交一个值5(二进制00101)。

然后你申请一个简单的掩码为每个字段来确定选择哪一个(有没有比场逐场更好的办法?):

boolean field1Selected = sum & FIELD1; 
boolean field2Selected = sum & FIELD2; 
etc 

缺点:有100个字段,你谈论一个非常大的数字!您可能必须使用2位数组。我也不相信这真的会简化你的问题,但也许它确实。

+0

这只是用100个掩码替换100个布尔字段吗?它确实使得TO在内存*中变得更小*,但是OP正试图解决的问题是什么? – 2010-08-11 15:53:24

+0

生成的用于存储位掩码的数字仅适用于java max的整数值范围。我认为。 TO在内存中稍小,但这是我能看到的唯一好处。 最初的问题实际上是寻找一种“比逐场更好的方法”。 – NimChimpsky 2010-08-11 16:07:11