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 1)

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 primera parte de 4. 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 otras palabras desconocidas. Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 1) - 1

Contenido:

Introducción

Comencé a familiarizarme con tecnologías y marcos que eran nuevos para mí estudiando varios ejemplos en los que se usaban, porque generalmente entiendo algo mejor cuando lo veo en acción usando un ejemplo de una aplicación completa. Normalmente, estos ejemplos son aplicaciones CRUD ( Crear , Leer , Actualizar , Eliminar ); Internet está lleno de ejemplos de este tipo de diversos grados de complejidad. El problema es que normalmente no explican en detalle cómo, qué y por qué se hizo allí, por qué se añadió tal o cual dependencia, por qué se necesita tal o cual clase, etc. En la mayoría de los casos, toman una aplicación completamente terminada, con un archivo POM final, con versiones finales de las clases, y simplemente repasan cada una, sin centrarse en las pequeñas cosas que probablemente parezcan obvias para una persona experimentada. He visto muchos ejemplos de este tipo y, por lo general, está claro cómo funciona todo, pero no está del todo claro cómo llegaron a esto. Por lo tanto, decidí que un ejemplo así sería útil no desde la posición de un desarrollador experimentado, sino desde la posición de un principiante que nunca ha trabajado con Spring, Hibernate y otras cosas.
Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 1) - 2
Intentaré describir con el mayor detalle posible (hasta donde mi comprensión me permita) todo mi camino para crear una aplicación CRUD, comenzando con algo en el nivel más simple de Hello World. En primer lugar, hago esto por mí mismo, porque cuando intentas describir, contar, explicar algo, se asimila y organiza mucho mejor en tu cabeza. Pero si esto le resulta útil a alguien y le ayuda a descubrir algo, estaré muy contento. En este ejemplo, intentemos crear una aplicación CRUD simple usando Maven , Tomcat , Spring , Hibernate y MySQL . Pasos preliminares como instalar Maven , MySQL , usar la versión Ultimate de la idea, etc. Creo que no es necesario describirlo en detalle, no debería haber problemas con esto. Vale la pena señalar que en este ejemplo, la configuración se configurará usando clases Java (llamadas JavaConfig) sin usar xml.

Creando un proyecto

Entonces, como soy un novato, no usaremos ningún arquetipo oscuro. Spring inicializr todavía suena demasiado aterrador. Por lo tanto, crearemos el proyecto Maven simple más común. No tengo un nombre de dominio, así que en groupid simplemente escribiré testgroupy en artefactoid escribiré el nombre, por ejemplo filmography(esta será una lista de películas). Creamos un proyecto y elegimos Enable auto-importcuando la idea lo sugiere. Gracias a esto, cada vez que realicemos algún cambio en el archivo POM (Project Object Model, este archivo describe toda la estructura del proyecto Maven), inmediatamente todo se aplicará automáticamente al proyecto. Las bibliotecas se tomarán de nuestro repositorio local si ya las tenemos, o si usamos algunas dependencias nuevas que no hemos tratado antes, Maven simplemente las descargará a través de Internet desde el repositorio central. Maven también tiene una función para descargar fuentes y documentación (Descargar Fuentes y/o Documentación). También es muy conveniente, si algo no está claro con alguna clase o método, puedes ir al código fuente y ver cómo funciona todo por dentro. Agreguemos un par de detalles. Esta será una aplicación web y usaremos Tomcat . Para implementar una aplicación en Tomcat, debe transferirla allí en forma de archivo war (recurso de aplicación web, un formato especial para aplicaciones web). Para hacer esto, agregue la siguiente línea al archivo POM para que la aplicación se compile en un archivo war:
<packaging>war</packaging>
Bueno, también necesitarás un directorio especial para fuentes web, en nuestro caso habrá páginas jsp y algunos recursos web. Creemos un maindirectorio webapp. Debería llamarse exactamente así y ubicarse exactamente de mainla misma manera que java, resourcesporque esta es la estructura de directorios estándar de Maven. Una vez que hayamos instalado el paquete wary así determinado que se trata de un proyecto web, automáticamente se marcará el directorio webappcomo fuentes de aplicaciones web (habrá un punto azul en él) y en esta carpeta se buscará todo lo relacionado con la web. Y un momento. De forma predeterminada, Maven usa la versión 1.5 del lenguaje, pero quiero usar, por ejemplo, la versión 1.8 - Java 8 (puede tomar 10 u 11, pero aún no hay planes para usar ninguna característica desde allí, así que sea 8). ). Esto se puede resolver de manera muy simple, escribimos en Google algo como "Maven java 8" y vemos qué se debe agregar al archivo POM para que Maven compile nuestras clases para la versión requerida. Como resultado, tenemos lo siguiente: Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 1) - 3

