java - ¿Debo recuperar el registro de la base de datos en la capa de vista de Struts2?
jsp model-view-controller (3)
Tengo una página de edición en la que quiero recuperar los temas y niveles de la base de datos y mostrar como opción de selección para que el usuario edite el curso .
Cuando se envía el formulario, se realizará una nueva solicitud, la entrada del usuario es capturada por courseBean con validación XML. Cuando la validación XML falló, reenviará con el courseBean que acaba de capturar la entrada del usuario a edit.jsp .
Así que cada vez que voy al edit.jsp , recuperaré los registros de la base de datos. ¿Debo hacerlo de esa manera?
Además, traté de recuperar el tema iluminado y el nivel encendido y almacenarlos como el atributo de solicitud en la clase de acción que muestra edit.jsp por primera vez. Pero cuando la nueva solicitud se realiza desde la entrada del usuario, la lista de temas y la lista de niveles recuperados de la base de datos ya no estarán disponibles.
códigos (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>
Un consejo, si quiere apegarse a la arquitectura MVC, entonces nunca tenga Business Logic en View. De acuerdo con la arquitectura de MVC, los ingenieros de IU que trabajan con View no necesitan saber nada sobre la lógica de negocios.
La combinación de código HTML y Java en su página JSP complica la vista y causará problemas en el mantenimiento del código.
Haga uso de este tutorial para ver cómo implementar operaciones CRUD en Struts 2.
Lo que necesitas es un caché. Pero si los registros de la base de datos están obligados a cambiar con frecuencia, es desaconsejable.
Sin embargo, si la consulta en cuestión es pequeña (creo que lo es) consultar la base de datos no debería ser un gran problema de rendimiento.
En otra nota, mirando a su JSP, todo lo que veo es obsoleto y mal uso de scriplets JSP.
Como ha agregado los struts de etiqueta 2, asumiré que este es un proyecto web de struts 2. Considere (con fuerza) el uso de struts ui tags incorporados para el trabajo realizado en sus scriplets.
Su enfoque solo puede describirse como el uso de un grupo de dínamos para alimentar una ciudad cuando tiene un reactor nuclear a su disposición.
Te sugiero que comiences aquí: http://struts.apache.org/2.x/docs/home.html
Esto le dará una idea correcta del marco y de sus capacidades completas.
Usando Struts2 ya no necesitarás usar Scriptlet
( <% stuff %>
). Son viejos, malos, tienen una lógica comercial inyectada en las páginas de vista, no los utilices. No necesita JSTL tampoco, solo usando etiquetas Struts2 puede lograr cualquier resultado.
Para un mejor desacoplamiento y separación de códigos y conceptos, debe tener:
-
DAO Layer
: solo hace las consultas simples; -
BUSINESS Layer
empresarial: expone los resultados de la capa DAO a través de losService
, agregando múltiples llamadas DAO y realizando varias operaciones comerciales cuando es necesario; -
PRESENTATION Layer
: Las Acciones, que en Struts2 actúa como el Modelo; aquí llama al Servicio desde la capa empresarial para recuperar los objetos que necesita el JSP; JSP (VIEW Layer)
: el JSP contiene el HTML simple, y accede a los datos necesarios a través de los Accessors (Getters) de la Acción, y finalmente cualquier otro elemento necesario de Value Stack (#session
,#session
, etc.).En tu ejemplo, todo esto
<% 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(); %>
debe estar en DAO / Business Layers, expuesto por dos funciones como getSubjectList();
y getLevelList();
. Luego en tu Acción deberías tener algo como:
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;
}
}
y en su JSP, en lugar de:
<select name="subject_id"> <% for (Object subjectObject : subjectList) { subject subject = (Subject) subjectObject; %> <option value="<%=subject.getId()%>"><%=subject.getName()%></option> <% } //end for %> </select>
accedes a la lista como (forma fea mixta de HTML / Struts2):
<select name="subject_id">
<s:iterator value="subjectList">
<option value="<s:property value="id"/>">
<s:property value="name"/>
</option>
</s:iterator>
</select>
o, en el caso de un Seleccionar, con la etiqueta de identificación de UI apropiada de Struts2:
<s:select name = "subject_id"
list = "subjectList"
listKey = "id"
listValue = "name" />
Si separar todas las capas es demasiado difícil al principio, aplana los primeros tres niveles en las Acciones, solo para comprender cómo separata Java (Acción) y Struts2 UI Tags (JSP). Cuando se entienda, puede mover la lógica DAO a la capa empresarial, preferiblemente a un EJB. Cuando se logra eso, se divide nuevamente con más granularidad ...
La acción será algo como esto:
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;
}
}
Acerca de su pregunta sobre la carga múltiple de las listas, puede usar un caché (mejor si tiene un temporizador) si la lista es fija (por ejemplo, cambia una vez al mes) o si la carga cada vez, no hay problemas para hacerlo ese. Tenga en cuenta que si la validación falla, ValidationInterceptor reenviará la solicitud al JSP mapeado en el resultado de tipo INPUT, sin llegar al método execute (), por lo que debe implementar la interfaz Preparable desde Action y colocar el material de carga en el método prepare()
. ejecutar cada vez por el 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;
}
}
Proceda por pasos, el marco es fácil y poderoso, la web tiene muchos ejemplos y proporciona un gran soporte ...