更新struts2中的嵌套对象

时间:2011-03-21 12:23:47

标签: struts2 nested

使用struts2,它将通过ognl自动在我们的动作中创建bean,当我们创建一个新对象时很容易使用它,例如,在用户注册页面中,我们构建一个表单用于填充他们的信息,在我们获取属性填充bean的操作中,我们可以直接保存它(可能需要一些验证),它很容易。

但是如何更新db中的现有对象?

我们可以构建一个表单,(预填充可以在页面中更新的属性),当用户进行一些修改时,我们会更新它。

但是我们在操作中获得的bean是由struts2创建的(我们将这个bean称为bean_struts2),我们想要更新的是db(我们称之为bean bean_db)。

现在问题是如何将bean_struts2的修改复制到bean_db?

对于非嵌套对象,我们可以迭代bean_struts2的所有属性,并将其设置为bean_db。

例如:

bean_db.setPassword(bean_struts2.getPassword());
.....

但是当要更新的bean是嵌套对象时,它并不那么容易。

就我而言,这些是实体:

class Task{
    Object non_updatedProperty;
    List<TaskSteps> steps;
    List<User> managers;
    User publisher;
}
class User{
    id,name;
}
class TaskStep{
    id,name;
    List<Operator> operators;
    TaskStepStatus status;
}
enum TaskStepStatus{
    ongoing,completed.
}
class Operator{
    id,name;
}

要更新的bean是“任务”对象。

在页面中:

<s:form action="task_update" namespace="/common" cssStyle="width:95%">
    <s:textfield value="%{task.id}" cssStyle="display:none" name="task.id"></s:textfield>
    <s:textfield value="%{task.publisher.name}" readonly="true" label="Publisher"></s:textfield>
    <s:textfield name="task.name" value="%{task.name}" label="Task Name"/>
    <table>
        <caption align="left">Steps</caption>
        <tr>
            <th>Step Name</th>
            <th>Operators</th>
            <th>Status</th>
            <th>Set order</th>
            <th><span id="addStep" style="cursor:pointer" >Add a step</span></th>
        </tr>
        <s:iterator value="task.steps">
            <tr class="step">
                <td>
                    <s:textfield name="task.steps[0].name" value="%{#this.name}" theme="simple"/>
                    <s:textfield name="task.steps[0].id" value="%{#this.id}" theme="simple" cssStyle="display:none"/>
                </td>
                <td><s:textfield name="task.steps[0].end" value="%{#this.end}" theme="simple"/></td>
                <td>        
                    <s:select list="allOpIndb"  listKey="id" listValue="name" value="%{#this.operator.{id}}"
                        name="task.steps[0].operator.id" multiple="true" theme="simple" id="a">
                    </s:select>
                </td>
                <td>
                    <s:select list="@com.zjswkj.location.entity.TaskStepStatus@values()"  theme="simple" 
                        name="task.steps[0].status" listValue="cnValue" value="%{#this.status}" id="b"/>
                </td>
                <td>
                    <span class="up">up</span>
                    <span class="down">down</span>
                    <span class="del">del</span>
                </td>
                <td></td>
            </tr>
        </s:iterator>
    </table>
</s:form>

通过struts2,我可以得到bean_strtus2(Task),它的id与bean_db相同。 我可以轻松地将其非嵌套属性复制到bean_db。但是它的TaskSteps的属性和TaskSteps的运算符如何呢。

只需使用:

task_db.setTaskSteps(task_struts2.getTaskSteps());??

当然不是,这可能导致一些具有相同名称的新TaskStep持久存在于db。

此外,还有一些属性无法更新,例如,任务的“non_updatedProperty”属性无法更新,只能在创建任务时设置。

因此,在更新表单中,我没有提供用于更新此属性的UI,因此如果我们调用:

task_db.setNon_updateProperty(task_struts2.getNon_updateProperty); 

将错过现有的财产,因为

task_struts2.getNon_updateProperty==null; !!!

我只是想知道是否有一些好的想法来处理这些类型的更新?

我不确定你们是否知道我的意思,但我尽力表达。

如果还有其他问题,我可以继续更新。

1 个答案:

答案 0 :(得分:2)

关于从表示层管理的“结构”(嵌套bean集)中有效传递信息的问题(在这里说,由Struts2填充)到服务中的另一个“结构”或“DB”等级,我建议认真看看http://dozer.sourceforge.net

关于通过表示层将“结构”的值修改从那时传递到DB的问题,它在很大程度上取决于映射数据库表的方式(我想你正在使用某种关系数据库)对象。

例如,当使用Hibernate时,有时可以直接从您的演示文稿bean创建POJO,并告诉hibernate“存储它”; Hibernate将根据传递的结构在表中创建/更新/删除适当的记录。 虽然大多数时候没有银弹,但是从DB内容映射的结构与从表示层映射的结构(例如通过推土机)之间的某种结构比较需要猜测必须添加,修改或删除。