我应该在Struts2视图层中检索数据库记录吗? [英] Should I retrieve database record in Struts2 view layer?

查看:114
本文介绍了我应该在Struts2视图层中检索数据库记录吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个编辑页面,我想从数据库中检索主题级别,并显示为选项,供用户编辑课程

I have a edit page in which I want to retrieve the subjects and levels from database and display as select option for user to edit the course.

提交表单时,它会发出新请求,用户输入由 courseBean 捕获并进行XML验证。当XML验证失败时,它会转发 courseBean ,它只是将用户输入捕获到 edit.jsp

When the form is submitted, it will make a new request , the user input is captured by courseBean with XML validation. When the XML validation failed, it will forward with the courseBean which just captured the user input to the edit.jsp.

所以每一个我去 edit.jsp 时,我会检索数据库记录。我应该这样做吗?

So every time I go the edit.jsp, I will retrieve the database records. Should I do it in that way?

此外,我试图检索主题点亮级别点亮,将它们存储为动作类中的请求属性,该动作类在第一次显示 edit.jsp 。但是,当新请求来自用户输入时,从数据库中检索到的主题列表级别列表将不再可用。

Besides, I tried to retrieve the subject lit and level lit and store them as the request attribute in the action class which displays edit.jsp at the first time. But when the new request is made from the user input, the subject list and level list retrieved from the database will be no longer available.

代码(edit.jsp):

codes (edit.jsp) :

<%
    Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
    Transaction tx = session2.beginTransaction();
    Query q = session2.createQuery("from Subject");
    List subjectList = q.list();
    List levelList = session2.createQuery("from Level").list();
%>

<div class="control-group">
    <label class="control-label" for="inputPassword">Subject</label>
    <div class="controls">
        <select name="subject_id">
            <%
                for (Object subjectObject : subjectList) {
                    Subject subject = (Subject) subjectObject;
            %>
            <option value="<%=subject.getId()%>"><%=subject.getName()%></option>
            <%  } //end for %>
        </select>
    </div>
</div>

<div class="control-group">
    <label class="control-label" for="inputPassword">Level</label>
    <div class="controls">
        <select name="level_id">
            <%
                for (Object levelObject : levelList) {
                    Level level = (Level) levelObject;
            %>
            <option value="<%=level.getId()%>"><%=level.getName()%></option>
            <%  } //end for %>
        </select>
    </div>
</div>


推荐答案

使用Struts2你将不再需要使用 Scriptlet s(<%stuff%> )。它们是旧的,坏的,它们是在视图页面中注入的业务逻辑,不使用它们。你也不需要JSTL,只需使用Struts2标签即可获得任何结果。

Using Struts2 you won't need to use Scriptlets (<% stuff %>) anymore. They're old, bad, they're business logic injected in view pages, do not use them. You do not need JSTL neither, just using Struts2 tags you can achieve any result.

为了更好地解耦和分离代码和概念,你应该:

