Está en la página 1de 8

Apuntes de Java

Pgina principal Comparator y Comparable Inicializadores Dao y Spring Sitemap Contenidos 1 Introduccin 2 Usando JDBC 2.1 RowMapper 2.2 Y el jdbcTemplate? 2.3 Y cmo el Spring pone el v alor del DataSource? 2.4 Proy ecto ejemplo

Buscar en este sitio

Pgina principal >

Dao y Spring

Acerca de
Este sitio pretende tener apuntes de Jav a que v oy encontrando y puede ser til (en principio para mi) para la comunidad.

3 Usando IBatis Est estructurado como 3.1 Archiv os .XML para iBATIS una pgina web 3.2 beans.xml para iBATIS ordenada, y a que en mi 3.3 La implementacin del acceso a IBatis. blog 3.4 http://apuntesdejav a.blogspot.com/ Proy ecto ejemplo 4 Usando JPA resulta ser muy 4.1 La clase entidad complicada la edicin :) 4.2 beans.xml para JPA 4.3 Implementacin de la interf az ProductDao 4.4 Proy ecto ejemplo 5 El resto del proy ecto 5.1 El DAOFactory 5.2 La interf az Dao: ProductoDao 5.3 El cliente: ProductManagedBean 6 Proy ectos utilizados

Introduccin
Spring es un poderoso framework para java donde su principal objetivo (y muy til) es la instanciacin de objetos. Desde nuestros programas - en vez de hacer new() y con cientos de inicializaciones de valores - simplemente obtenemos el objeto ya armadito desde el spring. Lo que veremos en este micro tutorial es cmo usar Spring bajo el patrn Dao y patrn Factory. Veremos una aplicacin web (usando JSF) que accede a la base de datos "sample" que viene incluido en el NetBeans. Nuestra aplicacin se ejecutar en Glassfish, y debe contar con un JDBC Resource que accede a la base de datos mencionada. En los ejemplos publicados, veremos que existe el archivo sun-resources.xml que contiene la configuracin del JDBC Resource y JDBC Pool para crear el DataSource en nuestro Glassfish:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE resources PUBLIC "-//Sun Microsystems, Inc.//DTD Application Serv

<resources>