Conexión de resorte MVC

Tienes que empezar por algún lado. Según el plan, conectaremos la base de datos y usaremos Hibernación, pero todo esto suena demasiado aterrador por ahora. Primero debemos hacer algo más simple. Spring MVC, esto ya es mejor, conocemos el patrón MVC desde hace mucho tiempo, se usó en la mitad de las tareas grandes del curso. A partir de aquí empezaremos a bailar. Para crear una aplicación web con Spring MVC, también necesitamos una Servlet-API, es decir. aquello con cuya ayuda se llevará a cabo la interacción solicitud-respuesta. Intentemos conectar esto. Vamos a Google, buscamos las dependencias necesarias en el repositorio de Maven y las añadimos al archivo pom.xml. Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 1) - 4En la sección Bibliotecas externas puede ver que no solo se cargó spring-webmvc , sino también muchas otras cosas. Aquellos. No necesitamos incluir dependencias adicionales para Spring Core , Context , Beans , etc. que necesitamos, todo lo que necesitábamos se obtuvo junto con spring-webmvc .

Necesitamos hacer un pequeño descargo de responsabilidad. Por lo general, se recomienda agregar una dependencia por separado para cada biblioteca utilizada, incluso si ya están incluidas con las que ya se agregaron, porque esto puede ayudar a evitar algunos problemas y fallas.

Un ejemplo sencillo. Digamos que agregamos una dependencia que usa alguna API y, al mismo tiempo, generaremos algún tipo de implementación para esta API. Y luego agregamos otra dependencia que usa la misma API y también recupera parte de su implementación para esto, pero esta vez es diferente. Así, tendremos 2 implementaciones diferentes de una misma API. Y si nosotros mismos queremos usar algunos métodos de esta API en alguna parte, entonces surgirá un problema, porque el sistema no sabrá qué implementación usar, elegirá al azar, quizás no la que esperábamos. Y si especifica explícitamente una dependencia para una de las implementaciones, se le dará prioridad.

Sin embargo, esta no es una recomendación tan estricta; se aplica principalmente a proyectos grandes donde se utilizan muchas bibliotecas diferentes de diferentes empresas. No haremos eso aquí para no cargar demasiado el archivo POM; no se esperan problemas. Sin embargo, vale la pena tener esto en cuenta.

Una nota más. ¿Qué significa provideddepender javax.servlet-api? El alcance es el alcance de la dependencia, providedlo que significa que la dependencia estará disponible en la etapa de compilación y prueba de la aplicación, pero no se archivará. El hecho es que para implementar la aplicación usaremos un contenedor de servlets, Tomcat, y ya tiene dichas bibliotecas en su interior, por lo que no es necesario transferirlas allí y cargar el archivo con una carga innecesaria. De cara al futuro, por la misma razón prescindiremos del método habitual main, porque ya existe dentro de Tomcat.

Creando páginas y controlador

Intentemos preparar algo sencillo ahora. Primero, creemos un webappdirectorio adicional, por ejemplo pages, en el que se almacenarán nuestras vistas, es decir. páginas jsp y cree un par de páginas. Necesitaremos una página en la que en el futuro se mostrará una lista de películas, por ejemplo films.jsp, y quizás podamos crear una página separada para editar, así sea editPage.jsp. No los completaremos con nada serio por ahora; solo para probar, haremos un enlace de una página a otra. Ahora necesitamos una clase que procese solicitudes, es decir. controlador. Agreguemos un nuevo paquete controllery creemos una clase en él FilmController(en general, no es necesario empaquetar todo en diferentes paquetes, esta aplicación será muy pequeña y simple, pero en un proyecto normal puede haber muchos controladores, clases de configuración, modelos , etc., por lo que incluso empezando con proyectos pequeños, es mejor acostumbrarse inmediatamente a hacer todo de forma ordenada y estructurada para que no haya desorden). En esta clase crearemos métodos que devolverán nuestras vistas en respuesta a las solicitudes.
package testgroup.filmography.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class FilmController {

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView allFilms() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("films");
        return modelAndView;
    }

    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public ModelAndView editPage() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("editPage");
        return modelAndView;
    }
}
¿Cuál es el punto de? Spring MVC tiene algo llamado DispatcherServlet. Es como el controlador principal, todas las solicitudes entrantes pasan a través de él y luego las pasa a un controlador específico. La anotación @Controllersimplemente le dice a Spring MVC que esta clase es un controlador (bueno, lógico en general), el despachador verificará las anotaciones @RequestMappingpara llamar al método apropiado. La anotación @RequestMappingle permite establecer direcciones para los métodos del controlador, mediante las cuales estarán disponibles en el cliente (navegador). También se puede aplicar a la clase de controlador para establecer, por así decirlo, la dirección raíz de todos los métodos. allFilms()El parámetro para el método valueestá establecido en " /", por lo que se llamará inmediatamente cuando se ingrese la combinación http://host:port/ en el navegador (es decir, de forma predeterminada es http://localhost:8080/ o http ://127.0.0.1:8080/ ). El parámetro methodespecifica qué tipo de solicitud se admite (GET, POST, PUT, etc.). Como aquí solo recibimos datos, se utiliza GET. Más adelante, cuando aparezcan métodos para agregar y editar, ya habrá solicitudes POST. (Por cierto, en lugar de una anotación @RequestMappingque indique un método, puede usar anotaciones @GetMapping, @PostMappingetc. @GetMappingde manera equivalente @RequestMapping(method = RequestMethod.GET)). En nuestros métodos, creamos un objeto ModelAndViewy configuramos el nombre de la vista que debe devolverse.

