Ir al contenido principal

Instalando Apache NetBeans 10 y configurarlo con Jakarta EE

Spring con JDBC y JPA

En este post veremos una aplicación Java Web donde la conexión a la base de datos se hará usando Spring, y también veremos cómo manipular la data con JDBC y con JPA. Todo esto lo ejecutaremos desde Tomcat.


Tecnologías utilizadas en este post:

  1. Maven
  2. JPA 2.1
  3. Tomcat 8.5
  4. Spring 4.3
  5. Hibernate 5.2
  6. Java 8
  7. Java EE Web Profile 7.0 (por el Tomcat)
  8. slf4j
  9. Base de datos

0. Logging

Para todo buen proyecto, es necesario contar con un logging. Para ello, usaremos el S4JL con puente el Log4j. Necesitamos para ello la dependencia en el pom.xml

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>


Además, necesitamos el archivo log4j.properties bien configurado para el proyecto.
. Estas serán las propiedades que utilizaremos en el proyecto:
    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>4.3.11.RELEASE</spring.version>
        <hibernate.version>5.2.11.Final</hibernate.version>
    </properties>

1. Generar el Proyecto desde Plantilla Maven

Ejecutar desde la consola del sistema operativo:


mvn archetype:generate -DgroupId=com.apuntesdejava -DartifactId=db-spring-sample-web -Dversion=1.0 -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false


También podríamos haberlo creado desde NetBeans o Eclipse como Módulo Web.

2. Archivo context.xml para Tomcat. Conexión a base de datos

La base de datos que usaremos es el H2 Database.

        <!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.196</version>
        </dependency>



Recomiendo mucho que la conexión a la base de datos se encargue el contenedor web, y no que la aplicación lo haga. La aplicación solo debería conectarse usando el JNDI. Aquí una explicación en un post anterior: DataSources en una aplicación Java EE


Adicionalmente, para que los componentes Java lo puede ver, es necesario crear la referencia en el archivo web.xml.

3. Archivo spring.xml para nuestra configuración de Spring con JDBC + DataSource

Necesitamos agregar las dependencias para Spring:
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>


Tendremos nuestro archivo src/main/resources/spring.xml con el siguiente contenido:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:context="http://www.springframework.org/schema/context"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
">
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:comp/env/jdbc/SampleDB"/>
    </bean>
    
    <context:annotation-config />
    <context:component-scan base-package="com.apuntesdejava.db"/>
</beans>

Entre las líneas 10 al 12 es importante, ya que allí es donde se establece la conexión a la base de datos. Además, en la línea 15 nos indica que comenzará a barrer todas las clases que serán interpretadas como beans de Spring, y los instanciará y asociará según sea lo necesario.

4. Clase que accede a Spring

Tendremos una clase Singleton (que será como una instancia Global) que nos permitirá acceder a las clases de Lógica negocio (o también llamados Servicios).

package com.apuntesdejava.db.util;

import com.apuntesdejava.db.service.PersonService;
import com.apuntesdejava.db.service.ProductService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 *
 * @author diego
 */
public class ApplicationBeans {

    private final ApplicationContext context;

    private ApplicationBeans() {
        context = new ClassPathXmlApplicationContext("spring.xml");
    }

    public static ApplicationBeans getInstance() {
        return ApplicationBeansHolder.INSTANCE;
    }

    private static class ApplicationBeansHolder {

        private static final ApplicationBeans INSTANCE = new ApplicationBeans();
    }

    public PersonService getPersonService() {
        //con JDBC
        return context.getBean(PersonService.class);
    }

5. Servicio: Interfaz e Implementación


PersonService tendrá el ejemplo para acceder usando JDBC. Aquí solo colocamos la interfaz, luego Spring sabrá cuál se instanciará.

Esta es la interfaz
Esta es la implementación. Así de simple.

6. Implementando de DAO con JDBC

De la misma manera, se asocia la interfaz para el DAO PersonDao, y Spring sabrá qué clase usar para instanciar.

Esta es la interfaz del DAO...
...y esta es su implementación con JDBC.

7. JSPs para listar y formulario de edición

Crearemos el archivo /src/main/webapp/persons/index.jsp que es el que visualizará el contenido de la tabla Person. Aquí accederemos al servicio PersonService y dejaremos que todo lo implementando antes fluya:
Como se puede ver, el código es practicamente limpio, ya que el acceso a la base de datos se ha hecho simple a través de su clase de servicio

Ahora, para crear un nuevo registro, el JSP es bastante simple:
Si pueden notar la línea 16, el action apunta a un servlet que ahora lo vamos a crear.

8. Servlet Controlador del formulario Person


La línea 56 es crucial: Simplemente se pasan los parámetros al servicio (que fue instanciado en la línea 50) y el registro en la base de datos es transparente.

Spring ya nos instanció tranquilamente la clase DAO para JDBC utilizando el DataSource configurado en la aplicación mediante el archivo context.xml.

9. Preparando la conexión con JPA

¿Y si queremos usar las funcionalidades de JPA, y en Tomcat? Aquí tengo la explicación.

Antes que nada, el archivo persistence.xml puede estar configurado con todos los valores para conectarse a la base de datos. Pero en honor a la reutilización, esto sería un desperdicio.. ya que la conexión a la base de datos ya está en el archivo context.xml, y nuestra parte de JDBC funciona bien... entonces ¿para que volver a crear la conexión a la base de datos?. Afortunadamente, JPA permite configurar usando el JNDI de un DataSource... y esta sería la configuración del archivo


Tomcat, tal cual como está "sacado de caja" no permite conexiones JTA. Por ello la configuración es RESOURCE_LOCAL.

10. Dependencias para JPA (con Hibernate)

Agregaremos esta dependencia en el pom.xml para usar el JPA implementado en Hibernate.
        <!-- JPA / Hibernate  -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-jpamodelgen</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <!-- FIN JPA / Hibernate -->

11. Método para la clase Spring

Agregamos en la clase com.apuntesdejava.db.util.ApplicationBeans el método
    public ProductService getProductService() {
        //con JPA
        return context.getBean(ProductService.class);
    }

12. Interfaz e Implementación del Servicio Product

Es igual que con JDBC. Aquí está la interfaz:
Y aquí la implementación:

13. Implementación del JPA

Spring nos instancia los objetos necesarios de tal manera que solo lo usemos de manera transparente. Aquí está la interfaz para DAO (bastante simple, luce igual que el JDBC, claro.. porque es la interfaz):
Y aquí el DAO implementado


El Spring nos ayudó a implementar JPA reutilizando la conexión de la base de datos del Tomcat. Sin ello, la conexión - realmente - se hace un poco complicado, declarando más variables y más objetos.

14. Para terminar: Los JSPs y el Servlet Controlador

Esto ya no tiene mucha explicación:

El Listado:


El Formulario:


El Servlet Controlador:


15. Los Recursos

Aquí está el código fuente para que lo puedan examinar, revisar y hacer lo que necesiten:

Comentarios

Entradas más populares de este blog

RESTful... la forma más ligera de hacer WebServices (Parte 1)

Quienes hayan usado SOAP para WebService, sabrán que es bien fácil de diseñar, pero algo complicado de consumir: se necesita toda una API para construir los clientes utilizando el WSDL. Por ejemplo, para PHP se necesita de la biblioteca NuSOAP. Entonces, para lograr el concepto de "lenguaje único XML" es un dolor de cabeza. Y más aún si el cliente es tan simple como JavaScript, manejar XML de SOAP provocaría suicidos masivos... o no usar WebServices.

Además, con SOAP se permite crear un solo servicio y ponerle varios métodos. Esto puede llevar a un mal diseño del servicio ya que podría tener un servicio que haga de todo: por ejemplo, un servicio de manejo de Clientes que permita también manejar Proveedores.

RESTful es una propuesta muy interesante de Roy Fielding que permite manejar los servicios web con métodos definidos, manteniendo la simpleza del protocolo como XML, pero que cada servicio sea identificado únicamente con un solo URI.

En este post veremos cómo crear un Ser…

¿Por valor o por referencia?

Esta es una pregunta existencial para todo programador Java. Cada uno encuentra una respuesta satisfactoria. Pero ahora veremos, basándonos en el libro para Certificación SCJP 1.5 de Katty Sierra, sobre la respuesta correcta.

Contraseñas encriptadas con Java

¿Quién no ha querido encriptar texto o archivo? Hay diversas maneras para hacer eso, por ejemplo, utilizando un diccionario donde se reemplazara cada caracter por un código.. y para poder desencriptarlo se debería utilizar el mismo diccionario para revertir el proceso. Pero si el diccionario cae en manos de alguien que no queremos que lo sepa, entonces estamos en peligro.
Cuando yo programaba en pascal, mi encriptación favorita era invirtiendo los bits... pero cualquiera también puede invertir los bits y listo.
Pero ya gente experta logró algoritmos de encriptación populares. Los más conocidos: MD5 y SHA.
En este post hablaremos cómo encriptar texto, sobretodo las contraseñas, utilizando MD5 o SHA.