db4o使用心得之一

[color=red]db4o主要的包[/color]
com.db4o: 是db4o最经常用到的功能,Db4o类和ObjectContainer接口是这个包最常用到的。Db4o是运行db4o数据库的起点,这个类中的静态方法openFile会以嵌入式的方式打开数据库文件,还可以在开启数据库之前进行 db4o 环境配置。ObjectContainer 接口可在单用户模式下作为数据库实例,也可作为 db4o 服务器的Client。每个 ObjectContainer 实例维护它自己所管理的已存储和已实例化对象,在需要 ObjectContainer 的时候,它会一直保持开启状态,一旦关闭,内存中数据库所引用的对象将被丢弃.
com.db4o.ext:这个包主要是提供比较高级点的功能。每个ObjectContainer 对象也是 com.db4o.ext.ExtObjectContainer对象,可以强转成ExtObjectContainer或者通过ext()方法,以获得更多高级特性。
com.db4o.config: db4o 所需的配置方面的类。
com.db4o.query:db4o的查询接口以及相关的Predicate类等。

[color=red]打开方式[/color]
db4o的数据库文件后缀名是yap.可以用本地模式打开
ObjectContainer db = Db4o.openFile("data.yap");
在这种模式下,同时只能打开一个ObjectContainer,若打开多个会抛出com.db4o.DatabaseFileLockedException 异常,因此比较适合嵌入式的应用。
也可以用服务器模式打开
ObjectServer server=Db4o.openServer("data.yap",9002);//分别是数据库文件名、端口
server.grantAccess("root","root");//设定用户名、密码
然后就可以再客户端打开了
ObjectContainer oc = server.openClient()
或者直接连接
ObjectContainer db=Db4o.openClient("192.168.1.10",9002,"root","root");
.服务器模式下就可以打开多个client,可以用作J2EE应用环境,也可以做一个简单的db4o连接池来动态管理ObjectContainer。

[color=red]CURD操作[/color]
1) set对象:假设有个pojo,如下
public class HttpConfig {	
private int maxConnectPerHost;
private int maxTotalConnections;
private int connectTimeout;
private String name;
private String ip;
.....

保存这个对象只需要简单的
ObjectContainer db = Db4o.openFile("data.yap");
db.set(httpConfig);

2) read对象:db4o也有自己的查询方式,分别是QBE(Query by Example)、NQ(Native Queries)、SODA(Simple Object Database Access),接下来分别说下。
[color=orange]QBE[/color]: 当利用 QBE 为 db4o 提供模板(example)对象时,db4o 将返回所有和非默认值字段匹配的全部对象,内部是通过反射所有的字段和构造查询表达式(所有非默认值字段结合”AND”表达式)来实现。比如查询name为"hankzhang"的所有HttpConfig对象
ObjectContainer db = Db4o.openFile("data.yap");
try{
//构造模板对象
HttpConfig hc = new HttpConfig();
hc.setName("hankzhang");
//查询对象
List<HttpConfig> list = db.get(hc);
for(HttpConfig httpConfig : list) {
System.out.println(httpConfig.getIP());
}

}finally{
db.close();
}

这种方式比较简单,但是也有明显的缺陷:
1、必须反射模板对象(Example)的所有成员
2、无法执行更进一步的查询表达式(例如 AND、OR、NOT 等等)
3、不能指定约束值 0(int)、""或者 null(对象)等。

[color=orange]SODA[/color]:SODA是db4o最底层的查询API,目前SODA中使用字符串来定义字段,这样将不能实现类型安全也无法在编译时检查代码,而且写起来较麻烦.同上的例子,用SODA来做就是
ObjectContainer db = Db4o.openFile("data.yap");
try{
//查询对象
Query query = db.query();
//设置被约束实例
query.constrain(HttpConfig.class);
//设置被约束实例的字段和约束条件
query.descend("name").constrain("hankzhang");
ObjectSet<HttpConfig> list = query.execute();
for(HttpConfig httpConfig : list) {
System.out.println(httpConfig.getIP());
}

}finally{
db.close();
}

Query对象的API内有:sortBy(按字段排序)和 orderAscending(顺序)、orderDescending (逆序)等方法。

[color=orange]NQ[/color]:使用NQ,可以保证我们的查询代码是完全的编译期错误检查、类型安全甚至重构。还是上面的例子
ObjectContainer db = Db4o.openFile("data.yap");
try{
ObjectSet<HttpConfig> result = db.query(new Predicate<HttpConfig>() {

public boolean match(HttpConfig hc) {
return hc.getName().equals("hankzhang");
}
});
for(HttpConfig httpConfig : list) {
System.out.println(httpConfig.getIP());
}

}finally{
db.close();
}

在db4o内部,会设法把NQ转换成 SODA。

说到查询就不能忘了最常见的分页了,分页的做法简单到不可思议。
ObjectContainer db = Db4o.openFile("data.yap");
try{
ObjectSet<HttpConfig> result = db.query(new Predicate<HttpConfig>() {

public boolean match(HttpConfig hc) {
return hc.getName().equals("hankzhang");
}
});
//记录总数
int count = result.size();
//每页三条,分4页,为了方便,假设count大于3*4
for(int i = 0; i < 4; i++){
System.out.println(i + "Page:" + result.get(i*3).getIP());
System.out.println(i + "Page:" + result.get(i*3+1).getIP());
System.out.println(i + "Page:" + result.get(i*3+2).getIP());
}

}finally{
db.close();
}

不要以为写错了,虽然取得了list实例,但是list内只是httpconfig对象在数据库内部的id号而已,只有result.get(i*3).getIP()这样的操作之后,才会去根据id获取真正的对象。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值