Sunteți pe pagina 1din 37

Desarrollo de Aplicaciones

Java con Spring

Fernando Rincn Martn


3. Acceso a datos
Soporte de Diferentes APIs
JDBC
Hibernate
JPA
JDO
Excepciones consistentes
Arbol de excepciones nico para todas las APIs
Excepciones no checkeables
Convierte automticamente las excepciones nativas
Arbol de clases de excepciones
Acceso por JDBC
Evita todo el cdigo que no es inecesario y
repetitivo
Quin tiene qu
responsabilidad?
Accin Spring Programador
Definir los parmetros de la conexin X
Abrir conexiones X
Definir los SQL X
Declarar parmetros y proveer los valores X
Peparar y ejecutar una sentencia X
Realizar el loop si hubiera resultados X
Realizar el trabajo dentro del loop X
Procesar las excepciones X
Manejar las transacciones X
Cerrar conexiones, sentencias y resultsets X
Inicializacin de Beans
Es necesario un DataSource para poder realizar
consultas a la base de datos
Por lo general, el DataSource se establece mediante
IoC en las clases.
public class JdbcMovieFinder implements MovieFinder {

private JdbcTemplate jdbcTemplate;

public JdbcMovieFinder(DataSource dataSource) {


this.jdbcTemplate = new JdbcTemplate(dataSource);
}

// ...

}
Templates JDBC
Clases para ejecutar comandos JDBC desde el
Framework.
Realizan todo el trabajo entre bastidores.
Simplifican el uso de JDBC
Templates JDBC
JdbcTemplate La base para todas las demas
Templates.
NamedParameterJdbcTemplate Template para usar
parmetros con nombre en las sentencias (a
diferencia de los parmetros estadard ?)
SimpleJdbcTemplate Simplificacin de las dos
anteriores, para uso simplificado
SimpleJdbcInsert Simplifica las inserciones
SimpleJdbcCall Simplifica las llamadas a
procedimientos SQL
JdbcTemplate
Es la clase base.
Con esta template se pueden realizar todas las
operaciones sobre la base de datos.
JdbcTemplate Ejemplos -
Select
int rowCount = this.jdbcTemplate.queryForInt("select count(*) from t_actor");

int countOfActorsNamedJoe = this.jdbcTemplate.queryForInt(


"select count(*) from t_actor where first_name = ?", "Joe");

String lastName = this.jdbcTemplate.queryForObject(


"select last_name from t_actor where id = ?",
new Object[]{1212L}, String.class);

Actor actor = this.jdbcTemplate.queryForObject(


"select first_name, last_name from t_actor where id = ?",
new Object[]{1212L},
new RowMapper<Actor>() {
public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {
Actor actor = new Actor();
actor.setFirstName(rs.getString("first_name"));
actor.setLastName(rs.getString("last_name"));
return actor;
}
});
JdbcTemplate Ejemplos -
Select
List<Actor> actors = this.jdbcTemplate.query(
"select first_name, last_name from t_actor",
new RowMapper<Actor>() {
public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {
Actor actor = new Actor();
actor.setFirstName(rs.getString("first_name"));
actor.setLastName(rs.getString("last_name"));
return actor;
}
});
JdbcTemplate Ejemplos -
Insert/Update/Delete
this.jdbcTemplate.update(
"insert into t_actor (first_name, last_name) values (?, ?)",
"Leonor", "Watling");

this.jdbcTemplate.update(
"update t_actor set = ? where id = ?",
"Banjo", 5276L);

this.jdbcTemplate.update(
"delete from actor where id = ?",
Long.valueOf(actorId));
JdbcTemplate Ejemplos Otras
Operaciones
this.jdbcTemplate.execute("create table mytable (id integer, name varchar(100))");

this.jdbcTemplate.update(
"call SUPPORT.REFRESH_ACTORS_SUMMARY(?)",
Long.valueOf(unionId));
NamedParameterJdbcTemplat
e
// some JDBC-backed DAO class...
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

public void setDataSource(DataSource dataSource) {


this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}

