Persistencia Básica en Java

4
86902

Persistencia Básica en Java

Cuando abordamos el desarrollo de una
aplicación en Java, uno de los primeros requerimientos que
debemos resolver es la integración con una base de datos para
guardar, actualizar y recuperar la información que utiliza
nuestra aplicación.

Se llama “persistencia” de
los objetos a su capacidad para guardarse y recuperarse desde un
medio de almacenamiento. La persistencia en Base de Datos
relacionales se suele implementar mediante el desarrollo de
funcionalidad específica utilizando la tecnología JDBC
o mediante frameworks que automatizan el proceso a partir de mapeos
(conocidos como Object Relational Mapping, ORM) como es el caso de
Hibernate.

Si bien existen más alternativas
de persistencia, en este tutorial aboraremos estas dos alternativas
ya que son las más frecuentemente utilizadas.

Los código fuente que se
muestran a continuación son fragmentos del Zip que se puede
encontrar en PersistenciaBasicaEnJava.zip

JDBC

Java DataBase Connectivity es el API de
Java que define cómo una aplicación cliente accederá
a una base de datos, independientemente del motor de base de datos al
que accedamos.

A continuación mostramos un
ejemplo del código necesario para insertar un elemento y hacer
una consulta:

//
Cargar el driver

Class.forName(jdbcDriver);

//
Crear una conexión

Connection
con = DriverManager.getConnection(jdbcUrl, userName,

password);

//
Crear un Statement para obtener el máximo id

Statement
stmt = con.createStatement();

ResultSet
rs = stmt.executeQuery(
«SELECT
MAX(id) FROM «
+ schema

+
«DEMO_QUERIES»);

int
id = 0;

if
(rs.next()) {

id
= rs.getInt(1) + 1;

}

rs.close();

stmt.close();

//
Crear un PreparedStatement para insert

PreparedStatement
prepareInsert = con.prepareStatement(

«INSERT
INTO »
+ schema + «DEMO_QUERIES
(id, nombre, fecha)”

+
“VALUES (?, ?, ?)»
);

//
Completar sus atributos

int
i = 1;

prepareInsert.setInt(i++,
id);

prepareInsert.setString(i++,
«Ejemplo JDBC»);

prepareInsert.setDate(i++,
new
Date((
new Date()).getTime()));

//
Ejecutar el insert

prepareInsert.executeUpdate();

prepareInsert.close();

//
Crear un PreparedStatement para select

PreparedStatement
prepareSelect = con

.prepareStatement(«SELECT
id, nombre, fecha FROM «
+ schema

+
«DEMO_QUERIES WHERE fecha < ?»);

//
Completar sus atributos

prepareSelect.setDate(1,
new
Date((
new
java.util.Date()).getTime()

+
DAY_IN_MILLIS));

//
Ejecutar la select

rs
= prepareSelect.executeQuery();

while
(rs.next()) {

System.out.println(«Id
= «
+ rs.getInt(1) + »
– nombre = «

+
rs.getString(2) +
» – fecha = «
+ rs.getDate(3) +
«»);

}

rs.close();

prepareSelect.close();

Como vemos el código
es esencialmente simple aunque si tenemos un número amplio de
clases y problemáticas de maestro/detalle (como pueden ser
facturas con items) o soporte multi-base de datos la implementación
puede volverse muy difícil de mantener.

Una mejora a la mantenibilidad es
utilizar el patrón de diseño Data Access Object (DAO,
Objeto de Acceso a Datos ver
http://es.wikipedia.org/wiki/Data_Access_Object) donde básicamente
definimos una interfaz y una clase que concentren toda la
funcionalidad de creación, lectura, actualización y
borrado en la base de datos.

Hibernate

En Hibernate esta misma funcionalidad
se simplifica a:

Entidad
entidad =
new
Entidad();

entidad.setId(id);

entidad.setNombre(«Ejemplo
Hibernate\n»
);

Session
session =
sessionFactory.getCurrentSession();

session.beginTransaction();

session.save(entidad);

session.getTransaction().commit();

O para obtener el listado:

Session
session =
sessionFactory.getCurrentSession();

session.beginTransaction();

Query
q = session

.createQuery(«from
e in class com.persistencia.hibernate.Entidad where e.fecha <
:fecha»
);

//
se inyecta el valor del parámetro utilizando el nombre

q.setParameter(«fecha»,
new
java.sql.Date(fecha.getTime()));

List
entidades = q.list();

¿¡¿Pero cómo
funciona la magia?!? Bueno, Entidad es un POJO (Plain Old Java
Object), es decir una simple clase Java que tiene métodos get
y set para cada uno de los atributos; así que ahí no
está la magia.

Es en el fichero de mapeo donde ponemos
la magia, que tampoco es tan complicada:

<hibernate-mapping>

<class
name=«com.hemasoft.demos.queries.hibernate.Entidad»

table=«DEMO_QUERIES»>

<id
name=«id»
type=«java.lang.Integer»
/>

<property
name=«nombre»
/>

<property
name=«fecha»
type=«java.sql.Date»
/>

</class>

</hibernate-mapping>

Este fichero de mapeo lo declaramos en
hibernate.cfg.xml junto a la información de acceso a la base
de datos de la siguiente forma:

<hibernate-configuration>


<session-factory>


<!–
Database connection settings –>


<property
name=«connection.driver_class»>oracle.jdbc.driver.OracleDriver</property>


<property
name=«connection.url»>jdbc:oracle:thin:@192.168.1.20:1521:qemu</property>


<property
name=«connection.username»>test</property>


<property
name=«connection.password»>test</property>


<!–
JDBC connection pool (use the built-in) –>


<property
name=«connection.pool_size»>1</property>


<!–
SQL dialect –>


<property
name=«dialect»>org.hibernate.dialect.Oracle9Dialect</property>


<mapping
resource=«com/hemasoft/demos/queries/hibernate/Entidad.hbm.xml»/>


</session-factory>

</hibernate-configuration>

Creo que el fichero es lo
suficientemente intuitivo como para no necesitar mayores
explicaciones.

Los costes de aprendizaje de este
framework en términos de tiempo dedicado se van recompensando
desde el primer día con el ahorro en tiempo de desarrollo y
depuración de código JDBC. Incluso, a partir de la
versión 3 de Hibernate su configuración se simplifica
notablemente mediante Anotaciones (recomiendo ver
http://www.hibernate.org/hib_docs/annotations/reference/en/html_single/#entity-mapping).

Además, Hibernate nos
proporciona grandes beneficios como:

  • soporte a múltiples motores
    de base de datos

  • bajo acoplamiento entre negocio y
    persistencia, ya que su diseño está orientado a
    objetos así como el soporte a consultas y operaciones (HQL).

  • desarrollo robusto, ya que el
    framework ha madurado tras años de uso en decenas de miles de
    proyectos

  • optimizado, ya que el SQL generado
    contiene optimizaciones específicas para cada motor de base
    de datos mediante componentes especializados llamados dialectos.

  • rápido y completo, ya que
    con la funcionalidad estándar de Hibernate podremos cubrir el
    80 – 90% de la persistencia de nuestra aplicación

    Todo esto nos permite centrar nuestros
    esfuerzos en desarrollar la funcionalidad de la aplicación.

Conclusiones

El acceso mediante JDBC conviene
utilizarlo cuando tenemos pocas clases, escasos conocimientos, escaso
tiempo para formación, modelo de datos muy desnormalizado o
alguna otra razón de peso.

Para todo lo demás, Hibernate es
una solución madura y dinámica que nos permite
simplificar a la vez que robustecer nuestro acceso a bases de datos.

Desde Autentia
(http://www.autentia.com) os
animamos a que utilicéis este tipo de tecnologías.
Basta ya de reinventar la rueda en cada desarrollo. Debemos construir
en función de patrones y estándares, y reutilizando al
máximo. Esto nos permite centrarnos en la lógica de
negocio, reducir los tiempos de desarrollo, y aumentar la calidad del
resultado.

4 Comentarios

Dejar respuesta

Please enter your comment!
Please enter your name here