android平台db4o使用示例

android平台db4o使用示例db4o是一个纯对象的数据库,现支持java和.NET。07年的时候,db4objects宣布db4o已可以顺利运行于Android平台,当时db4objects公司和db4o的爱好者积极推进db4o运行于GoogleAndroid平台,以期待让db4o成为Android上的首选数据库平台,但令人遗憾的是google最后选择了sqlite作为作为android平台的数据库。但是没有关系,db4o

大家好,又见面了,我是你们的朋友全栈君。

db4o是一个纯对象的数据库,现支持java和.NET。07年的时候,db4objects宣布db4o已可以顺利运行于Android平台,当时db4objects公司和db4o的爱好者积极推进db4o运行于Google Android平台,以期待让db4o成为Android上的首选数据库平台,但令人遗憾的是google最后选择了sqlite作为作为android平台的数据库。但是没有关系,db4objects有相应的解决方案,db4o可以无缝的运行于Android。

相对于关系型数据库,db4o还显得很年轻。大家对关系型数据库的理念根深蒂固,所以一时很难理解对象型数据库的理论。现在的数据库课程也都是以关系型数据库为示例,对象型数据库都是作为一个新兴的数据库一笔带过。这也导致很多人缺乏对象型数据的理论知识。真的想用好db4o,对象型数据的理论知识是必不可少的。例如对象型数据是没有主键这个概念的,这会让大多数人难以适应。

db4o也发展了几年了,到现在好多人还不知道,网上的资料比较少,也是比较老的版本。现在主流的android应用也都是使用sqlite数据库,这肯定是有原因的。这倒不是性能上的问题。Db4o的速度不见得会比关系型数据库慢。其最大的问题在于理解数据对象的关系和操作。db4o没有看上去那么简单,说实在的,我现在好多东西还没搞明白。比如:

class A {
	int id;
	String name;
	List<B> list;
}

存储这种结构的对象,我一直搞不明白A和B的关联情况。对应一些大应用还是建议使用比较成熟的东西。Android平台上大家倒是可以一试,我也分享下自己的学习成果。现在db4o最新是8.x。稳定版本是7.x。本人以7.x演示。要说的是android平台需要的db4o的jar要1M多(8.x版的要1.4M左右,网上说的400k应该是很早的版本了,官网上找不到了)。db4o的官网下载地址http://community.versant.com/Downloads/db4o.aspx。对应android开发只需要核心jar包db4o-7.x-core-java5.jar。在下载的压缩包里还有一个db4o数据库的视图工具OME(ObjectManager Enterprise),这是一个eclipse插件,是一个离线的安装包。

android平台db4o使用示例

Db4o的操作流程很简单:打开数据库文件,通过DAO读写数据,最后关闭数据库,支持事务和并发。

作为对象型数据库是不用写sql的,这点很爽。

 

对于db4o的基本操作不再多说,可以参考文章最后的参考链接。我做了一些封装,并使用泛型来减少Dao的创建。如果不使用本例的泛型的话,你需要对每个bean创建Dao,如UserDao、CacheDao。在关系型数据库中我们通过主键来识别一条记录,但是对象型数据库中没有记录,只有对象。db4o通过序列化java对象并存入文件,它识别是这个还是那个对象用的不是主键,而是UUID,这个UUID只有当一个对象被存入数据库中才会被分配到,未存入数据库的对象是没有UUID的,所以说我们并不能通过UUID来更新一条数据.那怎样更新一条数据?我们只能是先将这个对象查出来,然后修改内容再存入,或者查询到直接删除,然后存入新对象.

Db.java

