Должен ли я получить запись базы данных в слое представления Struts2?

У меня есть страница редактирования, на которой я хочу получить предметы и уровни из базы данных и отобразить в качестве опции выбора для пользователя, чтобы редактировать курс.

Когда форма отправлена, она сделает новый запрос, пользовательский ввод будет записан CourseBean с проверкой XML. Когда проверка XML не удалась, он будет перенаправлен с courseBean, который только что записал пользовательский ввод в файл edit.jsp.

Поэтому каждый раз, когда я захожу в edit.jsp, я получаю записи базы данных. Должен ли я сделать это таким образом?

Кроме того, я попытался найти освещенный предмет и освещенный уровень и сохранить их как атрибут запроса в классе действий, который отображает edit.jsp в первый раз. Но когда новый запрос сделан из пользовательского ввода, список субъектов и список уровней, извлеченные из базы данных, больше не будут доступны.

коды (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>

3 ответа

Решение

Использование Struts2 вам не нужно использовать Scriptletс (<% stuff %>) больше. Они старые, плохие, они вводят бизнес-логику на страницах просмотра, не используют их. Вам также не нужен JSTL, просто используя теги Struts2, вы можете достичь любого результата.

Для лучшего разделения и разделения кода и концепций вы должны иметь:

  1. DAO Layer: он выполняет только простые запросы;
  2. BUSINESS Layer: он предоставляет результаты уровня DAO через Service(s) агрегирование нескольких вызовов DAO и выполнение нескольких бизнес-операций при необходимости;
  3. PRESENTATION Layer: Действия, которые в Struts2 действуют как Модель; здесь вы вызываете сервис из бизнес-уровня, чтобы получить объекты, необходимые для JSP;
  4. JSP (VIEW Layer)JSP содержит простой HTML-код и получает доступ к данным, необходимым через Accessors (Getters) Action, и в конечном итоге к любому другому необходимому элементу из стека значений (#session, #request, так далее).

    В вашем примере все это

<% 
   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();, Тогда в вашем действии должно быть что-то вроде:

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 вместо:

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

Вы получаете доступ к списку следующим образом (безобразно смешанный путь HTML/Struts2):

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

или, в случае выбора, с соответствующим тегом выбора пользовательского интерфейса Struts2:

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

Если в начале разделить все слои слишком сложно, сгладьте первые три уровня в действиях, чтобы понять, как разделить теги Java (действие) и пользовательский интерфейс Struts2 (JSP). Когда это понято, вы можете переместить логику DAO на бизнес-уровень, предпочтительно в EJB. Когда достигнете этого, разделитесь снова с большей детализацией...

Действие будет что-то вроде этого:

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 перенаправит запрос в JSP, сопоставленный с результатом типа INPUT, без достижения метода execute(), поэтому вы должны реализовать интерфейс Preparable из Action и поместить загружаемые данные в prepare() метод, выполняемый каждый раз 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;
    }
}

Шаг за шагом, фреймворк прост и мощен, в Интернете множество примеров, а Stackru предоставляет отличную поддержку...

Вам нужен кеш. Но если записи базы данных часто меняются, это нецелесообразно.

Однако, если рассматриваемый запрос мал (я думаю, что он есть), запрос к базе данных не должен быть большой проблемой производительности.

С другой стороны, глядя на ваш JSP, все, что я вижу, является устаревшим и злоупотребляет скриптами JSP.

Поскольку вы добавили тег Struts 2, я буду считать, что это веб-проект Struts 2. Подумайте (настоятельно) об использовании встроенных в пользовательские теги Struts для работы, выполняемой в сценариях.

Ваш подход может быть описан только как использование динамо-машин для питания города, когда в вашем распоряжении ядерный реактор.

Я предлагаю вам начать здесь: http://struts.apache.org/2.x/docs/home.html

Это даст вам правильное представление о фреймворке и его полных возможностях.

Один совет, если вы хотите придерживаться архитектуры MVC, то никогда не используйте Business Logic in View. В соответствии с архитектурой MVC инженерам пользовательского интерфейса, работающим с View, не нужно вообще знать о Business Logic.

Смешивание HTML-кода и кода Java на вашей странице JSP усложнит представление и вызовет проблемы с поддержкой кода.

Используйте это руководство, чтобы увидеть, как реализовать CRUD-операции в Struts 2.

Другие вопросы по тегам