主子表问题

请大家谈谈主子表的保存策略,如:
开一张销售单,其中分单头及明细两部分,新增及删除整张单都好办,最复杂的是修改一张销售单明细部分的问题,明细部分可能同时包括新增,修改,删除三种状态的明细数据,大家提交到后台是如何区分的,以及前台显示及html标签name的命名采用什么方式更利于提交到后台区分?thks.

这个问题 我再做一次 最后回答:

1.在表单中增加一个隐藏域:
[code="java"]

[/code]

2.在新增,修改,删除时,设置隐藏域的值。
[code="java"]
NOCHANGE,//没有改变 0
NEW,//新增 1
MODIFY,//修改 2
DELETE//删除 3
[/code]
[code="java"]

[/code]
当然在隐藏域中可以增加一个自定义属性status。默认值为0 表示 没有变化(NOCHANGE).
在明细的一行发生变化后,改变它的行状态。

3.在用户修改完之后 确认 后提交到 后台。

4.在后台把 明细的每个 行取出来 根据状态 执行相应的增加,修改,删除操作。

明细部分 表体 做一个 隐藏域。也就是一个实体bean状态(status)

[code="java"]
enum status {
NOCHANGE,//没有改变
NEW,//新增
MODIFY,//修改
DELETE//删除
}
[/code]

这样在前台做新怎,修改,删除操作的时候。把bean状态更新
数据传到后台 后根据bean转台 执行相应的逻辑。

[quote]最复杂的是修改一张销售单明细部分的问题,明细部分可能同时包括新增,修改,删除三种状态的明细数据[/quote]

其实映射到表就是一对多的关系。对于你所说的同时新增,修改,删除其实可以不区分。
在页面展示时,可以使用javascrit动态的增加数据输入,也可删除。那么你在提交时,只需要将给用户显示的数据提交就行了,不用管这些数据是新增还是修改。在后台处理的时候,你只需要在保存明细的时候先把该主单的所有明细删除掉,然后在新插入所提交的信息就可以。

至于业页面input标签的name属性,你可以采取区分,比如第一行数据你用name1,第二行数据你用name2就行了。也可以都起相同的哦名字,在后天使用request.getParamters来获取就行,将来将获的数据组形同位置的拿出来就对应数据库的一条信息了。修改的信息是ID不为空,新增的信息是ID为空的(或者hidden成某一个固定的值)。比如:
[code="java"]


后台
String cols = request.getParmenters("col"):
String cos = request.getParameters("co"):

insert into table (col,co) valuse ( cols[0],cos[0])[/code]
类似上面的代码就行了。当然最重要的不是后台怎么处理,而是前台如何动态增加。这个你可以借助javascript实现DOM元素的动态增加。

另外就是通过AJAX技术。没进行一个操作(新增、删除或者更新)就保存一次

这个采用ajax技术不好,或者说不应该采用ajax技术,不能频繁的 对后台数据库进行不必要的操作。 因为 你有明细 在用户编辑完后 确认后才能 提交到后台保存。
有事用户 可能把明细 的一行 删了 但是 他发现 他删错了。这时怎么办?
所以 不能 采用ajax技术来针对每一个明细行。
[code="java"]


[/code]

在明细中 只需要增加这一个隐藏域就可以了。整个表单提交到后台 后 取出每个明细行的状态 ,根据状态去处理。

[quote]
这个方案是有问题的,因为在其它模块后台表中也有引用到销售单明细的Id,如果保存时不分三七二十一,删除了重新插入的话,就会生成新的Id,但其实这部分数据可能并没有作任何修改,会破坏关联表数据的完整性,更是破坏了业务逻辑。
[/quote]

你们的删除都是都是物理删除吗? 不是逻辑删除? 这样比较危险。

[code="java"]
liuqing,你的方案我不是很明白,你是说每行明细加一个隐藏域,操作时再更改这个状态值?如是,你这个有点类似jQuery DataTable插件原理,粗略了解了一下这个插件,它提供这样的一个方法来获取这三种状态的数据集,然后以json格式供提交至后台。
[/code]

兄弟 你理解对了。就是那个意思。
现在我给你举个例子。假设你的明细有三行,这是新增的保存了。

我现在把明细再查出来,我的明细三行在我没有编辑之前,后者其他操作时,他们的状态 都是 没有变化(NOCHANGE)。

我现在想把第二行 删掉 在第二行 我点了第二行的后面的删除按钮,这行先隐藏了。
此时 这行的状态 就是(DELETE).

其他两行 不变 。

这时 我点击保存。 表单提交 到后台。第一行 和 第三行 由于状态是NOCHANGE 所以我都不用去处理,第二行 是DELETE所以我把这行 从数据库中 物理或者逻辑删除 就好了。

整个交互 过程 业务逻辑和逻辑模型就是这样的。

[code="java"]
三种状态
[/code]

忘了 ,还有一句,三种状态是不够的 不能没有NOCHANGE(没有变化)。

兄弟 明白了 吧 累死你哥 我了 ,我去 喝点水了 再说。

[quote]
当然在隐藏域中可以增加一个自定义属性status。默认值为0 表示 没有变化(NOCHANGE).
[/quote]

这句说的有点问题,新增时为1 ,把保存明细查询出来的时候加载到页面时 为0
其他两种状态与用户的编辑事件有关。

[quote]这个方案是有问题的,因为在其它模块后台表中也有引用到销售单明细的Id,如果保存时不分三七二十一,删除了重新插入的话,就会生成新的Id,但其实这部分数据可能并没有作任何修改,会破坏关联表数据的完整性,更是破坏了业务逻辑。[/quote]

你说的是,但是如果是我,我可能不会将明细的ID用到其他地方,而是将在其他的地方用到主表的ID。这个我们可以不讨论,因为每个系统的都有自己个子的特点。

那么其实你的问题还是回到了后台在处理页面传来的没一条数据是实质上说要将进行何种操作进行说明的。当然个人认为其实主要考虑的还是删除的操作,因为新增和更新实质上一样的。

那么是否可以这样考虑。如果不考虑实际的SQL性能问题,那么我刚才见的方式还是可行的,只不过在对待删除数据时,需要做的是在操作前想得到当前所有明细ID,然后跟更新后的ID数组进行比较,新ID数组中没有的及时被删除的。新增和删除的就直接处理就可以了;如果要直接命中,那么其实就是在每条数据提交时,有页面传入其操作代码(新增,还是删除,还是更新)
方法其实还是刚才说到的那样,无非是多了一个隐藏域,用来指定针对该条数据后台的一个具体操作方式。

[quote]那么是否可以这样考虑。如果不考虑实际的SQL性能问题,那么我刚才见的方式还是可行的,只不过在对待删除数据时,需要做的是在操作前想得到当前所有明细ID,然后跟更新后的ID数组进行比较,新ID数组中没有的及时被删除的。新增和删除的就直接处理就可以了;如果要直接命中,那么其实就是在每条数据提交时,有页面传入其操作代码(新增,还是删除,还是更新)[/quote]

更正下

那么是否可以这样考虑。如果不考虑实际的SQL性能问题,那么我刚才建议的方式还是可行的,只不过在对待删除数据时,需要做的是在操作前先得到更新前的所有明细ID,然后跟更新后的ID数组进行比较,新ID数组中没有的即是要被删除的。新增和更新的就直接处理就可以了;
如果要直接命中(也就是后台知道如何处理提交的每一个ID),那么其实就是在每条数据提交时,由页面传入其操作代码(新增,删除,还是更新)方法其实还是刚才说到的那样,无非是多了一个隐藏域,用来指定针对该条数据后台的一个具体操作方式。