DBアクセス
接続確認
簡単な検索(全件検索、Idによる検索)を行うコードを用いて、db4oで用意されているクエリ機能(QBE、NQ、SODA、LINQ)、および、db4o DBのServerモードでのオープンについて解説します。ベースとなるコード(C#)は次になります。
[Productオブジェクトの全件取得(Idの昇順)]
using System; using System.Collections.Generic; // NQ, LINQ using System.Linq; // LINQ using Db4objects.Db4o; using Db4objects.Db4o.Query; // SODA using Db4objects.Db4o.Linq; // LINQ using db4oExample; namespace db4oExample.Test { public class Query1 { public static void Main(string[] args) { string dbfile = "/home/sta/data/db4o/TestData.db4o"; using (IObjectContainer db = Db4oFactory.OpenFile(dbfile)) { // Productオブジェクトの全件取得(Idの昇順) #region Query // QBE // ソート条件の設定は不可 //IObjectSet results = db.QueryByExample(typeof(Product)); // 結果セットに対してソート IObjectSet cache = db.QueryByExample(typeof(Product)); var results = cache.Cast<Product>().OrderBy(p => p.Id); #endregion foreach (Product p in results) { Console.WriteLine(p); } } } } } /* * ビルド: * * gmcs -r:Db4objects.Db4o.dll,Db4objects.Db4o.Linq.dll,db4oExample.dll query1.cs * * 実行: * * mono query1.exe * */
[Productオブジェクトの取得(Idによる検索)]
using System; using System.Collections.Generic; // NQ, LINQ using System.Linq; // LINQ using Db4objects.Db4o; using Db4objects.Db4o.Query; // SODA using Db4objects.Db4o.Linq; // LINQ using db4oExample; namespace db4oExample.Test { public class Query2 { public static void Main(string[] args) { string dbfile = "/home/sta/data/db4o/TestData.db4o"; string i; int id; Console.Write("ID?> "); i = Console.ReadLine(); if (!(Int32.TryParse(i, out id))) { Console.WriteLine("整数値を入力して下さい。入力値 = {0}", i); return; } using (IObjectContainer db = Db4oFactory.OpenFile(dbfile)) { // Productオブジェクトの取得(Idによる検索) #region Query // QBE IObjectSet result = db.QueryByExample(new Product(id, null, null, null)); #endregion foreach (Product p in result) { Console.WriteLine("FOUND!:{0}", p); } } } } } /* * ビルド: * * gmcs -r:Db4objects.Db4o.dll,Db4objects.Db4o.Linq.dll,db4oExample.dll query2.cs * * 実行: * * mono query2.exe * */
QBE
QBE(Query By Example)はdb4oで用意されている簡易クエリ機能ですが、簡易ゆえの限界があります。例えば、後述する各クエリではクエリの命令セットの中に、ソート条件の設定が可能ですが、QBEではできません。検索条件も設定した値(!初期値)のANDだけで、複雑な条件設定はできません。また、初期値による検索は全件が返されてしまいます。[実行例]
$ mono query2.exe
ID?> 1
FOUND!:ID:1 NAME:Clamp PRICE:12.48 DESCRIPTION:Workbench clamp
$ mono query2.exe
ID?> 0
FOUND!:ID:0 NAME:db4o PRICE: DESCRIPTION:db4o 7.4
FOUND!:ID:3000 NAME:3mm Bracket PRICE:0.52 DESCRIPTION:
FOUND!:ID:1 NAME:Clamp PRICE:12.48 DESCRIPTION:Workbench clamp
FOUND!:ID:50 NAME:Flat Head Screwdriver PRICE:3.17 DESCRIPTION:Flat head
FOUND!:ID:75 NAME:Tire Bar PRICE: DESCRIPTION:Tool for changing tires.
ID?> 1
FOUND!:ID:1 NAME:Clamp PRICE:12.48 DESCRIPTION:Workbench clamp
$ mono query2.exe
ID?> 0
FOUND!:ID:0 NAME:db4o PRICE: DESCRIPTION:db4o 7.4
FOUND!:ID:3000 NAME:3mm Bracket PRICE:0.52 DESCRIPTION:
FOUND!:ID:1 NAME:Clamp PRICE:12.48 DESCRIPTION:Workbench clamp
FOUND!:ID:50 NAME:Flat Head Screwdriver PRICE:3.17 DESCRIPTION:Flat head
FOUND!:ID:75 NAME:Tire Bar PRICE: DESCRIPTION:Tool for changing tires.
NQ
QBEを次のNQ(Native Query)に置き換え可能です。[Productオブジェクトの全件取得(Idの昇順)]
// NQ IList<Product> results = db.Query<Product> ( delegate(Product p) { return true; }, new Comparison<Product> ( delegate(Product p1, Product p2) { return p1.Id.CompareTo(p2.Id); } ) );
[Productオブジェクトの取得(Idによる検索)]
// NQ IList<Product> result = db.Query<Product> ( delegate(Product p) { return ( p.Id == id ); } );NQはdb4oでのメインクエリと位置づけられているようですが、単純な昇順の設定でこの記述は遠慮したいところです。
SODA
QBEを次のSODA Queryに置き換え可能です。[Productオブジェクトの全件取得(Idの昇順)]
// SODA IQuery query = db.Query(); query.Constrain(typeof(Product)); query.Descend("_id").OrderAscending(); IObjectSet results = query.Execute();
[Productオブジェクトの取得(Idによる検索)]
// SODA IQuery query = db.Query(); query.Constrain(typeof(Product)); query.Descend("_id").Constrain(id); IObjectSet result = query.Execute();SODAはdb4oで提供されているクエリ機能の中で下位レベルのクエリとされ、実際、他のクエリはSODAに変換されて実行ということなので、最初からSODAで記述すれば、パフォーマンス的にはよいということになります。
LINQ
QBEを次のLINQに置き換え可能です。[Productオブジェクトの全件取得(Idの昇順)]
// LINQ var results = from Product p in db orderby p.Id select p;
[Productオブジェクトの取得(Idによる検索)]
// LINQ var result = from Product p in db where p.Id == id select p;可読性に勝り、.NETで提供されている汎用的なクエリでもあるので、メインクエリとして使用されるようになるでしょうか。
Db4oFactory.OpenServer
Db4oFactory.OpenFileメソッドでオープンすると、ファイルとしてのオープンになりますが、Db4oFactory.OpenServerメソッドを使用することで、Client/Server形式のDBアクセスが可能になります。OpenServerメソッドの引数として渡すPORT番号の値により、ネットワークを経由しないEmbeded Serverモード(PORT=0)、ネットーワを経由するNetwor Serverモード(PORT=0以外)に分かれます。[Embeded Serverモード]
... IObjectServer server = Db4oFactory.OpenServer(dbfile, 0); // PORT=0 try { using (IObjectContainer client1 = server.OpenClient()) using (IObjectContainer client2 = server.OpenClient()) // 別のクライアントが必要な場合 { // 各Query } } finally { if (server != null) { server.Close(); } } ...
[Network Serverモード:サーバ側]
... IObjectServer server = null; try { server = Db4oFactory.OpenServer(dbfile, 4649); // 任意のPORT番号 server.GrantAccess("sta", "password"); Console.WriteLine("Server Started.\n### Hit some keys to stop the server ###"); Console.ReadLine(); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { if (server != null) { server.Close(); } Console.WriteLine("Server Stopped."); } ...
[Network Serverモード:クライアント側]
... using (IObjectContainer client = Db4oFactory.OpenClient("localhost", 4649, "sta", "password")) { // 各Query } ...Monoで他のDBも使ってみたよ!+(db4o、NHibernate編)3 へ続く。
0 件のコメント:
コメントを投稿