Configuración

Pasemos a configurar la configuración. configCreemos una clase en el paquete WebConfig. Tendrá un solo método que devuelve un objeto de tipo ViewResolver, esta es la interfaz necesaria para encontrar una representación por nombre.
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.view.InternalResourceViewResolver;

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

    @Bean
    ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/pages/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
}
@Configurationle dice a Spring que esta clase es una clase de configuración y contiene las definiciones y dependencias beande los componentes. Los beans son objetos gestionados por Spring. La anotación se utiliza para definir un bean @Bean. @EnableWebMvcle permite importar la configuración de Spring MVC desde WebMvcConfigurationSupport. También puedes implementar, por ejemplo, una interfaz WebMvcConfigurerque tenga un montón de métodos y personalizar todo a tu gusto, pero no necesitamos entrar en eso todavía, la configuración estándar será suficiente. @ComponentScanle dice a Spring dónde buscar los componentes que debe administrar, es decir clases marcadas con una anotación @Componento sus derivados como @Controller, @Repository, @Service. Estas anotaciones definen automáticamente la clase bean. En el método, viewResolver()creamos su implementación y determinamos dónde buscar exactamente las representaciones webapp. Por lo tanto, cuando en el método del controlador configuramos el nombre " films" la vista se encontrará como " /pages/films.jsp" Entonces, tenemos una clase de configuración, pero por ahora es solo algún tipo de clase separada, no afecta nuestra aplicación de ninguna manera. . Necesitamos registrar esta configuración en el contexto de Spring. Para esto necesitas una clase AbstractAnnotationConfigDispatcherServletInitializer. En el paquete, configcreamos su sucesor, digamos AppInitializer , e implementamos sus métodos.
package testgroup.filmography.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}
El último método registra direcciones y hay 2 métodos más para registrar clases de configuración. Las configuraciones web, donde ViewResolverse definen 's y similares, se colocan en getServletConfigClasses(). Es mejor leer sobre todo esto en la documentación y en varias guías, pero en nuestro caso no es necesario profundizar en esto todavía, el nuestro, WebConfigen principio, se puede RootClassesdefinir en ambos, incluso puedes definir ambos a la vez, seguirá funcionando. . Una cosa más. Puede haber problemas con la codificación cuando, al enviar valores con caracteres rusos desde el formulario, el resultado serán garabatos. Para resolver este problema, agregaremos un filtro que procesará previamente las solicitudes. Vamos a la clase AppInitializer y anulamos el método getServletFiltersen el que indicamos la codificación deseada, por supuesto, debe ser la misma que en todas partes, como en las páginas y en la base de datos:
protected Filter[] getServletFilters() {
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);
        return new Filter[] {characterEncodingFilter};
    }