For a better decoupling and separation of code and concepts, you should have:


  1. DAO Layer :它只是简单的查询;

  2. 业务层:它通过服务(s)公开DAO层结果,聚合多个DAO呼叫并执行需要时进行多项业务操作;

  3. PRESENTATION Layer :Struts2中的Actions作为模型;在这里,您从业务层调用服务,以检索JSP所需的对象;

  4. JSP(VIEW Layer):JSP包含纯HTML,并访问Action的Accessors(Getters)所需的数据,最终访问Value Stack中的任何其他所需元素( #session #request 等。)

  1. DAO Layer: it does just the plain queries;
  2. BUSINESS Layer: it exposes the DAO Layer results through Service(s), aggregating multiple DAOs calls and performing several business operations when needed;
  3. PRESENTATION Layer: The Actions, that in Struts2 acts as the Model; here you call the Service from the Business Layer, to retrieve the objects needed by the JSP;
  4. JSP (VIEW Layer): the JSP contains the plain HTML, and accesses the data needed through the Accessors (Getters) of the Action, and eventually any other needed element from the Value Stack (#session, #request, etc).

在你的例子中,所有这些

In your example, all of this




<% 
   Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
   Transaction tx = session2.beginTransaction();
   Query q = session2.createQuery("from Subject");
   List subjectList = q.list();
   List levelList = session2.createQuery("from Level").list(); 
%>


应该在DAO / Business Layers中,由两个函数公开 getSubjectList(); getLevelList(); 。然后在你的Action中你应该有类似的东西:

should be in DAO/Business Layers, exposed by two function like getSubjectList(); and getLevelList();. Then in your Action you should have something like:

public class YourAction {

    private List<Object> levelList; // private
    private List<Object> subjectList; // private

    public String execute() throws Exception {      
        // Call the service, load data
        levelList = getMyService().getLevelList();
        subjectList = getMyService().getSubjectList();

        // Forwarding to the JSP
        return SUCCESS;
    }

    public List<Object> getLevelList() {
        return levelList;
    }
    public List<Object> getSubjectList() {
        return subjectList;
    }

}

在您的JSP中,而不是:

and in your JSP, instead of:


<select name="subject_id">
<%
  for (Object subjectObject : subjectList) {
      subject subject = (Subject) subjectObject;
%>
      <option value="<%=subject.getId()%>"><%=subject.getName()%></option>
<%
  } //end for
%>
</select>

你访问列表(丑陋的混合HTML / Struts2方式):

you access the list like (ugly mixed HTML/Struts2 way):

<select name="subject_id">
    <s:iterator value="subjectList">
        <option value="<s:property value="id"/>">
            <s:property value="name"/>
        </option>   
    </s:iterator>
</select>

或者,对于Select,使用正确的Struts2 UI选择标记:

or, in the case of a Select, with the proper Struts2 UI Select Tag:

<s:select name = "subject_id" 
          list = "subjectList" 
       listKey = "id" 
     listValue = "name" />

如果在开始时分离所有图层太困难,请在动作中展平前三个级别,只是为了理解如何分离Java(Action)和Struts2 UI Tags(JSP)。
理解后,您可以将DAO逻辑移动到业务层,最好是EJB。当达到这个目标时,再次以更细的粒度分割...

If separating all the layers is too difficult at the beginning, flatten the first three levels in the Actions, just to understand how to separata Java (Action) and Struts2 UI Tags (JSP). When understood, you can move the DAO logic to the business layer, preferably into an EJB. When achieved that, split again with more granularity...

行动将是这样的:

public class YourAction {

    private List<Object> levelList; // private
    private List<Object> subjectList; // private

    public String execute() throws Exception {      
            Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
            Transaction tx = session2.beginTransaction();
            Query q = session2.createQuery("from Subject");
            subjectList = q.list();
            levelList = session2.createQuery("from Level").list();

        // Forwarding to the JSP
            return SUCCESS;
    }

    public List<Object> getLevelList() {
        return levelList;
    }
    public List<Object> getSubjectList() {
        return subjectList;
    }    
}

关于多次加载列表的问题,你如果列表是固定的(例如每月更改一次),或者每次加载它都可以使用缓存(如果使用计时器则更好),这样做没有问题。
请注意,如果验证失败,ValidationInterceptor会将请求转发到INP​​UT类型结果中映射的JSP,而不会到达execute()方法,因此您应该从Action实现Preparable接口并将加载内容放入 prepare()方法,每次都由PrepareInterceptor执行

About your question on multiple loading of the lists, you can use a cache (better if with a timer) if the list is fixed (it changes one a month for example), or loading it every time, there aren't problems in doing that. Please note that if validation fails, the ValidationInterceptor will forward the request to the JSP mapped in the INPUT type result, without reaching the execute() method, so you should implement Preparable interface from Action and put the loading stuff into prepare() method, execute every time by the PrepareInterceptor

public class YourAction implements Preparable {

    private List<Object> levelList; // private
    private List<Object> subjectList; // private

    public void prepare() throws Exception {
        // Call the service, load data, 
        // every time even if validation fails
        levelList = getMyService().getLevelList();
        subjectList = getMyService().getSubjectList();
    }

    public String execute() throws Exception {      

        // Forwarding to the JSP
        return SUCCESS;
    }

    public List<Object> getLevelList() {
        return levelList;
    }
    public List<Object> getSubjectList() {
        return subjectList;
    }
}

按步骤进行,框架简单而强大,网上有很多例子,StackOverflow提供了很好的支持......

Proceed by steps, the framework is easy and powerful, the web has plenty of examples and StackOverflow provides some great support...

这篇关于我应该在Struts2视图层中检索数据库记录吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