db4o使用心得之二

3)delete,update对象
把这两个操作放一起,是因为它们都跟一个东东:更新深度 有关系。
对于更新,代码是很简单的,还是拿那个例子来看。
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");
}
});
HttpConfig httpConfig = result.next();
//修改地址
httpConfig.setIP("172.16.60.26");
db.set(httpConfig);
}finally{
db.close();
}

但是如果httpConfig对象里面有个成员变量不是基本的java类型,是个自定义的对象,比如有这么个属性
private TaskConfig config;
会发现,如下代码不能起到作用。
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");
}
});
HttpConfig httpConfig = result.next();
//修改地址
httpConfig.setIP("172.16.60.26");
//修改内部自定义对象
httpConfig.setTaskConfig(new TaskConfig());
db.set(httpConfig);
}finally{
db.close();
}

即使设置了新的值,仍然修改不成功。这是因为 假设内部的成员对象比较复杂而且成员对象还能继续追溯下去,则更新一个对象,就需要对这些所有的对象都做更新,也就是 级联更新,这将引起很大的性能问题。因此默认情况下,只有基本的数据类型才会被修改到,如果确实要更新自定义的对象,就需要做级联设置。

//级联设置
Db4o.configure().objectClass(HttpConfig.class.getName()).cascadeOnUpdate(true);
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");
}
});
HttpConfig httpConfig = result.next();
//修改地址
httpConfig.setIP("172.16.60.26");
//修改内部自定义对象
httpConfig.setTaskConfig(new TaskConfig());
db.set(httpConfig);
}finally{
db.close();
}


删除对象,代码类似
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");
}
});
HttpConfig httpConfig = result.next();
db.delete(httpConfig);
}finally{
db.close();
}

如果需要级联删除的话,就需要在最前面加上
Db4o.configure().objectClass(HttpConfig.class.getName()).cascadeOnDelete(true);


[color=red]Db4o连接池[/color]
这个东西db4o没有相应实现,而且存在很大的争议性。如果没有连接池,每次都要使用都要open,close数据库文件,而这两个操作恰好是非常频繁的;如果加入连接池,因为每个ObjectContainer都有自己的事务,所有的操作都有事务保证。当打开 ObjectContainer,就已经进入事务了,commit() 或 rollback() 时,下一个事务立即启动。每个 ObjectContainer 实例维护它自己所管理的已存储和已实例化对象,在需要 ObjectContainer 的时候,它会一直保持开启状态,一旦关闭,内存中数据库所引用的对象将被丢弃。个人觉得,如果只是用来做本地应用的数据库,而且数据都是简单CURD操作,可以采取连接池的方式。
要实现也是比较容易的,实现打开一定数量的ObjectContainer,用个List<ObjectContainer>来保存。每次都从list中取出实例来用,用完返回到池内。

[color=red]ExtObjectContainer[/color]
ExtObjectContainer是ObjectContainer的子接口,它可以通过ObjectContainer实例的ext()方法得到。主要是进行一些其他的操作,比如getID(Object obj)得到对象的内部id,getObjectInfo(Object obj)得到对象的信息,getByID(long arg0)根据ID得到对象,getByUUID(Db4oUUID arg0)通过UUID得到对象,purge(Object obj)等。

[color=red]ObjectManager[/color]
这个是db4o的数据库管理工具,个人感觉不是很好用,对于基本的只读查看操作,自己个人做个web页面工具,就像h2database那样的,还是比较麻烦的,希望开发团队在新版本能注意到这方面的问题。如下是这个工具的的截图,网上google出来的:
[img]/upload/attachment/107703/f0ad82e5-0bc6-3ea0-941d-4bfdc1fcd0a6.jpg[/img]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值