<jdbc-resource enabled="true" jndi-name="jdbc/sample" object-type="user" <description/> </jdbc-resource> <jdbc-connection-pool allow-non-component-callers="false" associate-with<property name="URL" value="jdbc:derby://localhost:1527/sample"/> Esta intentando <property name="serverName" value="localhost"/> ingresar a un sitio <property name="PortNumber" value="1527"/> bloqueado por <property name="DatabaseName" value="sample"/> polticas de <property name="User" value="app"/> navegacin. <property name="Password" value="app"/> </jdbc-connection-pool> URL: </resources> pagead2.googlesyndication.com/pagead /ads?client=capub-7760122649700122& En resumen, para acceder a nuestra base de datos lo haremos por el dataSource, format=120x600_as& usando el JDNI: j dbc/sample. output=html& h=600&w=120& Usando JDBC lmt=1330737114& host=pub6693688277674466& RowMapper ad_type=text_image& color_bg=FFFFFF& Este es quizs la manera de acceder a la base de datos ms simple y bsica. color_border=FFFFFF& color_link=000000& Recordemos que cuando usbamos un JDBC normal, despus de hacer un color_text=5E6A72& executeQuery(), haciamos un while (rs.next()) y dentro del bucle haciamos color_url=4E7DBF& un new a cada objeto por cada fila y lo agregbamos a una lista. Pues con el flash=11.1.102& Spring es lo mismo, pero nos da una ayudadita. url=http%3A%2F %2Fsites.google.com%2Fsite%2Fapuntesdeja y-spring& public List getProducts() { dt=1331041529397& bpp=8& RowMapper mapper = new RowMapper() { shv=r20120229& jsv=r20110914& public Object mapRow(ResultSet rs, int rowNum) throws SQLExcept correlator=1331041530048& //se lee cada campo como en el while de un ResultSet comun Product p = new Product(); p.setProductId(rs.getInt("PRODUCT_ID")); p.setManufacturerId(rs.getInt("MANUFACTURER_ID")); p.setProductCode(rs.getString("PRODUCT_CODE")); p.setPurchaseCost(rs.getDouble("PURCHASE_COST")); p.setQuantityOnHand(rs.getInt("QUANTITY_ON_HAND")); p.setMarkup(rs.getFloat("MARKUP")); p.setAvailable(rs.getString("AVAILABLE")); p.setDescription(rs.getString("DESCRIPTION")); return p; } }; List list = jdbcTemplate.query("SELECT * FROM Product", mapper); return list; } El Spring es el que hace el executeQuery() y le decimos cmo lo va a tratar por cada fila del resultado. Esto se hace implementado la interfaz

org.springframework.jdbc.core.RowMapper. Para mayor informacin como hacer queries desde Spring, visitar: http://static.springframework.org/spring/docs/2.5.x/reference/jdbc.html

Y el jdbcTemplate?
Pues este objeto es una propiedad que fue recibida desde el Spring: private JdbcTemplate jdbcTemplate; public void setDataSource(DataSource ds) { jdbcTemplate = new JdbcTemplate(ds); }

Y cmo el Spring pone el valor del DataSource?


As:

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactory <property name="jndiName" value="jdbc/sample" /> </bean> <bean id="ProductDao" class="dao.derby.DerbyProductsDao"> <property name="dataSource" ref="dataSource" /> </bean>

Proyecto ejemplo
http://diesil-java.googlecode.com/files/SpringDaoJdbc.tar.gz

Usando IBatis
iBATIS es un framework de Apache que consiste en mapear las consultas y los objetos que son resultado de las consultas o que son usados como parmetros de ellas. Solo hace eso: mapea consultas. No confundir ni comparar con JPA. Con iBATIS, ya no se tiene que poner los comandos SQL dentro de los programas Java, sino se usa un archivo .xml.

Archivos .XML para iBATIS


Este es el contenido del archivo Product.xml que contiene las consultas que refiere a la tabla PRODUCT: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"> <sqlMap namespace="sample"> <resultMap id="productResult" class="beans.Product"> <result property="productId" column="PRODUCT_ID" /> <result property="manufacturerId" column="MANUFACTURER_ID" /> <result property="productCode" column="PRODUCT_CODE" /> <result property="purchaseCost" column="PURCHASE_COST" /> <result property="quantityOnHand" column="QUANTITY_ON_HAND" />

<result property="markup" column="MARKUP" /> <result property="available" column="AVAILABLE" /> <result property="description" column="DESCRIPTION" /> </resultMap> <select id="productSelect" resultMap="productResult"> SELECT * FROM PRODUCT </select> </sqlMap> Como se puede ver, el mapeo de cada columna con cada propiedad del objeto beans.Product est dado en el tag <resultMap> y es utilizado en el <select>. iBATIS ya sabe que cada resultado de ese query ser mapeado por el resultMap="productResult". El archivo de configuracin de iBATIS requiere cierta configuracin para acceder a la base de datos; pero usando Spring, el archivo quedar reducido a lo siguiente: (Archivo SqlmapConfig.xml) <sqlMapConfig> <sqlMap resource="Products.xml" </sqlMapConfig>

/>

beans.xml para iBATIS


Ahora, necesitamos configurar el beans.xml para que la conexin a la base de datos lo configure a nuestro iBATIS.

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactory <property name="jndiName" value="jdbc/sample" /> </bean> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapCli <property name="configLocation" value="classpath:SqlmapConfig.xml <property name="dataSource" ref="dataSource"/> </bean> <bean id="ProductDao" class="dao.ibatis.IBatisProductsDao"> <property name="sqlMapClient" ref="sqlMapClient" /> </bean>

La implementacin del acceso a IBatis.


Ahora, nuestra clase para manejar el IBatis es el siguiente:

public class IBatisProductsDao extends SqlMapClientDaoSupport implements Pr

public List getProducts() { List list = getSqlMapClientTemplate().queryForList("productSelect") // solo llama a la consulta return list; } } Por la herencia de la clase org.springframework.orm.ibatis.support.SqlMapClientDaoSupport, se tiene el mtodo setSqlMapClient(), que es lo que se est usando en el archivo beans.xml

Para mayor informacin de cmo usar IBatis con Spring, ver: http://static.springframework.org/spring/docs/2.5.x/reference/orm.html#orm-ibatis

Proyecto ejemplo
http://diesil-java.googlecode.com/files/SpringDaoIBatis.tar.gz

Usando JPA
Ser necesario usar Spring con JPA? Si vamos usar el patrn DAO + Factory, definitivamente que s. Ya que el Factory se encargar de devolver una interfaz implementada segn sea haya decidido usar. La aplicacin misma no cambia, solo cambiar la implementacin del acceso a la base de datos.

La clase entidad
Para usar JPA, es necesario hacer unos ajustes a nuestros Objetos de Transferencia (Transfer Objects, es decir, los objetos que usamos para mostrar en el lista y obtener datos de la base de datos). Es necesario que sean declarados como Entidades. @Entity @Table(name = "PRODUCT") public class Product implements Serializable { private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @Column(name = "PRODUCT_ID") private Integer productId; @Column(name = "PURCHASE_COST") private BigDecimal purchaseCost; @Column(name = "QUANTITY_ON_HAND") private Integer quantityOnHand; @Column(name = "MARKUP") private BigDecimal markup; @Column(name = "AVAILABLE") private String available; @Column(name = "DESCRIPTION") private String description; @Column(name="MANUFACTURER_ID") private int manufacturerId; @Column(name="PRODUCT_CODE") private String productCode; //...

beans.xml para JPA


El archivo persistence.xml ya tiene la conexin a la base de datos por el JNDI del datasource. Pero ahora lo que nos tiene que preocupar es acceder desde nuestra implementacin de ProductoDao usando JPA. NetBeans tiene un asistente para acceder al JPA usando el JNDI, pero como nuestra implementacin de ProductoDao no es un componente de JEE, entonces nos va a generar bastante cdigo con referente a Context y demas cosas de JNDI. Lo ideal es que se use anotaciones. Para ello, debemos considerar lo siguiente en nuestro beans.xml.

<bean id="emf" class="org.springframework.orm.jpa.LocalEntityManagerFac <property name="persistenceUnitName" value="SpringDaoJpaPU"/> </bean> <context:annotation-config /> <bean id="ProductDao" class="dao.jpa.JpaProductDao"/> El tag <context:annotacion-config/> es el que se encargar de permitir las anotaciones en nuestra implementacin de ProductDao.

Implementacin de la interfaz ProductDao


Ahora bien, nuestra implementacin de la interfaz ProductDao es como sigue: @Repository public class JpaProductDao implements ProductDao { @PersistenceUnit(unitName = "SpringDaoJpaPU") private EntityManagerFactory emf; @Transactional(readOnly = true) public List getProducts() { EntityManager em = emf.createEntityManager(); try { Query q = em.createQuery("SELECT p FROM Product p"); return q.getResultList(); } finally { if (em != null) { em.close(); } } } } Y todo lo dems, sigue igual.

Proyecto ejemplo
http://diesil-java.googlecode.com/files/SpringDaoJpa.tar.gz

El resto del proyecto


Como hemos visto, nos hemos centrado ms en el acceso a la base de datos que en la aplicacin en s.

El DAOFactory
Esa es la idea del DAO + Factory: solo cambiar el acceso a la base de datos, el resto de la aplicacin no debe sufrir modificacin alguna. De tal manera que si se necesita cambiar la manera de acceder a la base de datos, solo se necesita cambiar en el beans.xml la implementacin que necesitemos:

<!-- Usando JDBC --> <bean id="ProductDao" class="dao.derby.DerbyProductsDao"> <property name="dataSource" ref="dataSource" /> </bean> <!-- usando Ibatis --> <bean id="ProductDao" class="dao.ibatis.IBatisProductsDao"> <property name="sqlMapClient" ref="sqlMapClient" /> </bean> <!-- usando JPA --> <bean id="ProductDao" class="dao.jpa.JpaProductDao"/> Los tres casos son accedidos por el nombre "ProductDao". Esto quiere decir que nuestra clase DAOFactory, deber tener el siguiente cdigo: public class DaoFactory { private static DaoFactory instance; private synchronized static DaoFactory newInstance() { return new DaoFactory(); } private BeanFactory factory;

private DaoFactory() { ApplicationContext ctx = new ClassPathXmlApplicationContext("/beans factory = (BeanFactory) ctx; } public static DaoFactory getInstance() { if (instance == null) { instance = newInstance(); } return instance; } public ProductDao getProductDao() { return (ProductDao) factory.getBean("ProductDao"); } }

La interfaz Dao: ProductoDao


ProductDao es una interfaz que solo tiene los mtodos a implementar. No tiene nada ms. As que nuestro DaoFactory no sabr qu devolver el mtodo factory.getBean(). Solo sabe que lo que devuelva ser una interfaz ProductDao. public interface ProductDao { List getProducts(); }

El cliente: ProductManagedBean
El objeto que usar el DAOFactory para acceder a la base de datos, queda reducido a lo siguiente:

private ProductDao productDao; private List list; public ProductManagedBean() { productDao = DaoFactory.getInstance().getProductDao(); } public List getProducts() { if (list == null) { list = productDao.getProducts(); } return list; } En nuestra aplicacin es el ManagedBean encargado de mostrar el listado en el JSP.

Proyectos utilizados
JDBC: http://diesil-java.googlecode.com/files/SpringDaoJdbc.tar.gz iBatis: http://diesil-java.googlecode.com/files/SpringDaoIBatis.tar.gz JPA: http://diesil-java.googlecode.com/files/SpringDaoJpa.tar.gz

Acceder | Informar de uso inadecuado | Imprimir pgina | Eliminar acceso | Con la tecnologa de Google Sites