Archive for junio, 2009
Descripción de iBatis: ¿Qué es?, ¿para qué sirve?
iBatis es un framework de persistencia para Java, aunque con bastantes diferencias respecto a Hibernate, el gran dominador en este segmento.
La principal diferencia entre iBatis e Hibernate es que iBatis no es un ORM (Mapeo Objeto Relacional). Por lo tanto Hibernate genera el SQL para mapear objetos a tablas de la base de datos, mientras que en iBatis el SQL lo tendremos que escribir nosotros. Si tenemos un modelo de datos (nuestras tablas de BBDD) bastante diferente a nuestro modelo de negocio (nuestras clases Java) Hibernate nos puede dar bastantes dolores de cabeza.
Lo que sí hace iBatis es lo siguiente:
- Ejecuta el SQL escrito por nosotros mediante JDBC[] (Java DataBase Connectivity), por lo que nos olvidamos de los múltiples try/catch.
- Mapea propiedades de objetos a parámetros para las PreparedStatement (sentencias SQL parametrizables).
- Mapea los resultados de una query a un objeto o una lista de objetos.
En esta entrada ahora podría poner un pequeño ejemplo de utilización de iBatis, pero eso es lo que podemos encontrar en la documentación de iBatis en español.
Como resumen de lo que se puede ver en dicah documentación comentar:
- Tendremos un fichero de configuración de iBatis (SqlMapConfig.xml habitualmente) en el que indicaremos algunos parámetros de iBatis (como si está activo el cacheado), el
DataSource
(soporta varios tipos deDataSource
) y los distintos mapeos SQL. - Tendremos al menos un fichero de mapeo xml, en el que se indican las sentencias SQL, los parámetros a mapear o los resultados a mapear.
- Tendremos una clase que implementa
SQLMapClient
que es el interface que contiene los métodos para realizar las sentencias SQL (queryForObject
,queryForList
odelete
entre otros muchos). Esta clase la habremos obtenido medianteSqlMapClientBuilder
.
Otro punto fuerte de iBatis es su integración con Spring. Para trabajar con iBatis integrado en Spring los pasos a seguir serían los siguientes:
- El
DataSource
lo definiremos como un Bean en los archivos de definición de Spring. El resto del SqlMapConfig.xml y los xml de mapeo seguirían igual. - Spring proporciona el
SqlMapClientFactoryBean
ySqlMapClientTemplate
. A la factoría le proporcionaremos el DataSource y al template le proporcionamos la factoría. Ese template es la clase que nos proporciona los mismo métodos que elSQLMapClient
visto anteriormente.
También quiero nomrar en esta entrada a Ibator, que es una herramienta para generar código para iBatis. A partir de una tabla de base de datos es capaz de generar el xml de mapeo, las clases Java que representan al modelo de datos e incluso los DAO (Objetos de Acceso a Datos). Viene incluido un plugin para Eclipse. Aunque no la he utilizado, puede ser una herramienta útil en ocasiones.
Y por último decir que aunque sólo he hablado de iBatis para Java, desde la página del proyecto nos podemos descargar versiones para .Net o Ruby.
AJAX en CakePHP mediante jQuery
Hace poco hemos visto cómo utilizar AJAX en un formulario con CakePHP y hemos hablado en varias ocasiones de jQuery. Ahora vamos a ver cómo utilizar jQuery a través de CakePHP.
Dean Sofer comenta en Serving up actions as AJAX with jQuery in a few simple steps ( en inglés) que él no cree necesario un helper AJAX para jQuery (recordemos que el helper AJAX de CakePHP utiliza script.aculo.us) ya que un helper se utiliza para crear HTML y el javaScript debería estar lo más separado del HTML como sea posible (separación de funciones).
En este ejemplo vamos a modificar el código de nuestra aplicación de gestión de enlaces tal y como lo dejamos tras utilizar el formulario AJAX para insertar nuevos enlaces. Quitaremos todas las referencias al Helper de AJAX y le daremos la misma funcionalidad mediante jQuery.
Vamos a ver primero el controlador, explicando los cambios.
<?php class LinksController extends AppController { var $name = 'Links'; var $helpers = array('Html', 'Form', 'Javascript'); var $components = array('RequestHandler'); function add() { if (!empty($this->data)) { if ($this->Link->save($this->data)) { //$this->flash('Enlace añadido.','/links',3); } } $this->set('links', $this->Link->findAll()); //$this->render('index', 'ajax'); $this->render('list'); } function index() { $this->set('links', $this->Link->findAll()); } } ?>
- Eliminamos el helper de AJAX, aunque mantenemos el de JavaScript.
- Añadimos el componente
RequestHandler
. Este componente identifica las peticiones vía AJAX para poder responder con el layout AJAX (por defecto vacío). Como ahora sólo vamos a hacer llamadas aadd()
mediante AJAX podríamos omitir este componente y realizar la llamada a la vista mediante$this->render('list','ajax');
(hemos añadido el parámetro que indica el layout a utilizar). - Hemos cambiado la vista a mostrar por
list
, que veremos a continuación.
Ahora vemos la vista principal (/app/views/links/index.ctp):
<?php echo $javascript->link('jquery-1.3.1.min.js',false); echo $javascript->link('jquery.form.js',false); ?> <script type="text/javascript"> $(document).ready(function() { var options = { target:'#links', clearForm: true }; $('#newLinkForm').ajaxForm(options); }); </script> <h1>Enlaces disponibles</h1> <div id="links"> <?php echo $this->element('linksList', array('links' => $links)); ?> </div> <h2>Añadir enlace</h2> <?php echo $form->create('Link', array('action' => 'add', 'id' => 'newLinkForm')); echo $form->input('title', array('label' => 'Nombre', 'error' => __('Titulo no valido', true))); echo $form->input('url'); echo $form->submit('Añadir',array('escape'=>false)); echo $form->end(); ?>
- Lógicamente he sustituido los links a script.aculo.us por los de jQuery. Utilizo el plugin jQuery Form Plugin que me facilita la introducción de AJAX en el formulario.
- Añado el código JavaScript prácticamente como aparece en la página de jQuery Form Plugin. En
target
se le indica el div en el que se va a introducir la respuesta (en este caso el que tenga id «links»). Al final le aplicamos el métodoajaxForm
al formulario con id «newLinkForm». - He sustituido todo el listado de links por una llamada a un elemento CakePHP pasándole unos datos (
$this->element('linkslist', array('links' => $links));
). Luego explicaré el por qué de este cambio. - La creación del formulario la hago como inicialmente mediante el helper de formularios (ya no mediante el de AJAX). Le pongo el id como parámetro.
Vamos a ver ahora el elemento al que hacíamos referencia en la vista. Lo encontraremos en /app/views/elements/linksList.ctp.
<?php foreach ($links as $link): ?> <p> <a href="<?php echo $link['Link']['url']; ?>"><?php echo $link['Link']['title']; ?></a></p> <p>Añadido: <?php echo $link['Link']['created']; ?></p> <ul> <?php foreach ($link['Comment'] as $comment): ?> <li><?php echo $comment['comment'] . ' (' . $comment['created'] . ')'; ?></li> <?php endforeach; ?> <li><?php echo $html->link('Añadir comentario', '/comments/add/' . $link['Link']['id']);?></li> </ul> <?php endforeach; ?>
Como podemos ver es exactamente el mismo código que teníamos en la página principal y que generaba el listado de enlaces. Lo que hemos hecho es crear un elemento de CakePHP, es decir, una porción reutilizable. Y la reutilizamos en la página principal y en la nueva vista que hemos creado para la respuesta AJAX, que sólo tiene que contener el listado. Vemos dicha vista (/app/views/links/list.ctp) a continuación:
<?php echo $this->element('linkslist', array('links' => $links)); ?>
Y con esto ya tenemos funcionando el formulario AJAX mediante jQuery.
Comentarios recientes