JavaRush /Blog Java /Random-ES /Introducción a Maven, Spring, MySQL, Hibernate y la prime...
Макс
Nivel 41

Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 4)

Publicado en el grupo Random-ES
Buenas tardes. En este artículo me gustaría compartir mi primer encuentro con cosas como Maven, Spring, Hibernate, MySQL y Tomcat en el proceso de creación de una aplicación CRUD simple. Esta es la parte final. El artículo está destinado principalmente a aquellos que ya han completado entre 30 y 40 niveles aquí, pero aún no se han aventurado más allá de Java puro y recién están comenzando (o están a punto de comenzar) a ingresar al mundo abierto con todas estas tecnologías, marcos y otros desconocidos. palabras. Esta es la última cuarta parte del artículo "Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD". Las partes anteriores se pueden ver siguiendo los enlaces:

Contenido:

Diseño y recursos web.

Nuestra aplicación funciona, pero no puedes mirarla sin lágrimas, inscripciones aburridas, enlaces feos y un fondo blanco vacío. Necesitamos arreglar esto y agregar diferentes bellezas. Cómo hacemos esto? Bueno, antes que nada, puedes jugar con las páginas y hacer todo tipo de cosas usando las capacidades de HTML . Pero si intentas cambiar fondos, colores, tamaños, disposición de elementos, etc. usando solo HTML. etcétera. luego, al final, puedes hacer tal desorden en la página que no puedas distinguir nada allí más tarde. Y además, las opciones de diseño de HTML son bastante limitadas. Es mejor utilizar CSS (hojas de estilo en cascada) para esto . Luego, todo lo relacionado con el diseño se puede recopilar en un solo lugar y luego aplicarlo al elemento deseado de la página. El código CSS se puede escribir directamente en una página JSP en una etiqueta especial, pero es mucho más conveniente colocarlo en un archivo separado y luego simplemente aplicarlo a las páginas necesarias. Para colocar archivos con estilos y otros recursos web estáticos, crearemos un directorio separado dentro de webapp . Para no confundir los recursos web con los recursos normales (donde tenemos db.properties ), llamemos a este directorio res y coloquemos todos los archivos CSS, imágenes, etc. allí:
Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 4) - 1
Para utilizar estos archivos necesitamos especificar su ubicación en la configuración. Vayamos a nuestra clase WebConfig. Anteriormente, usábamos la anotación @EnableWebMvcpara no configurar nada, sino simplemente usar la configuración predeterminada. Pero ahora es necesario configurar algo. Para hacer esto, usamos la interfaz WebMvcConfigurer, que le permite anular los métodos de configuración. Eso. Podemos usar la configuración predeterminada, pero al mismo tiempo personalizar algunos aspectos por nosotros mismos. En este caso addResourceHandlers, necesitamos un método con el que indiquemos la ubicación de los recursos web estáticos. Por las dudas, toda la clase termina luciendo así:
package testgroup.filmography.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "testgroup.filmography")
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/res/**").addResourceLocations("/res/");
    }

    @Bean
    ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/pages/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
}
Ahora, para usar nuestro CSS en la página, debes vincularlo dentro de la etiqueta head:
<head>
    <link href="<c:url value="/res/style.css"/>" rel="stylesheet" type="text/css"/>
</head>
Simplemente agregue esta línea y cree, por ejemplo, este simple archivo CSS:
table {
    border-spacing: 0 10px;
    font:  bold 100% Georgia, serif;
    margin: 40px auto;
    text-shadow: 5px 5px 5px #3F3F7F;
    background: #B1B9D9;
    text-align: center;
    vertical-align: middle;
    width: 50%;
    border: 10px solid blue;
}
Y esto cambiará completamente nuestra tabla (parece estúpido, por supuesto, pero es así, por ejemplo): Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 4) - 2Bueno, creo que no es necesario hablar en detalle sobre CSS, todo es bastante simple. En Internet puede encontrar muchas opciones listas para usar para diseñar tablas y formularios. Pero es mejor, por supuesto, hacer el diseño usted mismo, no es necesario ser diseñador, después de todo, este no es un sitio complicado. Incluso unas pocas horas después del primer contacto serán suficientes para crear un diseño bastante hermoso y ordenado para una página tan simple. Además, Internet está lleno de todo tipo de lecciones, ejemplos, hay sitios especiales donde puedes editar HTML, CSS simultáneamente en una pantalla y ver inmediatamente cómo se ve todo. Con un poco de práctica puedes crear arte real. Es cierto que aquí tampoco deberías dejarte llevar (a menos, por supuesto, que tengas planes de convertirte en diseñador); de lo contrario, el diseño es tal que puedes quedarte estancado aquí durante mucho tiempo. Cuando comencé a entender CSS, me quedé estancado. Quería probarlo todo, cada propiedad, torcer algo, modificarlo, experimentar, tomar páginas de algunos sitios y rehacerlas hasta quedar irreconocibles. Probablemente me divertí con este juguete durante una semana, sin hacer nada más, hasta que me soltó :) Bueno, en general, por supuesto, no debes exagerar y hacer un milagro colorido e incomprensible, debes hacerlo de manera simple y con buen gusto. Lo único digno de mención. Debe comprender que CSS es una descripción del diseño y HTML es marcado . No deberías intentar hacer absolutamente todo a través de CSS; algunos aspectos serán muy difíciles de hacer, y otros son simplemente imposibles, cuando en HTML esto se hace con un par de líneas extra, o incluso solo un atributo en una etiqueta. Debes combinarlos, crear todo tipo de colores, fondos y fuentes en CSS y, si, por ejemplo, necesitas combinar un par de celdas de una tabla, es más fácil usar herramientas HTML. Bueno, por ejemplo, esto es lo que pude hacer con las páginas en un par de horas jugando con CSS y HTML (no entraré en detalles aquí sobre el lío que hice para lograr esto, al final habrá un enlace al GitHub de este proyecto donde puedes mirar): Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 4) - 3Por supuesto, no sé qué tan competente hice todo allí, pero considerando que vi CSS por primera vez una semana antes, creo que resultó bastante bien.

Paginación

Ahora todo funciona, se ve bien, pero hasta ahora solo hay unos pocos registros en la tabla. ¿Y si hay cien o mil películas? No es muy cómodo desplazarse por una lista tan larga. Es mucho más cómodo cuando la lista se muestra en páginas de 10 entradas, por ejemplo. Por lo tanto, ahora intentaremos implementar la división de la lista en páginas (a veces esto también se llama "paginación" o "paginación" ( paginación en inglés )). Esto se puede hacer de diferentes maneras. Por ejemplo, puede transferir la lista completa a una página jsp y crear allí una tabla para la cantidad requerida de registros. O, por ejemplo, puede extraer los registros necesarios de la lista general del servicio y luego enviar esta minilista a una página jsp para su visualización. Pero, por supuesto, es mejor hacer esto a nivel de base de datos. La idea no es tomar una lista completa de la base de datos y luego dividirla en pedazos, sino obtener inicialmente la pieza requerida de la base de datos sin tocar todo lo demás. Después de todo, ¿por qué necesitamos extraer todos los cientos o miles de registros de la base de datos a la vez? Si el que necesitamos está entre los diez primeros, es mejor extraer solo este diez. Vayamos a DAO y agreguemos allFilmsun parámetro al método int page, que será responsable del número de página (en el servicio, por supuesto, hacemos lo mismo). Y cambiemos un poco la implementación de este método, si antes sacamos la lista completa, ahora sacaremos solo una parte. setFirstResultLos métodos (con qué fila de la tabla comenzar) y setMaxResults(cuántos registros mostrar) nos ayudarán con esto :
@SuppressWarnings("unchecked")
public List<Film> allFilms(int page) {
    Session session = sessionFactory.getCurrentSession();
    return session.createQuery("from Film").setFirstResult(10 * (page - 1)).setMaxResults(10).list();
}
Aquellos. si esta es la 1ª página, mostramos un máximo de 10 registros, comenzando desde la 0, si es la 5ª página, entonces 10 registros comenzando desde la 40 (no olvide que la numeración en la base de datos comienza desde 0). También crearemos adicionalmente un método que devolverá la cantidad de registros en la tabla. Necesitaremos esto para saber el número de todas las páginas y crear enlaces para ellas en nuestra página jsp:
public int filmsCount() {
     Session session = sessionFactory.getCurrentSession();
     return session.createQuery("select count(*) from Film", Number.class).getSingleResult().intValue();
 }
Con dicha consulta, obtendremos el número de todos los registros de la tabla (como intvalor) sin tener que extraer los registros. Ahora vayamos al controlador y trabajemos en el método que devuelve la página principal con una lista de películas:
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView allFilms(@RequestParam(defaultValue = "1") int page) {
    List&ltFilm> films = filmService.allFilms(page);
    int filmsCount = filmService.filmsCount();
    int pagesCount = (filmsCount + 9)/10;
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("films");
    modelAndView.addObject("page", page);
    modelAndView.addObject("filmsList", films);
    modelAndView.addObject("filmsCount", filmsCount);
    modelAndView.addObject("pagesCount", pagesCount);
    return modelAndView;
}
Aquí ha aparecido una nueva anotación @RequestParam, que indica que estamos obteniendo este valor de un parámetro de solicitud. Ahora, si vamos a una dirección con un parámetro, por ejemplo http://localhost:8080/ ?page=4 , obtendremos, en consecuencia, la cuarta página. Establecemos el valor predeterminado en " 1 " para que cuando se inicie la aplicación, cuando vayamos a una dirección sin el parámetro http://localhost:8080/ , obtengamos la primera página. En el método obtenemos el número de todos los registros, luego de esta forma sencilla calculamos el número de páginas. Aquellos. si tenemos 10 registros, esta es 1 página, y si hay 11, entonces ya son 2. Bueno, transferimos todo esto al modelo. Necesita saber el número de páginas para crear enlaces para todas ellas en un ciclo y dejar que el número de películas esté allí por si acaso, por ejemplo, si desea mostrar esta información en algún lugar de la página. Ahora todo lo que queda es ir a films.jsp y agregar enlaces a cada página usando esta construcción:
<c:forEach begin="1" end="${pagesCount}" step="1" varStatus="i">
    <c:url value="/" var="url">
        <c:param name="page" value="${i.index}"/>
    </c:url>
    <a href="${url}">${i.index}</a>
</c:forEach>
Creamos enlaces por contador 1, 2, 3, ... y configuramos el parámetro por el valor del índice.

Por cierto, al igual que con la paginación, puedes agregar otras funciones, como ordenar, filtrar y buscar. Simplemente pasamos varios parámetros al método DAO y los usamos para formar una consulta adecuada a la base de datos para extraer los registros requeridos en el orden requerido.

Agreguemos un pequeño toque más. Volvemos al controlador. En los métodos de agregar, editar y eliminar, una vez completada la operación, redireccionamos a la página principal "redirect:/" . Eso. si estamos en algún lugar de la página 50 y hacemos clic en editar entrada, luego de la ejecución iremos a la dirección " / ", es decir Volvamos a la página 1. Esto no es muy conveniente, me gustaría volver al lugar de donde venimos. Resolvamos esto de manera muy simple. FilmControllerCreemos una variable de instancia en la clase.int page
private int page;
Dentro del método allFilmsasignaremos el valor del parámetro a esta variable page:
this.page = page;
Eso. Cada vez que se ejecuta este método (es decir, cuando navegamos por las páginas), el valor de la página actual se escribirá en la variable. Y luego usamos este valor en nuestros métodos para redirigir a la misma página.
modelAndView.setViewName("redirect:/?page=" + this.page);

Conclusión

Probablemente terminemos aquí. El resultado es una aplicación CRUD completa. Ciertamente está lejos de ser ideal (muy lejos), pero se puede optimizar y mejorar, corregir errores y agregar funcionalidad. Puede utilizar métodos integrados para operaciones crudas; agregar filtrado, búsqueda, clasificación; agregue otras tablas relacionadas; implementar soporte para diferentes usuarios con autorización y autenticación, etc. etcétera. El alcance de la imaginación es ilimitado, así que adelante. Enlace al github de este proyecto . Gracias por su atención. PD: Este es el primer intento en mi vida de escribir un artículo, así que no juzgues estrictamente :). Pido disculpas por no agregar enlaces diferentes a recursos útiles; desafortunadamente, todavía no puedo desarrollar el hábito de guardar enlaces a las fuentes de las que obtengo información. Y, por supuesto, pido disculpas por tantas cartas, la brevedad no es mi talento, espero que alguien pueda manejar esto. Enlaces a todas las partes.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION