初次接触db4o

这几天一直在思考如何实现ORM的数据缓存的问题,在网上找资料的时候发现了db4o和Linkin兄的利用db4o做中间层数据缓存,感觉上db4o搭配nhibernate是一个ORM的很好的实现方案。

今天是我第一天接触到db4o,总结了一下SDK里面的FirstStep,供大家初学的一个参考,顺便为db4o打个广告

主要内容:
1、什么是db4o
2、db4o的学习资源
3、db4o: the first step



什么是db4o?

db4o是一种纯对象数据库,相对于传统的关系数据库+ORM,db4o具有以下好处:
1)以存对象的方式存取数据(废话~~,不过你考虑一下完全以对象的方式去考虑数据的存取对传统的数据库设计思维来说是多么大的颠覆);
2)无需数据库服务器,只需要一个数据文件,且dll大小仅为300多k,非常适合作为嵌入式数据库;
3)提供Query By Sample, Native Query和Simple Object DataBase Access(SODA)三种方式进行数据查询,操作简便且功能强大,和sql说byebye。

同时,db4o有.net和java两种版本,.net版本已经支持.net 1.0/1.1/2.0了。

db4o可以在:http://www.db4o.com/default.aspx 下载,最新版本为5.0。同时还有一个叫objectmanager的工具,可用于查看数据文件中保存的对象,不过安装前需要安装jvm。


db4o的学习资源

对于初学者来说,参考db4o的api document和db4o tutorial就够了,这些在安装的时候都已经带了,不用到处找了。另外还可以上db4o的官方forum http://forums.db4o.com/login.aspx?pnr=&ReturnUrl=/forums,人气还可以。


 

db4o: the first step

今天我只是简单的介绍如何使用db4o实现简单对象的crud操作,并且对db4o的插入和查询效率进行了初步的测试,下一步会进行继续的深入,有兴趣的兄弟可以一块交流,db4o和nhibernate搭配实现orm的确是一套很好的方案。

1、基本概念:
先别去想什么db4o又是一套复杂的开源的东西,今天我们只需要了解com.db4o.ObjectContainer和com.db4o.Db4o两个类
(1)com.db4o.Db4o:db4o类库中的关键类之一,本文中的用途是用com.db4o.Db4o.OpenFile来创建和打开db4o的数据库文件
(2)com.db4o.ObjectContainer:简单点来说,db4o的数据库文件就是一个对象的容器(存储的是对象嘛~~),我们可以通过Db4o::OpenFile来获取指向db4o数据库文件的ObjectContainer,进行所需的存取操作后,调用ObjectContainer::Close()来关闭这一连接。

或许你会说,怎么会那么简单,没错,今天接触db4o的时候就是那么舒服,不用管什么数据库的Schema。

2、简单的db4o的存取操作:
示例如何进行对象的存取操作之前,我们先简单的定义一个对象类,用于db4o的存取。

 1 /// <summary>
 2     /// 用于测试db4o基本crud操作的对象类
 3     /// </summary>
 4      public class Entity
 5     {
 6         private string m_strName;
 7 
 8         public Entity(string strName)
 9         {
10             this.m_strName = strName;
11         }
12 
13         public string Name
14         {
15             get
16             {
17                 return this.m_strName;
18             }
19             set
20             {
21                 this.m_strName = value;
22             }
23         }
24     }


1)保存对象:

 1 private const string CONST_DEFAULT_DATAFILE = @"c:\db4obasic.yap";
 2 
 3  static void Main(string[] args)
 4 {
 5 
 6     // 打开数据文件
 7     ObjectContainer container = Db4o.OpenFile(CONST_DEFAULT_DATAFILE);
 8 
 9     try
10     {
11         Entity entity = new Entity("calvin");
12         container.Set(entity);
13     }
14     finally
15     {
16         container.Close();
17     }
18 }


2)删除已有对象:

 1 private const string CONST_DEFAULT_DATAFILE = @"c:\db4obasic.yap";
 2 
 3 static void Main(string[] args)
 4 {
 5 
 6     // 打开数据文件
 7     ObjectContainer container = Db4o.OpenFile(CONST_DEFAULT_DATAFILE);
 8 
 9     try
10     {
11         Entity entity = new Entity("calvin");
12         container.Set(entity);
13 
14         IList result = container.Get(entity);
15         container.Delete((Entity) result[0]);
16     }
17     finally
18     {
19         container.Close();
20     }
21 }


3)更新对象

 1 private const string CONST_DEFAULT_DATAFILE = @"c:\db4obasic.yap";
 2 
 3 static void Main(string[] args)
 4 {
 5 
 6     // 打开数据文件
 7     ObjectContainer container = Db4o.OpenFile(CONST_DEFAULT_DATAFILE);
 8 
 9     try
10     {
11         Entity entity = new Entity("foo");
12         container.Set(entity);
13 
14         IList result = container.Get(entity);
15         entity = (Entity) result[0];
16         entity.Name = "bar";
17         container.Set(entity);
18     }
19     finally
20     {
21         container.Close();
22     }
23 }


在2)和3)中,我使用了QBE来实现对象的查询,按照db4o官方的说法,用QBE可以快速的实现对象简单查询,但是限制也不少:
“Querying this way has some obvious limitations:
- db4o must reflect all members of your example object.
- You cannot perform advanced query expressions. (AND, OR, NOT, etc.)
- You cannot constrain on values like 0 (integers), "" (empty strings), or nulls (reference types) because they would be interpreted as unconstrained.
- You need to be able to create objects without initialized fields. That means you can not initialize fields where they are declared. You can not enforce contracts that objects of a class are only allowed in a well-defined initialized state.
- You need a constructor to create objects without initialized fields.

推荐使用的方式是Native Query(NQ),这是一种非常奇妙且简单的查询方式,我将在后续的文章中介绍nq,,按照Linkin兄的说法“nq搭配c#2.0的泛型和匿名函数,简直是数据查询的绝配”。

4)db4o的插入性能:
我简单测试了一下,看看db4o的插入性能如何,试试插入10万个简单对对象,代码断如下:

 1 /// <summary>
 2         /// 测试DB4o的插入效率
 3         /// </summary>
 4         /// <param name="container"></param>
 5         private static void TestBatchInsert(ObjectContainer container)
 6         {
 7             int iBegin = System.Environment.TickCount;
 8 
 9             for (int i = 0; i < 100000; i++)
10             {
11                 Entity entity = new Entity(i.ToString());
12                 container.Set(entity);
13             }
14 
15             // 在我的机器P42.6G, 768Memory上,插入时间为22563ms
16             Console.WriteLine("total time: " + (System.Environment.TickCount - iBegin));
17         }


在我机器(P4 2.6G, 768M内存)上首次插入10万个对象只用)了22s多,很不错。但当第二次插入的时候,却花了>10分钟(没耐心继续等了),大家一起找找原因吧。

5)db4o的查询性能:
采用4)中插入的数据,通过native query的方式查询Name以"1"开头的对象,花了10484ms,返回了1111个对象,慢了点~~。


 

总结

db4o搭配现有的orm,应该是一种很好的pl解决方案,当然首先要解决数据量较大的时候的多次插入和查询的耗时长的问题。时间的关系,今天没来的及测试db4o的系统占用率(只是觉得我在测试第二次插入数据的时候,写blog都ka了),本文涉及的代码从/Files/chwkai/db4oTutorial.rar下载。我也是初学,欢迎大家多讨论。

posted @ 2005-12-05 22:42  海南K.K  阅读(4912)  评论(9编辑  收藏  举报