Bueno, todo parece estar configurado, puedes intentar ejecutarlo y ver qué sucede. Ejecutar -> Ejecutar -> Editar configuraciones -> Agregar nueva configuración -> Servidor Tomcat -> Local A continuación, debe seleccionar un artefacto para implementar. La idea en sí dará una pista Advertencia: no hay artefactos marcados para implementación . Haga clic en el botón arreglar y seleccione ...: la guerra explotó . O puede ir a Implementación -> agregar -> Artefacto -> ...: la guerra explotó . Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 1) - 5Y también debe ir a Implementación y configurar el campo de contexto de Applecation (esto será parte de la dirección URL donde la aplicación estará disponible en el navegador) en " /". Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 1) - 6Entonces nuestra aplicación estará disponible inmediatamente en http://localhost:8080/ (pero también puedes especificar algo allí, por ejemplo " /filmography", y luego solo necesitarás agregar esto a todas las direcciones, es decir, por ejemplo no habrá " http://localhost:8080/edit" , pero será "http://localhost:8080/filmography/edit" ). Haga clic en Ejecutar y espere hasta que comience. Esto es lo que obtuve: Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 1) - 7todo parece estar bien, pero hay una advertencia. El hecho es que nuestras páginas ahora son de acceso público y se puede acceder a ellas directamente escribiendo la ruta en la barra de direcciones. Ingresamos a http://localhost:8080/pages/films.jsp y ahora hemos recibido nuestra página sin que el controlador lo sepa. De alguna manera esto no es muy correcto, así que crearemos un webappdirectorio especial WEB-INF. Lo que hay dentro estará oculto al público y solo se podrá acceder a él a través de un controlador. Colocamos el directorio con nuestras vistas ( pages) en WEB-INFy, ViewResolveren consecuencia, lo agregamos al prefijo:
viewResolver.setPrefix("/WEB-INF/pages/");
Ahora tenemos nuestra página en http://localhost:8080 , pero si intentamos ir directamente a http://localhost:8080/WEB-INF/pages/films.jsp obtenemos un error 404. Bueno, genial, tenemos el La aplicación web más sencilla, Hola mundo, como dicen. La estructura del proyecto actualmente se ve así:
Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 1) - 8

Modelo

Ya tenemos vistas y un controlador, pero en MVC también hay una tercera letra, así que para completar el cuadro también agregaremos un modelo. En el paquete, modelcreemos una clase Film, por ejemplo, con los siguientes campos: int id, String title(título), int year(año de estreno), String genre(género) y boolean watched(es decir, ya has visto esta película o no).
package testgroup.filmography.model;

public class Film {
    private int id;
    private String title;
    private int year;
    private String genre;
    private boolean watched;
// + Getters and setters
}
Nada especial, solo una clase ordinaria, campos privados, captadores y definidores. Los objetos de tales clases también se denominan POJO(objeto Java antiguo simple), bueno, es decir. "objeto java simple". Intentemos ahora crear dicho objeto y mostrarlo en la página. Por ahora, no nos preocuparemos demasiado por cómo crearlo e inicializarlo. Para probarlo, simplemente creémoslo estúpidamente directamente en el controlador, por ejemplo, así:
public class FilmController {
    private static Film film;

    static {
        film = new Film();
        film.setTitle("Inception");
        film.setYear(2010);
        film.setGenre("sci-fi");
        film.setWatched(true);
    }
Y agregue este objeto al nuestro ModelAndViewusando el método addObject:
@RequestMapping(method = RequestMethod.GET)
    public ModelAndView allFilms() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("films");
        modelAndView.addObject("film", film);
        return modelAndView;
    }
Ahora podemos mostrar este objeto en nuestra página. En films.jsplugar de Hola Mundo escribiremos y aquí se sustituirá ${film}el objeto correspondiente al nombre del atributo " ". filmIntentemos ejecutarlo y ver qué sucedió (para una salida clara del objeto, Filmse redefinió la clase toString()):
Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 1) - 9

Modelo-Vista-Controlador

En esta etapa, parece que ya tenemos una aplicación Spring MVC completa. Antes de continuar, sería bueno echar un vistazo a todo nuevamente y descubrir cómo funciona. En Internet puedes encontrar muchas fotos y diagramas sobre esto, a mí me gusta este:
Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 1) - 10
Cuando escribimos una solicitud en la línea del navegador, se acepta Dispatcher Servlet, luego encuentra un controlador adecuado para procesar esta solicitud HandlerMapping(esta es una interfaz para seleccionar un controlador, verifica cuál de los controladores disponibles tiene un método que acepta dicha dirección) , llama a un método adecuado y Controllerdevuelve información sobre la vista, luego el despachador encuentra la vista deseada por nombre usando ViewResolver'a, después de lo cual los datos del modelo se transfieren a esta vista y obtenemos nuestra página como salida. Algo como esto. Continuará... Presentamos Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 1) Presentamos Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 2) Presentamos Maven, Spring, MySQL, Hibernate y primera aplicación CRUD (parte 3) Introducción a Maven, Spring, MySQL, Hibernate y la primera aplicación CRUD (parte 4)
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION