Dao y Spring - Apuntes de Java
Dao y Spring - 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
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); }
<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.
<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>
/>
<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>
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; //...
<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.
Proyecto ejemplo
http://diesil-java.googlecode.com/files/SpringDaoJpa.tar.gz
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"); } }
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