Before we start, note that CUBRID will be accessed from NHibernate using the .NET driver. Doing this is not a more complicated task than accessing CUBRID with any other .NET-enabled systems. However, configuring NHibernate to work with CUBRID requires some different steps, as for the moment CUBRID support is not officially supported by NHibernate out of the box and we had to add the missing components.
Setting up the Directory Structure and Environment
In this tutorial you will learn how to configure a simple project that works with CUBRID and Hibernate to access a sample database. Let's start by creating a directory structure. In the directory of you project create a new folder called “lib”. Once you have downloaded the Hibernate, unpack it into a temporary directory and copy the following libraries to the lib folder you just created:
Now, in Visual Studio add the lib folder to your project, and make references to NHibernate.dll and Iesi.Collections.dll.
Unpack the Missing NHibernate support for CUBRID zip file and copy CUBRIDConnectionProvider.cs and CUBRIDDataDriver.cs to your project folder and add these two files to your project.
The directory structure of your project should look now like this:
Scenario
In this tutorial we will use the athlete table in the “demodb” database that is incorporated in CUBRID. Each athlete is identified by its 3-letters code, has a name, gender, nation, and participates in an event. We will use this table to insert/select/update/delete records using NHibernate.
If you do not have the "demodb" database installed, create a new database named demodb and in this database create a new table named athlete. DDL should look like this:
CREATE TABLE athlete (
code INTEGER AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(40) NOT NULL,
gender CHAR(1),
nation_code CHAR(3),
event VARCHAR(30)
)
Create the mapping class
Here we create the athlete C# class.
public class athlete {
virtual public int code { get; set; }
virtual public string Name { get; set; }
virtual public string Gender { get; set; }
virtual public string NationCode { get; set; }
virtual public string Event { get; set; }
}
Note: The members persisted in the database have to be virtual if you use lazy loading, which is usually best way.
Create the xml mapping file
It's time now to write the mapping for our country table. Create an xml file in your project called athlete.hbm.xml. Now modify the properties of this file and set the Build Action to Embedded Resource. The content of the file is:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Cubrid.Data.Test.Nhibernate"
namespace="Cubrid.Data.Test.Nhibernate">
<class name="athlete" lazy="true">
<id name="code" column="code">
<generator class="assigned"/>
</id>
<property name="Name" column ="name"/>
<property name="Gender" column="gender"/>
<property name="NationCode" column ="nation_code"/>
<property name="Event" column = "event"/>
</class>
</hibernate-mapping>
Configuring NHibernate
Nhibernate needs to know where the database lives and what type it is. To tell NHibernate this information, add an Application configuration File to your project. The content of this file will be:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="hibernate-configuration"
type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
</configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">
Cubrid.Data.Test.Nhibernate.CUBRIDConnectionProvider, Cubrid.Data.Test.Nhibernate
</property>
<property name="connection.driver_class">
Cubrid.Data.Test.Nhibernate.CUBRIDDataDriver, Cubrid.Data.Test.Nhibernate
</property>
<property name="dialect">
NHibernate.Dialect.GenericDialect
</property>
<property name="show_sql">
false
</property>
</session-factory>
</hibernate-configuration>
<connectionStrings>
<add name="ConnectionString" connectionString="server=localhost;database=demodb;port=33000;user=public;password="/>
</connectionStrings>
</configuration>
Note: The App.config file also contains the connection string used to connect to the database. Replace localhost with the IP address you want to use in case of remote database connection. Also, adjust the user,port and database if needed and in case the user has a password, add password=user_password; to the connection string (replace user_password with the right password).
Writing the main class
It’s time to see NHibernate in action. We will see how to insert, select, update and delete records from the athlete table. The main class code is:
class Program {
static void Main(string[] args)
{
athlete John = new athlete { code = 17000, Name = "John Terry", Gender = "M", NationCode = "GBR", Event = "Football" };
John.Print();
//lets insert John into the database
try
{
using (ISession session = OpenSession())
{
using (ITransaction transaction = session.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted))
{
session.Save(John);
transaction.Commit();
Console.WriteLine("Saved John to database");
}
}
}
catch (Exception e) { Console.WriteLine(e); }
//let's read the last 10 athletes in the database
using (ISession session = OpenSession())
{
IQuery query = session.CreateQuery("FROM athlete WHERE rownum < 11 order by code desc");
IList<athlete> athlete = query.List<athlete>();
Console.Out.WriteLine("athlete.Count = " + athlete.Count + "");
athlete.ToList().ForEach(p => p.Print());
athlete a = athlete.ToArray()[0];
Debug.Assert(a.Name.Equals("John Terry"));
Debug.Assert(a.Gender.Equals("M"));
Debug.Assert(a.NationCode.Equals("GBR"));
Debug.Assert(a.Event.Equals("Football"));
}
//let's update our athlete in the database
using (ISession session = OpenSession())
{
using (ITransaction transaction = session.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted))
{
IQuery query = session.CreateQuery("FROM athlete WHERE name = 'John Terry'");
athlete athlete = query.List<athlete>()[0];
athlete.Name = "Wayne Rooney";
transaction.Commit();
}
Console.WriteLine("Updated John. His name is now Wayne.");
}
//let's delete our athlete from the database
using (ISession session = OpenSession())
{
using (ITransaction transaction = session.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted))
{
IQuery query = session.CreateQuery("FROM athlete WHERE Name = 'Wayne Rooney'");
athlete athlete = query.List<athlete>()[0];
session.Delete(athlete);
transaction.Commit();
}
Console.WriteLine("Deleted Wayne Rooney from Database.");
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
static ISessionFactory SessionFactory;
static ISession OpenSession()
{
if (SessionFactory == null) //not threadsafe
{
//SessionFactories are expensive, create only once
Configuration configuration = new Configuration();
configuration.AddAssembly(Assembly.GetCallingAssembly());
SessionFactory = configuration.BuildSessionFactory();
}
return SessionFactory.OpenSession();
}
}
Program Output
Running this code will result in the following output.
