Veamos a NHibernate en funcionamiento. Para ello vamos a realizar un ejemplo de agenda. Siempre vamos a necesitar crear tres ficheros: el esquema SQL de la tabla, la clase que define el objeto y un fichero XML donde define la relación entre campos de la tabla y los atributos de la clase.
Nuestra tabla contactos alojará datos de nombre, apellidos, teléfono y fecha de nacimiento.
Estructura de la tabla (SQL)
contactos.sql
CREATE TABLE `contactos` (
`id_contacto` int(8) NOT NULL AUTO_INCREMENT,
`nombre` varchar(25) NOT NULL DEFAULT ”,
`apellidos` varchar(50) NOT NULL DEFAULT ”,
`email` varchar(50) NOT NULL DEFAULT ”,
`fecha_nacimiento` DateTime NOT NULL DEFAULT ”,
PRIMARY KEY `id_contacto` (`id_contacto`)
);
Clase que define nuestro objeto (C#)
La clase Contacto define toda la información de cada contacto encapsulada en un objecto.
Contacto.cs
using System;
class Contacto {
private int _id_contacto;
private string _nombre;
private string _apellidos;
private string _email;
private DateTime _fecha_nacimiento;/* protected para que NHibernate pueda acceder */
protected int id_contacto {
get { return this._id_contacto; }
set { this._id_contacto = value; }
}protected string nombre {
get { return this._nombre; }
set { this._nombre = value; }
}protected string apellidos {
get { return this._apellidos; }
set { this._apellidos = value; }
}protected string email{
get { return this._email; }
set { this._email = value; }
}protected DateTime fecha_nacimiento {
get { return this._fecha_nacimiento; }
set { this._fecha_nacimiento = value; }
}/* public */
public int IdContacto {
get { return this._id_contacto; }
}public string Nombre {
get { return this._nombre; }
set { this._nombre = value; }
}public string Apellidos {
get { return this._apellidos; }
set { this._apellidos = value; }
}public string Email{
get { return this._email; }
set { this._email = value; }
}public DateTime FechaNacimiento {
get { return this._fecha_nacimiento; }
set { this._fecha_nacimiento = value; }
}/* Constructor */
public Contacto() {
}
}
Mapeando la tabla con la clase (XML)
Por último construiremos nuestro fichero de mapeado, el encargado de relacionar las variables de los objetos con los datos de las tablas. Es importante que el fichero tenga como extensión .hbm.xml, NHibernate buscará automáticamente los ficheros con dicha extensión y los procesará.
nhibernate.hbm.xml
<hibernate-mapping xmlns=”urn:nhibernate-mapping-2.0″>
<class name=”Contacto, Agenda” table=”contactos”>
<id name=”id_contacto” column=”id_contacto” type=”Int32″ length=”10″>
<generator class=”increment”/>
</id>
<property name=”nombre” column=”nombre” type=”String” length=”25″/>
<property name=”apellidos” type=”String” length=”50″/>
<property name=”email” type=”String” length=”50″/>
<property name=”fecha_nacimiento” type=”Ticks”/></class>
</hibernate-mapping>
Analicemos la estructura del fichero. Cada class que definamos hace referencia al mapeado de una clase vinculada con la tabla que le asignemos, en este caso la clase “Contacto” con la tabla “contactos”. Dentro de ella deberemos especificar las variables que vamos a usar de dicha clase y vincularlo con la columna específica de la tabla que estamos trabajando. Usaremos property para vincular cada atributo de la clase con cada columna, usando “name” para el nombre de la variable de la clase y “column” el nombre de la columna de la tabla, véase que si el nombre de la columna es el mismo que el de la variable, no es necesario especificar nada, pues NHibernate usará el mismo nombre especificado en “name” como columna, y por último especificar el tipo de dato con “type” (Puede obtener una lista de los tipos usados en NHibernate y los tipos de datos con que se corresponde en: http://nhibernate.sourceforge.net/nh-docs/en/html/single/reference.html#mapping-types ) Si el esquema(tabla) utiliza algún tipo de columna clave, deberemos especificarlo con “id” de uso similar a “property” con el añadido de que podemos asignar un modelo de generación de claves para el campo, en este caso incrementado.
Haciendo uso de NHibernate
Para hacer uso de nuestro objeto crearemos un pequeño programa de consola:
Agenda.cs
using System;
using NHibernate;
using NHibernate.Cfg;class Agenda {
public static void Main(string[] args)
{
Console.WriteLine(“Iniciando Agenda…”);Configuration cfg = new Configuration();
cfg.AddAssembly(“Agenda”); // Carga los *.hbm.xml
Console.WriteLine(“Configuracion cargada”);ISessionFactory factory = cfg.BuildSessionFactory();
ISession session = factory.OpenSession();
ITransaction transaction = session.BeginTransaction();Contacto miContacto = new Contacto();
miContacto.Nombre = “Jaime”;
miContacto.Apellidos = “C”;
miContacto.Email = “jaimecg at gmail.com”;
miContacto.FechaNacimiento = new DateTime(1900,1,1); //Que viejo soy!// Realizamos la persistencia del objeto
session.Save(miContacto);Console.WriteLine (“Contacto añadido, id_contacto: {0}”, miContacto.IdContacto);
// Cierra la transacción y la conexión con la base de datos.
transaction.Commit();
session.Close();
}
}
Como ves, es realmente sencillo insertar objetos y manipularlos. Podríamos crear un manejador de Contactos y así crear nuestra capa de datos de la aplicación. Nos bastaría unas pocas líneas para generar un ContactosManager para la insercción, recuperacion, actualización o búsqueda de objetos Contacto.
Compilando
mcs -t:exe -r:System,System.Data,log4net,NHibernate -warn:4 -out:Agenda.exe -main:Agenda -resource:nhibernate.hbm.xml Contacto.cs Agenda.cs
Configurando
Agenda.exe.config
<configuration>
<configSections>
<section name=”nhibernate” type=”System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089″ />
<section name=”log4net” type=”log4net.Config.Log4NetConfigurationSectionHandler,log4net” /><nhibernate>
<add key=”hibernate.connection.provider” value=”NHibernate.Connection.DriverConnectionProvider” />
<add key=”hibernate.dialect” value=”NHibernate.Dialect.MySQLDialect” />
<add key=”hibernate.connection.driver_class” value=”NHibernate.Driver.MySqlDataDriver” />
<add key=”hibernate.connection.connection_string” value=”Server=localhost;Database=monohispano;User ID=root;Password=;” />
</nhibernate>
</configSections>
</configuration>
Ejecutando
mono Agenda.exe
Salida en pantalla:
$ mono Agenda.exe
Iniciando Agenda…
Configuracion cargada
Contacto añadido, id_contacto: 1