Fecha de creación del tutorial: 2006-09-07
Manual Básico de Apache iBatis
Introducción
¿Qué es iBatis?
Apache iBatis está constituido por dos frameworks independientes que generalmente se usan juntos: DAO y sqlMaps. El primero simplifica la implementación el patrón de diseño Direct Access Objects (DAO) y el segundo simplifica la persistencia de objetos en bases de datos relacionales.
iBatis NO es un ORM (Object Relational Mapper), por lo que se pueden utilizar modelos de datos existentes o poco normalizados y, finalmente, no es completamente transparente (el programador programa el SQL)
Ambos frameworks de iBatis han sido portados a .NET con notable éxito y popularidad. Ambas versiones ya son releases estables y maduras.
¿Para qué sirve?
El patrón DAO nos ayuda a organizar las tareas de persistencia (guardado, búsqueda, recuperación, borrado, etc.) de los objetos y nos permite definir múltiples implementaciones para un mismo objeto mediante la definición de una interfaz. Por ejemplo, la interfaz UsuarioDao tiene los metodos guardarUsuario(Usuario usuario), obtenerUsuario(String loginId), etc y dos implementaciones: UsuarioMySqlDao y UsuarioLdapDao donde implementamos las operaciones para MySql y Ldap respectivamente. Con iBatis DAO podremos configurar cuándo usar una u otra implementación sin necesidad de modificar código. Además, agregar un UsuarioOracleDao será muy fácil y no implicará modificar código del resto de la aplicación.
Cuando hacemos un análisis y diseño orientado a objetos obtenemos nuestro modelo de clases y también diseñamos el modelo de datos donde se almacena la información. Y siempre nos queda la tarea de conectarnos con una base de datos, crear statements, construir selects/updates/etc, recorrer resultsets y setear atributos de objetos, etc. para guardar, buscar, recuperar, etc. los valores de los atributos de un objeto. iBatis sqlMap simplifica esta tarea resumiéndola a la configuración de ficheros XML, con SQL ANSI o propietario y funciona con prácticamente cualquier base de datos con driver JDBC.
¿Cuándo utilizar iBatis?
Como toda herramienta, no vale para todo. iBatis sqlMap es muy válido cuando:
Se requiere una curva de aprendizaje rápida y pocos conocimientos previos, y no requiere aprender un lenguaje de consultas como en Hibernate o EJB CMP.
Se necesita manipular el SQL (para utilizar SQL propietario, optimizarlo, etc.) o se necesita llamar a procedimientos almacenados.
El modelo de datos existe previamente y no está muy normalizado (aunque lógicamente se puede utilizar con modelos nuevos y normalizados)
Alto rendimiento y optimización
…pero no para cuando:
Se requiere una automatización total y transparente de la persistencia
Se requiere soporte multi-RDBMS (motor de base de datos) transparente y automática
Hay una comparación constructiva con Hibernate en http://raibledesigns.com/page/rd?entry=hibernate_vs_ibatis
iBatis DAO es válido cuando:
Se sabe que el RDBMS (motor de base de datos) puede cambiar en el futuro
La implementación del acceso a datos puede requerir cambios sustanciales en el futuro
La implementación del acceso a datos puede variar entre un entorno de producción y otro (software comercial en distintos clientes)
iBatis DAO soporta sqlMap, Hibernate, etc.
¿Cómo funciona esto internamente?
Básicamente, programación declarativa y extensión del framework. Es decir, se configuran ficheros XML y, en iBatis DAO, se extienden clases donde se implementa la interfaz y el comportamiento específico.
Ejemplo:
iBatis DAO (opcional)
Crear un DAO.XML
<!DOCTYPE daoConfig PUBLIC "-//iBATIS.com//DTD DAO Configuration 2.0//EN" "http://www.ibatis.com/dtd/dao-2.dtd">
<daoConfig>
<context>
<transactionManager type="SQLMAP">
<property name="SqlMapConfigResource"
value="es/dxd/km/dao/sqlMap/sqlMapConfig.xml" />
</transactionManager>
<dao interface="es.dxd.km.dao.UsuarioDao"
implementation="es.dxd.km.dao.sqlMap.UsuarioSqlMapDao" />
</context>
</daoConfig>
Crear una utilidad de configuración tipo DaoConfig
public class DaoConfig {
private static final String DAO_XML = "es/dxd/km/dao/dao.xml";
private static final DaoManager daoManager;
static {
try {
daoManager = newDaoManager();
} catch (Exception e) {
throw new RuntimeException("Description. Cause: " + e, e);
}
}
public static DaoManager getDaoManager() {
return daoManager;
}
public static DaoManager newDaoManager() {
try {
Reader reader = Resources.getResourceAsReader(DAO_XML);
return DaoManagerBuilder.buildDaoManager(reader, null);
} catch (Exception e) {
throw new RuntimeException(
"Could not initialize DaoConfig. Cause: " + e, e);
}
}
}
Crear la interfaz del Dao para Usuarios, UsuariosDao:
public interface UsuarioDao extends Dao {
public int updateUsuario(Usuario usuario);
public int insertUsuario(Usuario usuario);
public int deleteUsuario(String idUsuario);
public Usuario getUsuario(String idUsuario);
public Usuario getUsuarioValidado(String idUsuario, String password);
public List getUsuariosByExample(Usuario usuario);
}
Crear su implementación:
public class UsuarioSqlMapDao extends SqlMapDaoTemplate implements
es.dxd.km.dao.UsuarioDao {
public UsuarioSqlMapDao(DaoManager arg0) {
super(arg0);
}
public int updateUsuario(Usuario usuario) {
try {
return getSqlMapExecutor().update("updateUsuario", usuario);
} catch (SQLException e) {
throw new DaoException("Error actualizando usuario. Cause: " + e, e);
}
}
public int insertUsuario(Usuario usuario) {
try {
getSqlMapExecutor().insert("insertUsuario", usuario);
} catch (SQLException e) {
throw new DaoException("Error insertando usuario. Cause: " + e, e);
}
return 1;
}
public int deleteUsuario(String idUsuario) {
try {
return getSqlMapExecutor().delete("deleteUsuario", idUsuario);
} catch (SQLException e) {
throw new DaoException("Error actualizando usuario. Cause: " + e, e);
}
}
public Usuario getUsuario(String idUsuario) {
try {
Usuario usuario = (Usuario) getSqlMapExecutor().queryForObject(
"getUsuarioById", idUsuario);
usuario.setRoles((List) getSqlMapExecutor().queryForList(
"getRolesUsuario", usuario));
return usuario;
} catch (SQLException e) {
throw new DaoException("Error recuperando usuario. Cause: " + e, e);
}
}
public List getUsuariosByExample(Usuario usuario) {
try {
Usuario usuarioExample = new Usuario();
if (usuario.getApellidos() != null) {
usuarioExample.setApellidos("%"
+ usuario.getApellidos().toLowerCase() + "%");
}
if (usuario.getNombre() != null) {
usuarioExample.setNombre("%"
+ usuario.getNombre().toLowerCase() + "%");
}
usuarioExample.setIdUsuario(usuario.getIdUsuario());
List usuarios = (List) getSqlMapExecutor().queryForList(
"getUsuariosByExample", usuarioExample);
// Asignar los roles
for (Iterator iter = usuarios.iterator(); iter.hasNext();) {
Usuario usuario2 = (Usuario) iter.next();
usuario2.setRoles((List) getSqlMapExecutor().queryForList(
"getRolesUsuario", usuario2));
}
return usuarios;
} catch (SQLException e) {
throw new DaoException("Error recuperando usuarios. Cause: " + e, e);
}
}
public Usuario getUsuarioValidado(String idUsuario, String password) {
Usuario usuario = getUsuario(idUsuario);
return usuario.getPassword().equals(password) ? usuario : null;
}
}
iBatis sqlMap
Crear la configuración sqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<properties
resource="properties/SqlMapConfig.properties" />
<settings cacheModelsEnabled="true" enhancementEnabled="true"
lazyLoadingEnabled="true" maxRequests="32" maxSessions="10"
maxTransactions="5" useStatementNamespaces="false" />
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}" />
<property name="JDBC.ConnectionURL" value="${url}" />
<property name="JDBC.Username" value="${username}" />
<property name="JDBC.Password" value="${password}" />
</dataSource>
</transactionManager>
<sqlMap
resource="es/dxd/km/dao/sqlMap/Usuario.xml" />
</sqlMapConfig>
La configuración de contexto es preferible sacarla afuera del xml para, por ejemplo, cambiar fácilmente de entornos, en el sqlMapConfig.xml se indicó que estuviera en properties/SqlMapConfig.properties:
driver=org.apache.derby.jdbc.ClientDriver
url=jdbc:derby://localhost:1527/kmdb
username=derby
password=derby
Finalmente, se configuran las operaciones y su SQL en Usuario.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="Usuario">
<select id="getUsuarioById" resultClass="es.dxd.km.model.Usuario">
SELECT rtrim(ID_USUARIO) as idUsuario, rtrim(PASSWORD) as
password, rtrim(NOMBRE) as nombre, rtrim(APELLIDOS) as apellidos
FROM APP.USUARIOS WHERE id_usuario = #value#
</select>
<select id="getRolesUsuario"
parameterClass="es.dxd.km.model.Usuario"
resultClass="es.dxd.km.model.Rol">
SELECT rtrim(R.ID_ROL) as idRol, rtrim(R.NOMBRE) as nombre,
rtrim(R.DESCRIPCION) as descripcion FROM APP.ROLES R,
APP.USUARIOS_ROLES U WHERE R.ID_ROL = U.ID_ROL AND U.ID_USUARIO
= #idUsuario#
</select>
<select id="getUsuariosByExample"
parameterClass="es.dxd.km.model.Usuario"
resultClass="es.dxd.km.model.Usuario">
SELECT rtrim(ID_USUARIO) as idUsuario, rtrim(PASSWORD) as
password, rtrim(NOMBRE) as nombre, rtrim(APELLIDOS) as apellidos
FROM APP.USUARIOS
<dynamic prepend="WHERE">
<isNotNull prepend="AND" property="nombre">
lower(NOMBRE) like #nombre#
</isNotNull>
<isNotNull prepend="AND" property="apellidos">
lower(APELLIDOS) like #apellidos#
</isNotNull>
<isNotNull prepend="AND" property="idUsuario">
ID_USUARIO = #idUsuario#
</isNotNull>
</dynamic>
</select>
<insert id="insertUsuario"
parameterClass="es.dxd.km.model.Usuario">
INSERT INTO APP.USUARIOS (ID_USUARIO, PASSWORD, NOMBRE,
APELLIDOS) VALUES (#idUsuario#, #password#, #nombre#,
#apellidos#)
</insert>
<update id="updateUsuario"
parameterClass="es.dxd.km.model.Usuario">
UPDATE APP.USUARIOS SET PASSWORD = #password#, NOMBRE =
#nombre#,APELLIDOS = #apellidos# WHERE ID_USUARIO = #idUsuario#
</update>
<delete id="deleteUsuario" parameterClass="string">
DELETE FROM APP.USUARIOS WHERE ID_USUARIO = #value#
</delete>
</sqlMap>
¿Licencia?
iBatis
es un proyecto que pertenece y utilza la licencia de Apache Software
Foundation, por lo que es Open Source disponible, modificable y
comercializable libremente.
(todo asesoramiento en este tema será
bienvenido)
¿Y para qué este manual básico?
Para simplificar el "first touch" y para explicar iBatis a alto nivel.
No pretende ser un tutorial, una guía del usuario ni un manual de referencia. Ellos ya se han escrito y están disponibles en las direcciones que se mencionan en la sección "¿Dónde encuentro más info?"
¿Dónde encuentro más info?
En la Página Oficial http://ibatis.apache.org encontrarán en la sección Documentación unos tutoriales muy buenos aunque extensos, una guía de referencia y el JavaDoc de la API. También tienen una sección de preguntas frecuentes muy completa.
Desde esta página también se puede descargar (recomiendo) el ejemplo oficial de utilización de iBatis: el JPetStore. Viene a ser como el PetStore de J2EE reconvertido a Struts+iBatis.
¿Cómo pongo en funcionamiento iBatis?
Básicamente hay que incluir las librerías en el path (en las aplicaciones web, en /WEB-INF/lib)
Lo ideal es deplegar el war del JPetStore, descargable desde http://ibatis.apache.org, y ver cómo funciona. Hacerle alguna modificación. Comenzar un prototipo desde cero y seguir los tutoriales.
Consejo: ser muy meticuloso con los XML porque la info de debugging es escasa y confusa.
Anímate y coméntanos lo que pienses sobre este tutorial
Puedes opinar o comentar cualquier sugerencia que quieras comunicarnos sobre este tutorial; con tu ayuda, podemos ofrecerte un mejor servicio.
| Autor | Mensaje de usuario registrado |
|---|
| Autor | Mensaje de usuario anónimo |
|---|---|
| oscardb |
Fecha de envío: 2009-04-27 - 09:58:33 PM ESTE TUTORIAL ES EL MEJOR QUE HE VISTO EN LA WEB MUCHAS FELICITACIONES!!! Y MUCHAS GRACIAS!! |
| Miguel de Francisco |
Fecha de envío: 2007-03-15 - 11:24:08 AM Sinceramente, muy buena la primera toma de contacto. Te felicito |
| alvaro |
Fecha de envío: 2006-09-20 - 05:59:21 PM Me gusto mucho, pero no encontré el JPetStore. |
| Adolfo Bravo |
Fecha de envío: 2006-09-13 - 05:03:24 AM Hola me gusto mucho la manera tan sucinta con la explicaron iBatis, gracias |
| Carletes |
Fecha de envío: 2006-09-09 - 08:41:17 PM Muy buen tutorial, si señor. ;-) Gracías por tu esfuerzo, dedicación y generosidad al compartir conocimiento. |
- Puedes inscribirte en nuestro servicio de notificaciones haciendo clic aquí.
- Puedes firmar en nuestro libro de visitas haciendo clic aquí.
- Puedes asociarte al grupo AdictosAlTrabajo en XING haciendo clic aquí.
- Añadir a favoritos Technorati.
Esta obra está licenciada bajo licencia Creative Commons de
Reconocimiento-No comercial-Sin obras derivadas 2.5
Recuerda
Autentia te regala la mayoría del conocimiento aquí compartido (Ver todos los tutoriales). Somos expertos en: J2EE, Struts, JSF, C++, OOP, UML, UP, Patrones de diseño ... y muchas otras cosas.
¿Nos vas a tener en cuenta cuando necesites consultoría o formación en tu empresa?, ¿Vas a ser tan generoso con nosotros como lo tratamos de ser con vosotros?
Somos pocos, somos buenos, estamos motivados y nos gusta lo que hacemos ...
Autentia = Soporte a Desarrollo & Formación.
Tutoriales recomendados
| Nombre | Resumen | Visitas | Valoración | Votos | ||
|---|---|---|---|---|---|---|
| Creando la Baraja de SCRUM de Autentia como aplicación para el IPhone 3G. | En este tutorial, se me ha ocurrido que podría hacer una pequeña aplicación útil: el pasar a IPhone la baraja de estimación que utilizamos en nuestra reuniones Scrum | 2010-02-09 | 43 | - | - | ![]() |
| Transformación de mensajes en SOA con OpenESB | En este tutorial vamos a mostrar con un ejemplo práctico una de las capacidades esenciales de todo sistema de integración, y por tanto característica del Enterprise Service Bus de SOA: la tranformación de mensajes. | 2010-01-29 | 320 | - | - | ![]() |
| Patrón Visitor con commons-collections y sus Closures | En este tutorial vamos a ver cómo podemos usar la librería de Apache commons-collections para implementar de forma sencilla un Visitor que se recorra todos los elementos de una colección. | 2010-01-14 | 439 | - | - | ![]() |
| Creación de servicios web RestFul, con soporte a persistencia, en NetBeans. | En este tutorial vamos a analizar el soporte que nos proporciona NetBeans para la creación de servicios web RESTful, que den soporte a las operaciones típicas que se pueden realizar contra una tabla de base de datos.El objetivo es la creación de un proyec | 2010-01-12 | 712 | Muy bueno | 1 | ![]() |
| Patrones de diseño de XML Schema | En este tutorial vamos a analizar y mostrar con ejemplos los cuatro principales patrones de diseño de XML Schema: Russian Doll, Salami Slice, Venetian Blind y Garden of Eden. | 2010-01-07 | 757 | Muy bueno | 1 | ![]() |
| PHP Vs Java | El cometido de este documento es el de realizar un análisis en profundidad de dos tecnologías ampliamente aceptadas por la comunidad diseñadora de portales web, como son PHP y Java. | 2010-01-04 | 1639 | - | - | ![]() |
| Procesador Inteligente de Eventos (IEP) con OpenESB | En este tutorial mostramos un ejemplo practico de gestion de eventos en SOA con IEP (Intelligent Event Processor) de OpenESB y probamos el resultado con soapUI | 2010-01-04 | 702 | - | - | ![]() |
| Tutorial de BPEL con OpenESB (I) | En este tutorial vamos a aprender a crear procesos BPEL practicando con un ejemplo: un proceso de negocio de venta online de libros. | 2009-12-29 | 1420 | - | - | ![]() |
| Tutorial de BPEL con OpenESB (II) | Continuación del Tutorial de BPEL con OpenESB (I). | 2009-12-29 | 1079 | - | - | ![]() |
| JavaBean Datasource Ireport | La particularidad del caso que nos ocupa, es conseguir que la fuente de datos del informe sea una lista de JavaBeans y no una consulta definida previamente en el informe. | 2009-12-14 | 1260 | Bueno | 2 | ![]() |
Nota:
Los tutoriales mostrados en este Web tienen como objetivo la difusión del conocimiento.
Los contenidos y comentarios de los tutoriales son responsabilidad de sus respectivos autores.
En algún caso se puede hacer referencia a marcas o nombres cuya propiedad y derechos es de sus respectivos dueños. Si algún afectado desea que incorporemos alguna reseña específica, no tiene más que solicitarlo.
Si alguien encuentra algún problema con la información publicada en este Web, rogamos que informe al administrador rcanales@adictosaltrabajo.com para su resolución.







