2009年9月3日木曜日

Monoで他のDBも使ってみたよ!+(db4o、NHibernate編)5


DBアクセス

接続確認

簡単な検索(全件検索、Idによる検索)を行うコードを用いて、NHibernateで用意されているクエリ機能(HQL、Criteria、Native SQL)を試します。

 ベースとなるコード(C#)は以下になります(各DBMS用NHibernateコンフィグファイルについては、「おまけ」の節に掲載します)。

[Productsテーブルの全件取得(Idの昇順)]
  1. using System;  
  2. using NHibernate;  
  3. using NHibernate.Cfg;  
  4. using NHibernate.Criterion;  
  5.   
  6. using NHibernateExample;  
  7.   
  8. namespace NHibernateExample.Test  
  9. {  
  10.   public class Query1  
  11.   {  
  12.     public static void Main(string[] args)  
  13.     {  
  14.       string s;  
  15.       string cfg_prefix;  
  16.   
  17.       // 接続先DBMSの選択  
  18.       START:  
  19.       Console.Write("Connect to\n1:SQLite\n2:PostgreSQL\n3:MySQL\n4:SQLServer\n5:Oracle\n6:Firebird\n7:DB2\n?> ");  
  20.       s = Console.ReadLine();  
  21.       switch(s)  
  22.       {  
  23.         case "1": cfg_prefix = "SQLite";     break// SQLite  
  24.         case "2": cfg_prefix = "PostgreSQL"break// PostgreSQL  
  25.         case "3": cfg_prefix = "MySQL";      break// MySQL  
  26.         case "4": cfg_prefix = "SQLServer";  break// SQL Server  
  27.         case "5": cfg_prefix = "Oracle";     break// Oracle  
  28.         case "6": cfg_prefix = "Firebird";   break// Firebird  
  29.         case "7": cfg_prefix = "DB2";        break// DB2  
  30.         defaultgoto START;  
  31.       }  
  32.   
  33.       Configuration cfg = new Configuration();  
  34.       cfg.Configure(cfg_prefix + ".cfg.xml");  
  35.       ISessionFactory factory = cfg.BuildSessionFactory();  
  36.   
  37.       using (ISession session = factory.OpenSession())  
  38.       {  
  39.         // Productsテーブルの全件取得(Idの昇順)  
  40.         #region Query  
  41.   
  42.         // HQL  
  43.         var results = session.CreateQuery(  
  44.           "from Product as p order by p.Id asc")  
  45.           .List();  
  46.  
  47.         #endregion  
  48.   
  49.         foreach (Product p in results)  
  50.         {  
  51.           Console.WriteLine(p);  
  52.         }  
  53.       }  
  54.     }  
  55.   }  
  56. }  
  57. /* 
  58. * ビルド: 
  59. * 
  60. *   gmcs -r:NHibernate.dll,NHibernateExample.dll query1.cs 
  61. * 
  62. * 実行: 
  63. * 
  64. *   mono query1.exe 
  65. * 
  66. */  

[ProductsテーブルのIdによる検索]
  1. using System;  
  2. using NHibernate;  
  3. using NHibernate.Cfg;  
  4. using NHibernate.Criterion;  
  5.   
  6. using NHibernateExample;  
  7.   
  8. namespace NHibernateExample.Test  
  9. {  
  10.   public class Query2  
  11.   {  
  12.     public static void Main(string[] args)  
  13.     {  
  14.       string s;  
  15.       string cfg_prefix;  
  16.   
  17.       string i;  
  18.       int id;  
  19.   
  20.       // 接続先DBMSの選択  
  21.       START:  
  22.       Console.Write("Connect to\n1:SQLite\n2:PostgreSQL\n3:MySQL\n4:SQLServer\n5:Oracle\n6:Firebird\n7:DB2\n?> ");  
  23.       s = Console.ReadLine();  
  24.       switch(s)  
  25.       {  
  26.         case "1": cfg_prefix = "SQLite";     break// SQLite  
  27.         case "2": cfg_prefix = "PostgreSQL"break// PostgreSQL  
  28.         case "3": cfg_prefix = "MySQL";      break// MySQL  
  29.         case "4": cfg_prefix = "SQLServer";  break// SQL Server  
  30.         case "5": cfg_prefix = "Oracle";     break// Oracle  
  31.         case "6": cfg_prefix = "Firebird";   break// Firebird  
  32.         case "7": cfg_prefix = "DB2";        break// DB2  
  33.         defaultgoto START;  
  34.       }  
  35.   
  36.       Console.Write("ID?> ");  
  37.       i = Console.ReadLine();  
  38.       if (!(Int32.TryParse(i, out id)))  
  39.       {  
  40.         Console.WriteLine("整数値を入力して下さい。入力値 = {0}", i);  
  41.         return;  
  42.       }  
  43.   
  44.       Configuration cfg = new Configuration();  
  45.       cfg.Configure(cfg_prefix + ".cfg.xml");  
  46.       ISessionFactory factory = cfg.BuildSessionFactory();  
  47.   
  48.       using (ISession session = factory.OpenSession())  
  49.       {  
  50.         // ProductsテーブルのIdによる検索  
  51.         #region Query  
  52.   
  53.         // HQL  
  54.         var result = session.CreateQuery(  
  55.           "from Product as p where p.Id = :id")  
  56.           .SetParameter("id", id)  
  57.           .UniqueResult<Product>();  
  58.  
  59.         #endregion  
  60.   
  61.         if (result != null)  
  62.         {  
  63.           Console.WriteLine("FOUND!:{0}", result);  
  64.         }  
  65.       }  
  66.     }  
  67.   }  
  68. }  
  69. /* 
  70. * ビルド: 
  71. * 
  72. *   gmcs -r:NHibernate.dll,NHibernateExample.dll query2.cs 
  73. * 
  74. * 実行: 
  75. * 
  76. *   mono query2.exe 
  77. * 
  78. */  
HQL
HQL(Hibernate Query Language)はNHibernateで用意されているSQLライクなクエリ言語です。

 NHibernateで用意されている各クエリは、SQLに変換されるので、コンフィグファイルで次の設定をした場合、
  1. <property name="show_sql">true</property>  
HQLが次のようにSQLに変換されるのが分かります。

[Productsテーブルの全件取得(Idの昇順)]
NHibernate: SELECT this_.ProductID as ProductID0_0_, this_.ProductName as ProductN2_0_0_, this_.Price as Price0_0_, this_.ProductDescription as ProductD4_0_0_ FROM Products this_ ORDER BY this_.ProductID asc

[ProductsテーブルのIdによる検索]
NHibernate: select product0_.ProductID as ProductID0_, product0_.ProductName as ProductN2_0_, product0_.Price as Price0_, product0_.ProductDescription as ProductD4_0_ from Products product0_ where (product0_.ProductID=@p0 ); @p0 = '1'

 また、HQLではありませんが、「Idによる検索」の様な、PRIMARY KEYによる検索の場合、次の記述が可能です。

[ProductsテーブルのIdによる検索]
  1. var result = session.Get<Product>(id);  
Criteria
HQLを次のCriteriaに置き換え可能です。

[Productsテーブルの全件取得(Idの昇順)]
  1. // Criteria  
  2. var results = session.CreateCriteria(typeof(Product))  
  3.   .AddOrder(Order.Asc("Id"))  
  4.   .List();  

[ProductsテーブルのIdによる検索]
  1. // Criteria  
  2. var result = session.CreateCriteria(typeof(Product))  
  3.   .Add(Expression.Eq("Id", id))  
  4.   .UniqueResult<Product>();  
CriteriaはHQLより簡易なクエリ機能と位置づけられているようです。
Native SQL
HQLを次のNative SQLに置き換え可能です。

[Productsテーブルの全件取得(Idの昇順)]
  1. // Native SQL  
  2. var results = session.CreateSQLQuery(  
  3.   "SELECT * FROM Products ORDER BY ProductID")  
  4.   .AddEntity(typeof(Product))  
  5.   .List();  

[ProductsテーブルのIdによる検索]
  1. // Native SQL  
  2. var result = session.CreateSQLQuery(  
  3.   "SELECT * FROM Products WHERE ProductID = :id")  
  4.   .AddEntity(typeof(Product))  
  5.   .SetParameter("id", id)  
  6.   .UniqueResult<Product>();  
上記の様に、直接SQL文を記述することが可能です。

 Monoで他のDBも使ってみたよ!+(db4o、NHibernate編)6 へ続く。

0 件のコメント:

コメントを投稿