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

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

问题描述

我有一个编辑页面,我想在其中从数据库中检索科目级别,并将其显示为选择选项供用户编辑课程强>.

当表单被提交时,它会发出一个新的请求,用户输入被courseBean 用 XML 验证捕获.当 XML 验证失败时,它会将刚刚捕获用户输入的 courseBean 转发到 edit.jsp.

所以每次我去edit.jsp,我都会检索数据库记录.我应该那样做吗?

此外,我尝试检索 subject litlevel lit 并将它们作为请求属性存储在显示 edit.jsp第一时间.但是当从用户输入发出新请求时,从数据库中检索到的主题列表级别列表将不再可用.

代码(edit.jsp):

<%会话 session2 = HibernateUtil.getSessionFactory().getCurrentSession();交易 tx = session2.beginTransaction();查询 q = session2.createQuery("来自主题");列表主题列表 = q.list();List levelList = session2.createQuery("from Level").list();%><div class="control-group"><label class="control-label" for="inputPassword">Subject</label><div class="控件"><select name="subject_id"><%对于(对象主题对象:主题列表){主题主题=(主题)主题对象;%><option value="<%=subject.getId()%>"><%=subject.getName()%></option><% }//结束%></选择>

<div class="control-group"><label class="control-label" for="inputPassword">Level</label><div class="控件"><select name="level_id"><%对于(对象级别对象:级别列表){级别 level = (Level) levelObject;%><option value="<%=level.getId()%>"><%=level.getName()%></option><% }//结束%></选择>

解决方案

使用 Struts2,您将不再需要使用 Scriptlets (<% stuff %>).它们是旧的,坏的,它们是在视图页面中注入的业务逻辑,不要使用它们.你也不需要JSTL,只要使用Struts2标签就可以实现任何结果.

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

  1. DAO 层:它只做简单的查询;
  2. BUSINESS Layer:它通过Service(s)暴露DAO层的结果,聚合多个DAOs调用并在需要时执行多个业务操作;
  3. PRESENTATION Layer:Actions,在Struts2中作为Model;在这里,您从业务层调用服务,以检索 JSP 所需的对象;
  4. JSP(VIEW 层):JSP 包含纯 HTML,并通过 Action 的访问器(Getter)访问所需的数据,并最终从 Value 中访问任何其他需要的元素堆栈(#session#request 等).

    在你的例子中,所有这些

<块引用>

<%会话 session2 = HibernateUtil.getSessionFactory().getCurrentSession();交易 tx = session2.beginTransaction();查询 q = session2.createQuery("来自主题");列表主题列表 = q.list();List levelList = session2.createQuery("from Level").list();%>

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

public class YourAction {私人列表<对象>级别列表;//私人的私人列表<对象>主题列表;//私人的公共字符串执行()抛出异常{//调用服务,加载数据levelList = getMyService().getLevelList();subjectList = getMyService().getSubjectList();//转发到 JSP返回成功;}公共列表<对象>getLevelList() {返回级别列表;}公共列表<对象>获取主题列表(){返回主题列表;}}

并在您的 JSP 中,而不是:

<块引用>

<s:iterator value="subjectList"><option value="<s:property value="id"/>"><s:property value="name"/></选项></s:迭代器></选择>

或者,在选择的情况下,使用适当的 Struts2 UI 选择标签:

<s:select name = "subject_id"列表=主题列表"listKey = "id"listValue = "名称"/>

如果一开始分离所有的层太难了,把Actions中的前三个层次展平,只是为了理解如何分离Java(Action)和Struts2 UI标签(JSP).理解后,您可以将 DAO 逻辑移至业务层,最好移至 EJB.实现后,再次以更大的粒度拆分...

Action 将是这样的:

public class YourAction {私人列表<对象>级别列表;//私人的私人列表<对象>主题列表;//私人的公共字符串执行()抛出异常{会话 session2 = HibernateUtil.getSessionFactory().getCurrentSession();交易 tx = session2.beginTransaction();查询 q = session2.createQuery("来自主题");主题列表 = q.list();levelList = session2.createQuery("from Level").list();//转发到 JSP返回成功;}公共列表<对象>getLevelList() {返回级别列表;}公共列表<对象>获取主题列表(){返回主题列表;}}

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

public class YourAction 实现了 Preparable {私人列表<对象>级别列表;//私人的私人列表<对象>主题列表;//私人的公共无效准备()抛出异常{//调用服务,加载数据,//每次即使验证失败levelList = getMyService().getLevelList();subjectList = getMyService().getSubjectList();}公共字符串执行()抛出异常{//转发到 JSP返回成功;}公共列表<对象>getLevelList() {返回级别列表;}公共列表<对象>获取主题列表(){返回主题列表;}}

循序渐进,框架简单而强大,网络上有大量的例子,StackOverflow 提供了一些很好的支持......

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.

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.

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

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.

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>

解决方案

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: 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(); 
%>

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;
    }

}

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>

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>

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" />

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...

The Action will be something LIKE this:

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;
    }    
}

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;
    }
}

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天全站免登陆