public int countOfActorsByFirstName(String firstName) {

String sql = "select count(*) from T_ACTOR where first_name = :first_name";

SqlParameterSource namedParameters = new MapSqlParameterSource("first_name",


firstName);

return namedParameterJdbcTemplate.queryForInt(sql, namedParameters);


}
BeanPropertySqlParameterSo
urce
Provee parmetros, buscando los mtodos en un
objeto Bean.
public int countOfActors(Actor exampleActor) {

// notice how the named parameters match the properties of the above 'Actor'
class
String sql =
"select count(*) from T_ACTOR where first_name = :firstName and last_name
= :lastName";

SqlParameterSource namedParameters = new


BeanPropertySqlParameterSource(exampleActor);

return this.namedParameterJdbcTemplate.queryForInt(sql, namedParameters);


}
Instanciacin de JdbcTemplate
Es thread-safe
Por tanto se puede usar una nica instancia por
datasource.
Por tanto, se puede configurar como bean
singleton e inyectarlo en los objetos DAO.
Traduccin de Errores
Interfaz SQLExceptionTranslator
Clase SQLErrorCodeSQLExceptionTranslator
Es la clase por defecto.
Realiza la conversin mediante cdigos de error
propietarios de la base de datos.
Por defecto, usa un bean de tipo SQLErrorCodes
Dicho bean, por defecto se crea desde el fichero sql-
error-codes.xml en el classpath
Existe un fichero con cdigos de error en el framework
DataSources
Spring no obliga a usar una Api de pool o acceso
a base de datos.
Toda la api esta basada en la clase DataSource
(clase estandar de java).
Se puede usar la mayora de Pooles (DBCP, C3PO) y
tambin usar un DataSource por JNDI (Pooles de
servidores de aplicaciones).
DriverManagerDataSource
Clase de Spring que provee un DataSource.
Devuelve una nueva conexin cada vez.
NO USAR EN PRODUCCION
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
Ejemplo Pool DBCP
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
Ejemplo JNDI
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/MyDataSource"/>
</bean>

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource"/>


Otras Funcionalidades
Operaciones Batch
JdbcTemplate.updateBatch(...)
SimpleJdbcTemplate.updateBatch(...)
Simplificaciones con SimpleJdbcInsert
Leer las claves generadas:
KeyHolder y JdbcTemplate.update(...)
SimpleJdbcInsert.usingGeneratedKeyColumns
Otras Funcionalidades
Modelado de operaciones con Objetos Java
Se pueden crear como Beans Spring
SqlQuery
MappingSqlQuery
MappingSqlQueryWithParameters
UpdatableSqlQuery
SqlUpdate
StoredProcedure
Otras Funcionalidades
Carga/Escritura de LOBs/CLOBs
DefaultLobHandler
Soporte de Bases de datos Embebidas
<jdbc:embedded-database id="dataSource">
<jdbc:script location="classpath:schema.sql"/>
<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>

Inicializacion de Bases de Datos


<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="classpath:com/foo/sql/db-schema.sql"/>
<jdbc:script location="classpath:com/foo/sql/db-test-data.sql"/>
</jdbc:initialize-database>
Practica JDBC
Crear implementacin de TercerosDAO con
acceso a base de datos.
Existen scripts de creacin, por tanto se puede
usar una base de datos embebida (HSQL).
No sobreescribir la implementacin que
tenemos, crear otra que use JDBC (en un
paquete nuevo)
Modificar el BO para que la suma use el
mtodo del DAO.
Integracin con ORM
Soporta:
Hibernate
JPA
JDO
iBATIS
Ventajas
Facil de testear
Excepciones comunes a todas las APIs
Configuraciones manejadas por Spring
Transacciones integradas con Spring
Integracin con Hibernate
Necesitamos un Bean de Session Factory.
Este necesita un DataSource

Integracin con Hibernate


<beans>

<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="mappingResources">
<list>
<value>product.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
</value>
</property>
</bean>

</beans>
Usando la Api de Hibernate
Se pueden realizar los DAO usando la api nativa de
hibernate.
Ventaja: desacople con Spring.
Inconveniente: no tiene el control de excepciones de
Spring.
Usando la Api de Hibernate
public class ProductDaoImpl implements ProductDao {

private SessionFactory sessionFactory;

public void setSessionFactory(SessionFactory sessionFactory) {


this.sessionFactory = sessionFactory;
}

public Collection loadProductsByCategory(String category) {


return this.sessionFactory.getCurrentSession()
.createQuery("from test.Product product where product.category=?")
.setParameter(0, category)
.list();
}
}
Usando la Api de Hibernate
Aunque se use la Api de Hibernate, las
transacciones son implementadas por Spring.
El objeto Session que devuelve el bean
LocalSessionFactoryBean controla las transacciones
a nivel Spring.
HibernateTemplate
Modo clsico de usar la integracin con
Hibernate.
No se aconseja en Spring 3.0
HibernateTemplate
public class ProductDaoImpl implements ProductDao {

private HibernateTemplate hibernateTemplate;

public void setSessionFactory(SessionFactory sessionFactory) {


this.hibernateTemplate = new HibernateTemplate(sessionFactory);
}

public Collection loadProductsByCategory(String category) throws


DataAccessException {
return this.hibernateTemplate.find("from test.Product product where
product.category=?", category);
}
}
Practica Hibernate
Realizar un JDO para el acceso a productos con
hibernate.
El fichero de configuracin de hibernate se adjunta en
la prctica.
Probar el acceso a productos en el mtodo Main
(Sacar la lista por la salida estandar).

S-ar putea să vă placă și