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 件のコメント:
コメントを投稿