Должен ли я получить запись базы данных в слое представления 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, вы можете достичь любого результата.
Для лучшего разделения и разделения кода и концепций вы должны иметь:
DAO Layer
: он выполняет только простые запросы;BUSINESS Layer
: он предоставляет результаты уровня DAO черезService
(s) агрегирование нескольких вызовов DAO и выполнение нескольких бизнес-операций при необходимости;PRESENTATION Layer
: Действия, которые в Struts2 действуют как Модель; здесь вы вызываете сервис из бизнес-уровня, чтобы получить объекты, необходимые для JSP;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.