【问题标题】:update the nested object within struts2更新 struts2 中的嵌套对象
【发布时间】:2011-03-21 12:23:47
【问题描述】:

使用struts2,它会通过ognl自动在我们的action中创建bean,在我们创建新对象的时候很容易使用,例如在用户注册页面,我们构建一个表单来填写他们的信息,在action中我们得到属性填充的bean,我们可以直接保存(可能需要一些验证),就是这么简单。

但是如何更新数据库中已存在的对象呢?

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

但是我们在action中得到的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是“Task”对象。

在页面中:

<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被持久化到数据库中。

还有一些属性是不能更新的,比如Task的“non_updatedProperty”属性是不能更新的,只能在创建任务时设置。

所以在更新表单中,我没有提供 UI 来更新这个属性,所以如果我们调用:

task_db.setNon_updateProperty(task_struts2.getNon_updateProperty); 

会错过现有的属性,因为

task_struts2.getNon_updateProperty==null; !!!

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

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

如果有更多问题,我仍然可以更新。

【问题讨论】:

    标签: struts2 nested


    【解决方案1】:

    关于有效地将信息从表示层管理的“结构”(一组嵌套的 bean)(可以说,由 Struts2 填充)传输到服务或“数据库”的另一个“结构”的问题水平,建议认真看http://dozer.sourceforge.net

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

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

    【讨论】:

    • 是的,我使用休眠,我上面提到的每个实体都映射到数据库中的一个表。你说创建pojo,如何?任务不能是pojo。它是嵌套类。
    • 关于“不可编辑”属性,您可以使用 将它们传递给表示层,以便将它们返回到 task_struts2 填充结构中。
    • 关于“pojo”,如果task是taskSteps的“组合”,也就是说一个taskStep没有独立的意义,你应该在hibernate中使用一个“cascade=all, delete-orphans”描述 task 和 taskSteps 实体之间关系的映射。然后使用推土机,您可以轻松地从 struts2 创建的任务/taskStep 嵌套实例中创建,并将其与您的休眠 dao 层一起存储。 Hibernate 将计算适当的修改(更新、删除和创建子实体)
    • 是的,我可以得到struts创建的Task对象(这个task对象包含了struts创建的taskSteps),问题是我必须从中复制一些(不是全部)属性任务对象到数据库中的相关对象。无论我使用推土机还是beanutils,我都必须决定应该复制哪个属性,哪个不应该。我只是想知道所有与更新相关的逻辑是否都如此复杂?
    • 总而言之,您需要将 struts2 返回的嵌套结构合并到从数据库中获取的嵌套结构中,但仅对于结构的特定“子集”,您“拾取” " 来自您构建输入页面时的整个嵌套结构。恐怕我对此一无所知,因为我没有看到表示这个子集的标准方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-25
    • 2023-04-03
    • 2016-02-20
    • 2021-12-15
    • 2019-11-02
    • 1970-01-01
    相关资源
    最近更新 更多