package com.sljm.lfa.store;import java.io.Serializable;import java.util.ArrayList;import java.util.List;import com.db4o.Db4oEmbedded;import com.db4o.ObjectContainer;import com.db4o.ObjectSet;import com.db4o.config.CommonConfiguration;import com.db4o.config.EmbeddedConfiguration;import com.db4o.query.Query;/** * @author SunnyCoffee * @date 2013-9-7 * @version 1.0 * @desc DB配置和操作接口 */public class Db<T extends Serializable> {	private Class<T> clazz;	private String unique;	private static ObjectContainer db;	/**	 * 这里的unique是class里作为索引的属性	 * 	 * @param clazz	 * @param unique	 */	public Db(Class<T> clazz, String unique) {		this.clazz = clazz;		this.unique = unique;	}	// 打开数据库	private ObjectContainer getDb() {		if (db == null || db.ext().isClosed()) {			db = Db4oEmbedded.openFile(conf(), getDbPath());		}		return db;	}	private String getDbPath() {		return "/mnt/sdcard/lfa.db4o";// 数据库文件的路径	}	// 数据库的参数配置. 数据库配置并没有存储到文件,每次打开数据库执行此方法进行配置	private EmbeddedConfiguration conf() {		EmbeddedConfiguration conf = Db4oEmbedded.newConfiguration();		CommonConfiguration common = conf.common();		if (unique != null) {			common.objectClass(clazz).objectField(unique).indexed(true);		}		common.objectClass(clazz).cascadeOnUpdate(true);		common.objectClass(clazz).cascadeOnActivate(true);		return conf;	}	/**	 * 存储对象	 * 	 * @param obj	 */	public void store(T obj) {		if (obj == null) {			return;		}		getDb().store(obj);	}	public void store(List<T> list) {		if (list == null) {			return;		}		for (T t : list) {			getDb().store(t);		}	}	/**	 * 删除对象	 * 	 * @param obj	 */	public void delete(T obj) {		if (obj == null) {			return;		}		getDb().delete(obj);	}	public void delete(List<T> list) {		if (list == null) {			return;		}		for (T t : list) {			getDb().delete(t);		}	}	/**	 * 查询所有的某一对象	 * 	 * @return	 */	public List<T> queryAll() {		Query query = getDb().query();		query.constrain(clazz);		query.descend(unique).orderAscending();		ObjectSet<T> set = query.execute();		List<T> list = fromObjectSet(set);		return list;	}	/**	 * 根据id查询一个对象	 * 	 * @param field	 *            字段	 * @param id	 *            字段的值	 * @return	 */	public T queryById(Object id) {		List<T> list = queryWhere(unique, id);		if (list.size() == 0) {			return null;		}		return list.get(0);	}	public List<T> queryWhere(String field, Object value) {		Query query = getDb().query();		query.constrain(clazz);		query.descend(field).constrain(value);		ObjectSet<T> set = query.execute();		List<T> list = fromObjectSet(set);		return list;	}	public void close() {		getDb().commit();		if (db != null) {			db.close();			db = null;		}	}	private List<T> fromObjectSet(ObjectSet<T> set) {		List<T> list = new ArrayList<T>();		while (set.hasNext()) {			list.add(set.next());		}		return list;	}}

db4o有3种查询方式,官方一直推荐NQ(Native Queries),也就是原生查询.首先它是类型安全的,其次查询支持本地语言。还有就是QBE(Query by Example)和SODA(Simple Object Database Access)。QBE没有用过,似乎没什么特点。SODA的是最低层的查询方式,速度快、灵活性高,不足之处就是非类型安全的。本例中因为有排序操作,考虑效率和易用性上使用了SODA。

DbApiImpl.java

package com.sljm.lfa.store;import java.util.List;import com.sljm.lfa.bean.Cache;/** * @author SunnyCoffee * @date 2013-10-22 * @version 1.0 * @desc 数据库接口实现类,查询使用SODA。 NQ查询更安全,考虑到效率和简单使用了SODA, *       如此一来必须使用字符串来表示字段,如果javaBean变动这里字段必须做调整 */public class DbApiImpl implements DbApi {	public Cache getCacheById(final String id) {		Db<Cache> db = new Db<Cache>(Cache.class, "id");		Cache cache = db.queryById(id);		db.close();		return cache;	}	public void updateCache(Cache cache) {		Db<Cache> db = new Db<Cache>(Cache.class, "id");		Cache c = db.queryById(cache.getId());		db.delete(c);		db.store(cache);		db.close();	}	public void clearCache() {		Db<Cache> db = new Db<Cache>(Cache.class, "id");		List<Cache> list = db.queryAll();		db.delete(list);		db.close();	}}	

这里注意两点一个是Serializable接口,一个是空构造方法。

Cache.java

package com.sljm.lfa.bean;import java.io.Serializable;/** * @author SunnyCoffee * @create 2013-8-21 * @version 1.0 * @desc 缓存bean */public class Cache implements Serializable {	/**	 * 	 */	private static final long serialVersionUID = 1L;	private String id;	private long lastModified;	private long valid;	private Object result;	public Cache() {	}		// set and get}

参考链接:

http://www.ibm.com/developerworks/cn/java/j-db4o/

http://www.db4o.com

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/162572.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java406错误_Java项目部署遇到406错误[通俗易懂]

    1、406错误发生406错误的原因是服务器传递回来的值客户端无法解析。通过在谷歌浏览器的开发浏览器查看代码,发现RequestHeader的Accept格式为application/json格式,而服务器传回的报文中ResponseHeader的格式却为text/html,导致js解析不了数据,报406错误。因此,我们需要将服务器的数据先转换成json,再将其以application/json的C…

    2022年4月8日
    51
  • Kong插件开发向导

    Kong插件开发向导转载李亚飞大佬的文章:https://www.lyafei.com/简介前面洋洋洒洒写了那么多文章,Kong搭建、Konga搭建、Kong插件开发工具包、Lua算法实现等等,就为了这篇Kong插件开发铺垫,在进一步讨论之前,有必要再简要阐述下Kong是如何构建的,特别是它如何与Nginx集成,以及它与Lua脚本之间的关系。使用lua-nginx-module模块可以在Nginx中启用Lua脚本功能,Kong与OpenResty一起发布,OpenResty中已经包.

    2022年6月26日
    41
  • 第一范式第二范式第三范式「建议收藏」

    第一范式第二范式第三范式「建议收藏」关系数据库中的关系必须满足一定的要求。满足不同程度要求的为不同范式。数据库的设计范式是数据库设计所需要满足的规范。只有理解数据库的设计范式,才能设计出高效率、优雅的数据库,否则可能会设计出错误的数据库. 目前,主要有六种范式:第一范式、第二范式、第三范式、BC范式、第四范式和第五范式。满足最低要求的叫第一范式,简称1NF。在第一范式基础上进一步满足一些要求的为第二范式,简称2NF。其余依此类推

    2022年5月10日
    40
  • 程序员如何学习量化交易,一文总结

    程序员如何学习量化交易,一文总结最近有位金融行业的朋友想把一个盈利能力很强的策略做成量化程序遇到问题,问题是这样的线程A在while(true)的循环里做条件判断,循环耗时1分钟。循环结束判断条件满足的时候调用交易接口下单建仓。想实现条件成立马上建仓,而不需要等待1分钟的循环。想通过多进程或者多线程方式,但两个线程不知道如何交互。对有经验的开发来说这样的逻辑很简单,只要通过线程通信的方式就可以实现。A线程判断到满足条件就发个消息给B线程,B线程while(true)等待消息就行。技术本身不复杂,只是没接触过编程的不知道还可以这么干

    2022年6月26日
    29
  • 关系数据库的设计_关系型数据库的设计原则

    关系数据库的设计_关系型数据库的设计原则1、设计一个合适的关系数据库系统的关键是关系数据库模式的设计,即应构造几个关系模式, 每个模式有哪些属性,怎样将这些相互关联的关系模式组建成一个适合的关系模型,关系数据库 的设计必须在关系数据库设计理论的指导下进行。2、关系数据库设计理论有三个方面的内容:函数依赖、范式和模式设计。函数依赖起核心作用, 它是模式分解和模式设计的基础,范式是模式分解的标准。【例1】设计一个学生课程数据库,其关系…

    2022年8月18日
    24
  • Java后台登录注册管理系统

    Java后台登录注册管理系统转载请注明出处:https://blog.csdn.net/binbinqq86/article/details/81746294项目简介环境搭建ide的选择数据库相关tomcat相关开始JDBC封装DAO封装Junit编写jsp编写servlet编写运行结果写在最后项目简介本文是笔者自己学习后台开发打响的第一枪,也是后台开发最基础的了,记得刚毕业的时候做过一个web项目,一直到今天都没有再了解过这方面,如今重新拾起,感觉还是需要多了解一些后端的东西,如果一直停留在移动端和前

    2022年4月25日
    51

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号