移动端5大数据库比较

5个用于移动开发的最流行数据库对比

 

五个数据库分别从数据库存储类型、优点、缺点、特点、API接口、操作示例六个方面进行阐述。

  • BerkeleyDB

  • 数据库存储类型

  relational,objects, key-value pairs, documents

  1. 2.        优点

  2. a)        处理速度快。

  3. b)        BDB并发高于RDBMS

  4. c)        基于HASH支持select数据比RDBMS快。

  5. d)        高度可移植。不论是32bit,64bit,它可以运行在高端服务器、桌面系统、掌上电脑等。

  6. e)        函数库本身很紧凑,可以运行在高度受限的嵌入式系统上。

  7. 3.        缺点

  8. a)        不支持结构化的查询语言(SQL)

  9. b)        只提供了简单的逻辑操作,对于要求不同服务的应用不合适。

  10. c)        没有提供对交互查询的支持,也没有提供图形化的报表工具。

  11. 4.        特点

  12. a)        采用嵌入式模型。直接连接到应用程序中,和应用程序在同一内存空间运行。这一点是比关系型数据库优越的主要原因,因为和应用运行在同一地址空间,省掉了数据库操作时的进程间通信,不管是在单机还是分布式系统上,进程间通信所花的时间多于函数调用所要的时间。

  13. b)        BDB对所有的操作提供了简洁的函数调用接口,无需对查询语言进行解析,也不需要预执行。

  14. c)        提供了简单的数据访问服务。如:在表中插入一条记录、从表中删除一条记录、通过查询键(key)从表中查找一条记录、更新表中已有的一条记录。

  15. 5.        API接口

  16. a)        打开database环境。

Environment myDbEnvironment=new Environment(File file, envConfig); 

  1. 关闭database环境

myDbEnvironment.close();

  1. 清理日志。

       myDbEnvironment.cleanLog(); 

  1. 打开database

myDbEnvironment.openDatabase( Stringdataname,DatabaseConfig dbConfig);

  1. 关闭database

myDbEnvironment.Close();

  1. 添加记录

Database.put();

  1. 不重复添加记录

Database.putNoOverwrite();

  1. 读取记录

Database.get();

  1. 删除记录

Database.delete();

  1. 6.        操作示例

 详见附录1.

 

  • Couchbase-lite

  • 数据库存储类型

documents

  1. 2.        优点

  2. a)        轻量级、嵌入式,可同步的NoSql数据引擎。提供了一种简单的方法来跨设备同步应用程序的数据。

  3. b)        支持不同结构的数据存储。

  4. c)        支持对等复制。

  5. d)        支持低延时、离线下获取数据。

  6. 3.        缺点

  7. a)        不支持sql语句。

  8. 4.        特点

  9. a)        主要模块包含:Manager(类似数据库)Database(类似table)、Document(类似)、RevisionAttachmentViewQueryReplicationModel

  10. b)        Manager管理一系列的Database

  11. 5.        API接口

  12. a)        创建一个Manager实例。

Managermanager=new Manager(AndroidContext aContext,Option o);

  1. 创建一个Database实例。

Database db=manager.getDatabase(Stringname);//如果manager中没有该database,就会自动生成一个空的database

  1. 添加数据改动说明。

       db.addChangeListener(new ChangeListener(){})

  1. 删除database

  myDatabase.delete();

  1. 创建document

Document document =database.createDocument();

  1. 读取document

Document doc =database.getDocument(myDocId);

  1. 更新document

Document doc = database.getDocument(myDocId);
doc.update(new Document.DocumentUpdater() {}
h)        删除document。
doc.delete();

 

  1. 6.        操作

详见附录2.

  • SqlLite

  • 数据库存储类型

relational

  1. 2.        优点

  2. a)        轻量

  3. b)        单一文件。所有的信息(比如表、视图、触发器等)都包含在同一个文件中,这个文件可以拷贝到其他目录或者其他机器,不需要其他改变。

  4. c)        跨平台、可移植。不仅支持主流操作系统,还支持其他的androidwindows phonesymbin等。

  5. d)        关系型数据库、支持sql语句。

  6. 3.        缺点

  7. a)        SQL标准不全,官网上列举了所有不支持的SQL92标准,最明显是不支持外键约束。

  8. b)        需要其他机器读取SQLite数据库文件,当使用NFS并发读取的时候出现数据损坏问题。

  9. c)        省略了一些比较有用的特性,例如高并发性、严格的存取控制,存储过程等等。

  10. 4.        特点

  11. a)        它是大小写不敏感的。

  12. b)        字段是无类型(Typelessness)的。

  13. 5.        API接口

  14. a)        创建数据库。

Publicstatic SQLiteDatabase openOrCreateDatabase (String path, SQLiteDatabase.CursorFactory factory);

  1. 关闭数据库

public void close ();

  1. 增加数据。

SQLiteDatabase.insert(Stringtable,String nullColumnHack, ContentValues values);

  1. 删除数据。

SQLiteDatabase.delete(Stringtable,String whereClause,String [] whereArgs);

  1. 更新数据。

public int update (String table, ContentValues values, String whereClause, String[] whereArgs);

  1. 查寻数据。

public Cursor query (booleandistinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);

 

  1. 6.        操作

      详见附录3.

  • LevelDB

  • 数据库存储类型

key-valuepairs

  1. 2.        优点

  2. a)        操作简单,写入速度快。

  3. 3.        缺点

  4. b)        接口较少,很多复杂的数据库操作不支持。

  5. 4.        特点

  6. a)        LevelDb是一个持久化存储的KV系统,将大部分数据存储到磁盘上。

  7. b)        存储数据时,会根据记录的key有序存储,也就是说相邻的key值在存储文件中是依次顺序存储的,而用户可以自己定义key的比较函数。

  8. c)        LevelDb的操作接口很简单,基本操作包括写记录,读记录以及删除记录。

  9. d)        支持数据快照功能,使得读取操作不受写操作影响,可以再读操作过程中始终看到一致的数据。

  10. 5.        API接口

  11. a)        插入一条数据。

publicSnapshot put(byte[] key, byte[] value, WriteOptions options) throwsDBException;

  1. 删除一条数据。

publicSnapshot delete(byte[] key, WriteOptions options) throws DBException;

  1. 获取一条数据。

public byte[]get(byte[] key, ReadOptions options) throws DBException;

  1. 6.        操作

详见附录4

  • UnQlite

  • 数据库存储类型

key-valuepairs, documents

  1. 2.        优点

  2. a)        零配置,事务化。

  3. b)        跨平台。可以在32bit64bit之间切换。

  4. c)        是一个自包含的C库,无外部依赖。

  5. d)        是一个标准的key/value存储,但是与BerkeleyDBLevelDB相比,拥有更加丰富的特性集,包括支持事务、并发读等。

  6. 3.        缺点

  7. a)        不支持java语言。

  8. 4.        特点

  9. a)        无服务器的数据库引擎。

  10. b)        支持事务化。

  11. c)        零配置。

  12. d)        单一数据库文件,不使用临时文件。

  13. e)        跨平台的文件格式。

  14. f)         自包含C库,对外部无依赖。

  15. g)        标准的key-value存储格式。

  16. h)        基于jx9标准存储json文档存储数据库。

  17. i)          支持游标,满足线性记录遍历。

  18. j)          简单、清晰,容易使用的API

  19. 5.        API接口

java接口

  1. 6.        操作

java接口

  • 综合意见:

  • sqllite是最符合传统数据库的关系型数据库,如果所要保存的数据是符合关系型数据库的规则,那sqllite是最佳选择。

  • Couchbase-lite最明显的特点是跨设备同步应用程序的数据。它对每一次的数据操作都会生成操作说明文件,以此来对不同设备的操作进行数据统一,所以如果类似icloud等操作可以选用Couchbase-lite数据库。

  • UnQlite不支持java API,如果使用c,可以考虑。

  • LevelDBBerkeley DB都支持key-value存储,BerkeleyDB支持数千的并发线程同时操作数据库,支持最大256Tb的数据,LevelDB支持快照功能,也支持数据的正向和反向遍历访问,支持多线程同步,但是不支持多线程同时访问,各有利弊,可根据具体的需求进行选择。

 

 

 附录1

package je.gettingStarted;  

 

import com.sleepycat.je.DatabaseException;  

 

import com.sleepycat.je.Environment;  

  

import com.sleepycat.je.EnvironmentConfig;  

 

import java.io.File;  

 

..  

 

Environment myDbEnvironment = null;  

 

try {  

 

   EnvironmentConfig envConfig = new EnvironmentConfig();  

 

   envConfig.setAllowCreate(true);//如果不存在则创建一个  

 

   myDbEnvironment = new Environment(new File("/export/dbEnv"), envConfig);  

 

} catch (DatabaseException dbe) {  

 

   // 错误处理  

 

}  

 

2. 关闭database环境  

 

可以通过Environment.close()这个方法来关闭database环境,当你完成数据库操作后一定要关闭数据库环境。  

  

示例:  

  

import com.sleepycat.je.DatabaseException;  

  

import com.sleepycat.je.Environment;  

  

...  

  

try {  

  

    if (myDbEnvironment != null) {  

  

        myDbEnvironment.close();  

  

    }  

  

} catch (DatabaseException dbe) {  

  

    // Exception handling goes here  

  

}  

  

3. 清理日志  

  

通常在关闭数据库连接的时候,有必要清理下日志,用以释放更多的磁盘空间。我们可以在Environment.close前执行下Environment.cleanLog()来达到此目的。  

  

示例:  

  

import com.sleepycat.je.DatabaseException;  

  

import com.sleepycat.je.Environment;  

  

...  

  

try {  

  

    if (myDbEnvironment != null) {  

  

        myDbEnvironment.cleanLog(); // 在关闭环境前清理下日志  

  

        myDbEnvironment.close();  

  

    }  

  

} catch (DatabaseException dbe) {  

  

    // Exception handling goes here  

  

}  

  

4. Database环境的配置  

  

可以通过EnvironmentConfig这个对象来配置database环境。如果想得到当前环境的配置信息则可以通过Environment.getConfig()方法得到当前环境的配置信息。  

  

也可以使用EnvironmentMutableConfig来配置环境,其实 EnvironmentConfig是EnvironmentMutableConfig的子类,所以EnvironmentMutableConfig能够使用的设置,EnvironmentConfig也同样能够使用。  

  

如果你要获取当前环境的使用情况,那么你可以通过使用EnvironmentStats.getNCacheMiss().来监视RAM cache命中率。EnvironmentStats可以由Environment.getStats()方法获取。  

  

EnvironmentConfig常见方法介绍  

  

 EnvironmentConfig.setAllowCreate() ;  

  

如果设置了true则表示当数据库环境不存在时候重新创建一个数据库环境,默认为false.  

  

 EnvironmentConfig.setReadOnly()  

  

以只读方式打开,默认为false.  

  

 EnvironmentConfig.setTransactional()  

  

事务支持,如果为true,则表示当前环境支持事务处理,默认为false,不支持事务处理。  

  

EnvironmentMutableConfig的介绍  

  

 setCachePercent()  

  

设置当前环境能够使用的RAM占整个JVM内存的百分比。  

  

 setCacheSize()  

  

设置当前环境能够使用的最大RAM。单位BYTE  

  

 setTxnNoSync()  

  

当提交事务的时候是否把缓存中的内容同步到磁盘中去。  

  

true 表示不同步,也就是说不写磁盘  

  

 setTxnWriteNoSync()  

  

当提交事务的时候,是否把缓冲的log写到磁盘上  

  

true 表示不同步,也就是说不写磁盘  

  

示例一:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.DatabaseException;  

  

import com.sleepycat.je.Environment;  

  

import com.sleepycat.je.EnvironmentConfig;  

  

import java.io.File;  

  

...  

  

Environment myDatabaseEnvironment = null;  

  

try {  

  

    EnvironmentConfig envConfig = new EnvironmentConfig();  

  

    //当环境不存在的时候自动创建环境  

  

       envConfig.setAllowCreate(true);  

  

       //设置支持事务  

  

       envConfig.setTransactional(true);  

  

    myDatabaseEnvironment =  

  

        new Environment(new File("/export/dbEnv"), envConfig);  

  

} catch (DatabaseException dbe) {  

  

   System.err.println(dbe.toString());  

  

   System.exit(1);  

  

}  

  

示例二:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.DatabaseException;  

  

import com.sleepycat.je.Environment;  

  

import com.sleepycat.je.EnvironmentMutableConfig;  

  

import java.io.File;  

  

...  

  

try {  

  

    Environment myEnv = new Environment(new File("/export/dbEnv"), null);  

  

    EnvironmentMutableConfig envMutableConfig =  

  

        new EnvironmentMutableConfig();  

  

    envMutableConfig.setTxnNoSync(true);  

  

    myEnv.setMutableConfig(envMutableConfig);  

  

} catch (DatabaseException dbe) {  

  

    // Exception handling goes here  

  

}  

  

示例三:  

  

import com.sleepycat.je.Environment;  

  

...  

  

//没有命中的CACHE  

  

long cacheMisses = myEnv.getStats(null).getNCacheMiss();  

  

...  

  

5. Database操作  

  

在BDB中,数据是以key/value方式成队出现的。  

  

打开database  

  

可以通过environment.openDatabase()方法打开一个database,在调用这个方法的时候必须指定database的名称。和databaseConfig() (注:数据库设置)  

  

示例:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseConfig;  

  

import com.sleepycat.je.DatabaseException;  

  

import com.sleepycat.je.Environment;  

  

import com.sleepycat.je.EnvironmentConfig;  

  

import java.io.File;  

  

...  

  

Environment myDbEnvironment = null;  

  

Database myDatabase = null;  

  

...  

  

try {  

  

    // 打开一个环境,如果不存在则创建一个  

  

    EnvironmentConfig envConfig = new EnvironmentConfig();  

  

    envConfig.setAllowCreate(true);  

  

    myDbEnvironment = new Environment(new File("/export/dbEnv"), envConfig);  

  

    // 打开一个数据库,如果数据库不存在则创建一个  

  

    DatabaseConfig dbConfig = new DatabaseConfig();  

  

dbConfig.setAllowCreate(true);  

  

    myDatabase = myDbEnvironment.openDatabase(null,  

  

"sampleDatabase", dbConfig); //打开一个数据库,数据库名为  

  

                                   //sampleDatabase,数据库的配置为dbConfig  

  

} catch (DatabaseException dbe) {  

  

    // 错误处理  

  

}  

  

关闭database  

  

通过调用Database.close()方法来关闭数据库,但要注意,在关闭数据库前必须得先把游标先关闭。  

  

使用示例:  

  

import com.sleepycat.je.DatabaseException;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.Environment;  

  

...  

  

try {  

  

        if (myDatabase != null) {  

  

            myDatabase.close();  

  

        }  

  

        if (myDbEnvironment != null) {  

  

            myDbEnvironment.close();  

  

        }  

  

} catch (DatabaseException dbe) {  

  

    // 错误处理  

  

}  

  

设置数据库属性  

  

其实设置数据库属性跟设置环境属性差不多,JE中通过DatabaseConfig对象来设置数据库属性。你能够设置的数据库属性如下。  

  

 DatabaseConfig.setAllowCreate()  

  

如果是true的话,则当不存在此数据库的时候创建一个。  

  

 DatabaseConfig.setBtreeComparator()  

  

设置用于Btree比较的比较器,通常是用来排序  

  

 DatabaseConfig.setDuplicateComparator()  

  

设置用来比较一个key有两个不同值的时候的大小比较器。  

  

 DatabaseConfig.setSortedDuplicates()  

  

设置一个key是否允许存储多个值,true代表允许,默认false.  

  

 DatabaseConfig.setExclusiveCreate()  

  

以独占的方式打开,也就是说同一个时间只能有一实例打开这个database。  

  

 DatabaseConfig.setReadOnly()  

  

以只读方式打开database,默认是false.  

  

 DatabaseConfig.setTransactional()  

  

如果设置为true,则支持事务处理,默认是false,不支持事务。  

  

使用示例:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.DatabaseException;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseConfig;  

  

...  

  

// Environment open omitted for brevity  

  

...  

  

Database myDatabase = null;  

  

try {  

  

    DatabaseConfig dbConfig = new DatabaseConfig();  

  

    dbConfig.setAllowCreate(true);  

  

    dbConfig.setSortedDuplicates(true);  

  

    myDatabase =  

  

        myDbEnv.openDatabase(null,  

  

                             "sampleDatabase",  

  

                             dbConfig);  

  

} catch (DatabaseException dbe) {  

  

    // Exception handling goes here.  

  

}  

  

一些用来管理的方法  

  

l Database.getDatabaseName()  

  

取得数据库的名称  

  

如:String dbName = myDatabase.getDatabaseName();  

  

l Database.getEnvironment()  

  

取得包含这个database的环境信息  

  

如:Environment theEnv = myDatabase.getEnvironment();  

  

l Database.preload()  

  

预先加载指定bytes的数据到RAM中。  

  

如:myDatabase.preload(1048576l); // 1024*1024  

  

l Environment.getDatabaseNames()  

  

返回当前环境下的数据库列表  

  

如:  

  

import java.util.List;  

  

List myDbNames = myDbEnv.getDatabaseNames();  

  

for(int i=0; i < myDbNames.size(); i++) {  

  

    System.out.println("Database Name: " + (String)myDbNames.get(i));  

  

}  

  

l Environment.removeDatabase()  

  

删除当前环境中指定的数据库。  

  

如:  

  

String dbName = myDatabase.getDatabaseName();  

  

myDatabase.close();  

  

myDbEnv.removeDatabase(null, dbName);  

  

l Environment.renameDatabase()  

  

给当前环境下的数据库改名  

  

如:  

  

String oldName = myDatabase.getDatabaseName();  

  

String newName = new String(oldName + ".new", "UTF-8");  

  

myDatabase.close();  

  

myDbEnv.renameDatabase(null, oldName, newName);  

  

l Environment.truncateDatabase()  

  

清空database内的所有数据,返回清空了多少条记录。  

  

如:  

  

Int numDiscarded= myEnv.truncate(null,  

  

myDatabase.getDatabaseName(),true);  

  

System.out.println("一共删除了 " + numDiscarded +" 条记录 从数据库 " + myDatabase.getDatabaseName());  

  

6. Database 记录  

  

JE的记录包含两部分,key键值和value数据值,这两个值都是通过DatabaseEntry对象封装起来,所以说如果要使用记录,则你必须创建两个DatabaseEntry对象,一个是用来做为key,另外一个是做为value.  

  

DatabaseEntry能够支持任何的能够转换为bytes数组形式的基本数据。包括所有的JAVA基本类型和可序列化的对象.  

  

  

使用记录  

  

示例一:把字符串转换DatabaseEntry  

  

package je.gettingStarted;  

  

import com.sleepycat.je.DatabaseEntry;  

  

...  

  

String aKey = "key";  

  

String aData = "data";  

  

try {  

  

//设置key/value,注意DatabaseEntry内使用的是bytes数组  

  

DatabaseEntry theKey=new DatabaseEntry(aKey.getBytes("UTF-8"));  

  

DatabaseEntry theData=new DatabaseEntry(aData.getBytes("UTF-8"));  

  

} catch (Exception e) {  

  

    // 错误处理  

  

}  

  

示例二:把DatabaseEntry里的数据转换成字符串  

  

byte[] myKey = theKey.getData();  

  

byte[] myData = theData.getData();  

  

String key = new String(myKey, "UTF-8");  

  

String data = new String(myData, "UTF-8");  

  

读和写database 记录  

  

读和写database记录的时候大体是基本一样的,唯一有区别的是每个key写是否允许写多条记录,默认情况下是不支持多条记录的。  

  

a) 你可以使用如下方法向database 里添加记录  

  

 Database.put()  

  

向database中添加一条记录。如果你的database不支持一个key对应多个data或当前database中已经存在该key了,则使用此方法将使用新的值覆盖旧的值。  

  

 Database.putNoOverwrite()  

  

向database中添加新值但如果原先已经有了该key,则不覆盖。不管database是否允许支持多重记录(一个key对应多个value),只要存在该key就不允许添加,并且返回perationStatus.KEYEXIST信息。  

  

 Database.putNoDupData()  

  

想database中添加一条记录,如果database中已经存在了相同的 key和value则返回 OperationStatus.KEYEXIST.  

  

使用示例:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseEntry;  

  

...  

  

String aKey = "myFirstKey";  

  

String aData = "myFirstData";  

  

try {  

  

    DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));  

  

    DatabaseEntry theData = new DatabaseEntry(aData.getBytes("UTF-8"));  

  

    myDatabase.put(null, theKey, theData);  

  

} catch (Exception e) {  

  

    // Exception handling goes here  

  

}  

  

b) 你可以使用如下方法从database 里读取记录  

  

1. Database.get()  

  

基本的读记录的方法,通过key的方式来匹配,如果没有改记录则返回OperationStatus.NOTFOUND。  

  

l Database.getSearchBoth()  

  

通过key和value来同时匹配,同样如果没有记录匹配key和value则会返回OperationStatus.NOTFOUND。  

  

使用示例:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseEntry;  

  

import com.sleepycat.je.LockMode;  

  

import com.sleepycat.je.OperationStatus;  

  

...  

  

String aKey = "myFirstKey";  

  

try {  

  

    DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));  

  

    DatabaseEntry theData = new DatabaseEntry();  

  

if (myDatabase.get(null, theKey, theData, LockMode.DEFAULT) ==  

  

        OperationStatus.SUCCESS) {  

  

        byte[] retData = theData.getData();  

  

        String foundData = new String(retData, "UTF-8");  

  

        System.out.println("For key: '" + aKey + "' found data: '" +  

  

                            foundData + "'.");  

  

    } else {  

  

        System.out.println("No record found for key '" + aKey + "'.");  

  

    }  

  

} catch (Exception e) {  

  

    // Exception handling goes here  

  

}  

  

c) 删除记录  

  

可以使用Database.delete()这个方法来删除记录。如果你的database支持多重记录,则当前key下的所有记录都会被删除,如果只想删除多重记录中的一条则可以使用游标来删除。  

  

当然你也可以使用Environment.truncateDatabase()这个方法来清空database 中的所有记录。  

  

  

使用示例:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseEntry;  

  

...  

  

try {  

  

    String aKey = "myFirstKey";  

  

    DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));  

  

    myDatabase.delete(null, theKey);  

  

} catch (Exception e) {  

  

}  

  

d) 提交事务  

  

当你对database进行了写操作的时候,你的修改不一定马上就能生效,有的时候他仅仅是缓存在RAM中,如果想让你的修改立即生效,则可以使用Environment.sync()方法来把数据同步到磁盘中去。  

  

e) 不同类型的数据的处理  

  

1. 你可以使用DatabaseEntry来绑定基本的JAVA数据类型,主要有String、Character、Boolean、Byte、Short、Integer、Long、Float、Double.  

  

使用示例一:  

  

package je.gettingStarted;  

  

import com.sleepycat.bind.EntryBinding;  

  

import com.sleepycat.bind.tuple.TupleBinding;  

  

import com.sleepycat.je.DatabaseEntry;  

  

...  

  

try {  

  

    String aKey = "myLong";  

  

    DatabaseEntry theKey = new  

  

    DatabaseEntry(aKey.getBytes("UTF-8"));     

  

    Long myLong = new Long(123456789l);  

  

DatabaseEntry theData = new DatabaseEntry();  

  

EntryBinding myBinding =  

  

    TupleBinding.getPrimitiveBinding(Long.class);  

  

    myBinding.objectToEntry(myLong, theData);  

  

    myDatabase.put(null, theKey, theData);  

  

} catch (Exception e) {  

  

    // Exception handling goes here  

  

}  

  

使用示例二:  

  

package je.gettingStarted;  

  

import com.sleepycat.bind.EntryBinding;  

  

import com.sleepycat.bind.tuple.TupleBinding;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseEntry;  

  

import com.sleepycat.je.LockMode;  

  

import com.sleepycat.je.OperationStatus;  

  

...  

  

Database myDatabase = null;  

  

try {  

  

       String aKey = "myLong";  

  

       DatabaseEntry theKey = new  

  

       DatabaseEntry(aKey.getBytes("UTF-8"));  

  

DatabaseEntry theData = new DatabaseEntry();  

  

EntryBinding myBinding =         

  

       TupleBinding.getPrimitiveBinding(Long.class);  

  

       OperationStatus retVal = myDatabase.get(null, theKey, theData,  

  

       LockMode.DEFAULT);  

  

       String retKey = null;  

  

       if (retVal == OperationStatus.SUCCESS) {  

  

    Long theLong = (Long) myBinding.entryToObject(theData);  

  

           retKey = new String(theKey.getData(), "UTF-8");  

  

           System.out.println("For key: '" + retKey + "' found Long: '" +  

  

                        theLong + "'.");  

  

       } else {  

  

           System.out.println("No record found for key '" + retKey + "'.");  

  

       }  

  

} catch (Exception e) {  

  

       // Exception handling goes here  

  

}  

  

2. 可序列化的对象的绑定  

  

1. 首先你需要创建一个可序列化对象  

  

2. 打开或创建你的database,你需要两个,一个用来存储你的数据,另外一个用来存储类信息。  

  

3. 实例化catalog类,这个时候你可以使用com.sleepycat.bind.serial.StoredClassCatalog,来存储你的类信息。  

  

4. 通过com.sleepycat.bind.serial.SerialBinding来绑定数据和类。  

  

5. 绑定并存储数据。  

  

示例:  

  

l 创建一个可序列化的对象  

  

package je.gettingStarted;  

  

import java.io.Serializable;  

  

public class MyData implements Serializable {  

  

    private long longData;  

  

    private double doubleData;  

  

    private String description;  

  

    MyData() {  

  

        longData = 0;  

  

        doubleData = 0.0;  

  

        description = null;  

  

    }  

  

    public void setLong(long data) {  

  

        longData = data;  

  

    }  

  

    public void setDouble(double data) {  

  

        doubleData = data;  

  

    }  

  

    public void setDescription(String data) {  

  

        description = data;  

  

    }  

  

    public long getLong() {  

  

        return longData;  

  

    }  

  

    public double getDouble() {  

  

        return doubleData;  

  

    }  

  

    public String getDescription() {  

  

        return description;  

  

    }  

  

}  

  

l 存储数据  

  

package je.gettingStarted;  

  

import com.sleepycat.bind.EntryBinding;  

  

import com.sleepycat.bind.serial.StoredClassCatalog;  

  

import com.sleepycat.bind.serial.SerialBinding;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseConfig;  

  

import com.sleepycat.je.DatabaseEntry;  

  

...  

  

String aKey = "myData";  

  

MyData data2Store = new MyData();  

  

data2Store.setLong(123456789l);  

  

data2Store.setDouble(1234.9876543);  

  

data2Store.setDescription("A test instance of this class");  

  

try {  

  

    DatabaseConfig myDbConfig = new DatabaseConfig();  

  

    myDbConfig.setAllowCreate(true);  

  

    myDbConfig.setSortedDuplicates(true);  

  

    Database myDatabase = myDbEnv.openDatabase(null, "myDb", myDbConfig);  

  

    myDbConfig.setSortedDuplicates(false);  

  

//打开用来存储类信息的库  

  

    Database myClassDb = myDbEnv.openDatabase(null, "classDb", myDbConfig);  

  

    // 3)创建catalog  

  

    StoredClassCatalog classCatalog = new StoredClassCatalog(myClassDb);  

  

  // 4)绑定数据和类  

  

    EntryBinding dataBinding = new SerialBinding(classCatalog,  

  

                                                 MyData.class);  

  

    DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));  

  

  // 向DatabaseEntry里写数据  

  

    DatabaseEntry theData = new DatabaseEntry();  

  

    dataBinding.objectToEntry(data2Store, theData);  

  

    myDatabase.put(null, theKey, theData);  

  

} catch (Exception e) {  

  

    // 错误处理  

  

}  

  

l 读数据  

  

package je.gettingStarted;  

  

import com.sleepycat.bind.EntryBinding;  

  

import com.sleepycat.bind.serial.StoredClassCatalog;  

  

import com.sleepycat.bind.serial.SerialBinding;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseConfig;  

  

import com.sleepycat.je.DatabaseEntry;  

  

import com.sleepycat.je.LockMode;  

  

...  

  

// The key data.  

  

String aKey = "myData";  

  

try {  

  

    DatabaseConfig myDbConfig = new DatabaseConfig();  

  

    myDbConfig.setAllowCreate(false);  

  

    Database myDatabase = myDbEnv.openDatabase(null, "myDb", myDbConfig);  

  

       //用来存储类信息的库  

  

Database myClassDb = myDbEnv.openDatabase(null, "classDb", myDbConfig);  

  

// 实例化catalog  

  

    StoredClassCatalog classCatalog = new StoredClassCatalog(myClassDb);  

  

// 创建绑定对象  

  

    EntryBinding dataBinding = new SerialBinding(classCatalog,  

  

                                                 MyData.class);  

  

    DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));  

  

    DatabaseEntry theData = new DatabaseEntry();  

  

    myDatabase.get(null, theKey, theData, LockMode.DEFAULT);  

  

    // Recreate the MyData object from the retrieved DatabaseEntry using  

  

    // 根据存储的类信息还原数据  

  

MyData retrievedData=(MyData)dataBinding.entryToObject(theData);  

  

} catch (Exception e) {  

  

    // Exception handling goes here  

  

}  

  

3. 自定义对象的绑定  

  

使用tuple binding 来绑定自定义数据的步骤  

  

①. 实例化你要存储的对象  

  

②. 通过com.sleepycat.bind.tuple.TupleBinding class来创建一个tuple binding。  

  

③. 创建一个database,跟序列化的对象不同,你只需要创建一个。  

  

④. 通过继承第二步的类来创建一个entry binding 对象。  

  

⑤. 存储和使用数据  

  

使用示例:  

  

l 创建要存储的对象  

  

package je.gettingStarted;  

  

public class MyData2 {  

  

    private long longData;  

  

    private Double doubleData;  

  

    private String description;  

  

    public MyData2() {  

  

        longData = 0;  

  

        doubleData = new Double(0.0);  

  

        description = "";  

  

    }  

  

    public void setLong(long data) {  

  

        longData = data;  

  

    }  

  

    public void setDouble(Double data) {  

  

        doubleData = data;  

  

    }  

  

    public void setString(String data) {  

  

        description = data;  

  

    }  

  

    public long getLong() {  

  

        return longData;  

  

    }  

  

    public Double getDouble() {  

  

        return doubleData;  

  

    }  

  

    public String getString() {  

  

        return description;  

  

    }  

  

}  

  

l 创建一个TupleBinding对象  

  

package je.gettingStarted;  

  

import com.sleepycat.bind.tuple.TupleBinding;  

  

import com.sleepycat.bind.tuple.TupleInput;  

  

import com.sleepycat.bind.tuple.TupleOutput;  

  

public class MyTupleBinding extends TupleBinding {  

  

    // 把对象转换成TupleOutput  

  

    public void objectToEntry(Object object, TupleOutput to) {  

  

        MyData2 myData = (MyData2)object;  

  

to.writeDouble(myData.getDouble().doubleValue());  

  

        to.writeLong(myData.getLong());  

  

        to.writeString(myData.getString());  

  

    }  

  

   //把TupleInput转换为对象  

  

    public Object entryToObject(TupleInput ti) {  

  

Double theDouble = new Double(ti.readDouble());  

  

        long theLong = ti.readLong();  

  

        String theString = ti.readString();  

  

        MyData2 myData = new MyData2();  

  

        myData.setDouble(theDouble);  

  

        myData.setLong(theLong);  

  

        myData.setString(theString);  

  

        return myData;  

  

    }  

  

}  

  

l  读和写数据  

  

package je.gettingStarted;  

  

import com.sleepycat.bind.tuple.TupleBinding;  

  

import com.sleepycat.je.DatabaseEntry;  

  

...  

  

TupleBinding keyBinding = new MyTupleBinding();  

  

MyData2 theKeyData = new MyData2();  

  

theKeyData.setLong(123456789l);  

  

theKeyData.setDouble(new Double(12345.6789));  

  

theKeyData.setString("My key data");  

  

DatabaseEntry myDate = new DatabaseEntry();  

  

try {  

  

    // 把theKeyData 存储到DatabaseEntry里  

  

    keyBinding.objectToEntry(theKeyData, myDate);  

  

    ...  

  

    // Database 进行了一些读和写操作  

  

    ...  

  

    // Retrieve the key data  

  

    theKeyData = (MyData2) keyBinding.entryToObject(myDate);  

  

} catch (Exception e) {  

  

    // 错误处理  

  

}  

  

f) 使用比较器  

  

JE是使用BTrees来组织结构的,这意味着当对database的读和写需要涉及BTrees间的节点比较。这些比较在key间是经常的发生的。如果你的database支持多重记录,那么也会存在data间的比较。  

  

默认的情况JE的比较器是按照字节的方式来进行比较的,这通常情况下能处理大多数的情况。但有的时候确实需要自定义比较器用于特殊的通途,比如说按照key来排序。  

  

l 创建自己的比较器  

  

其实很简单,只要你重写Comparator class中的比较方法(compare)就可以了,通过Comparator.compare()会传递给你两个byte 数组形式的值,如果你知道结构,则可以根据你自己定义的方法来进行比较  

  

  

示例:  

  

package je.gettingStarted;  

  

import java.util.Comparator;  

  

public class MyDataComparator implements Comparator {  

  

    public MyDataComparator() {}  

  

    public int compare(Object d1, Object d2) {  

  

        byte[] b1 = (byte[])d1;  

  

        byte[] b2 = (byte[])d2;  

  

        String s1 = new String(b1, "UTF-8");  

  

        String s2 = new String(b2, "UTF-8");  

  

return s1.compareTo(s2);  

  

    }  

  

}  

  

l 让database使用你自定义的比较器  

  

如果你想改变database中基本的排序方式,你只能重新创建database并重新导入数据。  

  

①. DatabaseConfig.setBtreeComparator()  

  

用于在database里两个key的比较  

  

②. DatabaseConfig.setOverrideBtreeComparator()  

  

如果为true则代表让database使用 DatabaseConfig.setBtreeComparator()设置的比较器来代替默认的比较器。  

  

③. DatabaseConfig.setDuplicateComparator()  

  

用于database可以使用多重记录的时候的data的 比较。  

  

④. DatabaseConfig.setOverrideDuplicateComparator()  

  

如果为true则代表让database使用 DatabaseConfig. setDuplicateComparator()设置 的比 较器来代替默认的比较器。  

  

使用示例:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseConfig;  

  

import com.sleepycat.je.DatabaseException;  

  

import java.util.Comparator;     

  

...  

  

try {  

  

    DatabaseConfig myDbConfig = new DatabaseConfig();  

  

    myDbConfig.setAllowCreate(true);  

  

// 设置要使用的比较器  

  

    myDbConfig.setDuplicateComparator(MyDataComparator.class);  

  

    // 使用自己定义的比较器  

  

    myDbConfig.setSortedDuplicates(true);  

  

    Database myDatabase = myDbEnv.openDatabase(null, "myDb", myDbConfig);  

  

} catch (DatabaseException dbe) {  

  

    // Exception handling goes here  

  

}  

  

六、 游标的使用  

  

游标提供了遍历你database中记录的一种机制,使用游标你可以获取,添加,和删除你的记录。如果你的database支持多重记录,则可以通过游标访问同一个key下的每一个记录。  

  

l 打开和关闭游标  

  

要想使用游标则你必须通过Database.openCursor()方法来打开一个游标,你可以通过CursorConfig来配置你的游标。  

  

可以通过Cursor.close()方法来关闭游标。请注意在关闭database和环境前一定要关闭游标,否则会带来错误。  

  

打开游标示例:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.Cursor;  

  

import com.sleepycat.je.CursorConfig;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseException;  

  

import com.sleepycat.je.Environment;  

  

import java.io.File;  

  

...  

  

Environment myDbEnvironment = null;  

  

Database myDatabase = null;  

  

Cursor myCursor = null;  

  

try {  

  

    myDbEnvironment = new Environment(new File("/export/dbEnv"), null);  

  

    myDatabase = myDbEnvironment.openDatabase(null, "myDB", null);  

  

    myCursor = myDatabase.openCursor(null, null);  

  

} catch (DatabaseException dbe) {  

  

    // Exception handling goes here ...  

  

}  

  

关闭游标示例:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.Cursor;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.Environment;  

  

...  

  

try {  

  

    ...  

  

} catch ... {  

  

} finally {  

  

    try {  

  

        if (myCursor != null) {  

  

            myCursor.close();  

  

        }  

  

        if (myDatabase != null) {  

  

            myDatabase.close();  

  

        }  

  

        if (myDbEnvironment != null) {  

  

            myDbEnvironment.close();  

  

        }  

  

    } catch(DatabaseException dbe) {  

  

        System.err.println("Error in close: " + dbe.toString());  

  

    }  

  

}  

  

l 通过游标来获取记录  

  

可以通过游标的Cursor.getNext()方法来遍历记录,Cursor.getNext()表示游标指针向下移动一条记录。同样的Cursor.getPrev()表示游标指针向上移动一条记录。  

  

使用示例一:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.Cursor;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseEntry;  

  

import com.sleepycat.je.DatabaseException;  

  

import com.sleepycat.je.LockMode;  

  

import com.sleepycat.je.OperationStatus;  

  

...  

  

Cursor cursor = null;  

  

try {  

  

    cursor = myDatabase.openCursor(null, null);  

  

    DatabaseEntry foundKey = new DatabaseEntry();  

  

    DatabaseEntry foundData = new DatabaseEntry();  

  

    // 通过cursor.getNex方法来遍历记录  

  

while (cursor.getNext(foundKey, foundData, LockMode.DEFAULT) ==  

  

        OperationStatus.SUCCESS) {  

  

String keyString = new String(foundKey.getData(), "UTF-8");  

  

        String dataString = new String(foundData.getData(), "UTF-8");  

  

        System.out.println("Key | Data : " + keyString + " | " +  

  

                       dataString + "");  

  

    }  

  

} catch (DatabaseException de) {  

  

    System.err.println("Error accessing database." + de);  

  

} finally {  

  

    // 使用后必须关闭游标  

  

    cursor.close();  

  

}  

  

使用示例二:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.Cursor;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseEntry;  

  

import com.sleepycat.je.DatabaseException;  

  

import com.sleepycat.je.LockMode;  

  

import com.sleepycat.je.OperationStatus;  

  

...  

  

Cursor cursor = null;  

  

try {  

  

    ...  

  

    // Open the cursor.  

  

    cursor = myDatabase.openCursor(null, null);  

  

    DatabaseEntry foundKey = new DatabaseEntry();  

  

    DatabaseEntry foundData = new DatabaseEntry();  

  

    // 使用cursor.getPrev方法来遍历游标获取数据  

  

   while (cursor.getPrev(foundKey, foundData, LockMode.DEFAULT)  

  

       == OperationStatus.SUCCESS) {  

  

        String theKey = new String(foundKey.getData(), "UTF-8");  

  

        String theData = new String(foundData.getData(), "UTF-8");  

  

        System.out.println("Key | Data : " + theKey + " | " + theData + "");  

  

    }  

  

} catch (DatabaseException de) {  

  

    System.err.println("Error accessing database." + de);  

  

} finally {  

  

    // 使用后必须关闭游标  

  

    cursor.close();  

  

}  

  

l 搜索数据  

  

你可以通过游标方式搜索你的database记录,你也可以通过一个key来搜索你的记录,同样的你也可以通过key和value组合在一起来搜索记录。如果查询失败,则游标会返回OperationStatus.NOTFOUND。  

  

游标支持都检索方法如下:  

  

1) Cursor.getSearchKey()  

  

通过key的方式检索,使用后游标指针将移动到跟当前key匹配的第一项。  

  

2) Cursor.getSearchKeyRange()  

  

把游标移动到大于或等于查询的key的第一个匹配key,大小比较是通过你设置的比较器来完成的,如果没有设置则使用默认的比较器。  

  

3) Cursor.getSearchBoth()  

  

通过key和value方式检索,然后把游标指针移动到与查询匹配的第一项。  

  

4) Cursor.getSearchBothRange()  

  

把游标移动到所有的匹配key和大于或等于指定的data的第一项。  

  

比如说database存在如下的key/value记录,,大小比较是通过你设置的比较器来完成的,如果没有设置则使用默认的比较器。  

  

假设你的database存在如下的记录。  

  

               Alabama/Athens               Alabama/Florence               Alaska/Anchorage               Alaska/Fairbanks                Arizona/Avondale               Arizona/Florence然后查询  

  

查询的key  

  

查询的data  

  

游标指向  

  

Alaska  

  

Fa  

  

Alaska/Fairbanks  

  

Arizona  

  

Fl  

  

Arizona/Florence  

  

Alaska  

  

An  

  

Alaska/Anchorage  

  

使用示例:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.Cursor;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseEntry;  

  

import com.sleepycat.je.DatabaseException;  

  

import com.sleepycat.je.LockMode;  

  

import com.sleepycat.je.OperationStatus;  

  

...  

  

String searchKey = "Alaska";  

  

String searchData = "Fa";  

  

Cursor cursor = null;  

  

try {  

  

    ...  

  

    cursor = myDatabase.openCursor(null, null);  

  

    DatabaseEntry theKey =  

  

         new DatabaseEntry(searchKey.getBytes("UTF-8"));  

  

    DatabaseEntry theData =  

  

         new DatabaseEntry(searchData.getBytes("UTF-8"));  

  

    cursor = myDatabase.openCursor(null, null);  

  

OperationStatus retVal = cursor.getSearchBothRange(theKey,  

  

theData, LockMode.DEFAULT);  

  

    if (retVal == OperationStatus.NOTFOUND) {  

  

        System.out.println(searchKey + "/" + searchData +  

  

                           " not matched in database " +  

  

                           myDatabase.getDatabaseName());  

  

    } else {  

  

        String foundKey = new String(theKey.getData(), "UTF-8");  

  

        String foundData = new String(theData.getData(), "UTF-8");  

  

        System.out.println("Found record " + foundKey + "/" + foundData +  

  

                           "for search key/data: " + searchKey +  

  

                           "/" + searchData);  

  

    }  

  

} catch (Exception e) {  

  

    // Exception handling goes here  

  

} finally {  

  

   cursor.close();  

  

}  

  

l 使用游标来定位多重记录  

  

如果你的库支持多重记录,你可以使用游标来遍历一个key下的多个data.  

  

1) Cursor.getNext(), Cursor.getPrev()  

  

获取上一条记录或下一条记录  

  

2) Cursor.getSearchBothRange()  

  

用语定位到满足指定data的第一条记录。  

  

3) Cursor.getNextNoDup(), Cursor.getPrevNoDup()  

  

跳到上一个key的最后一个data或下一个key的第一个data,忽略 当前key多重记录的存在。  

  

4) Cursor.getNextDup(), Cursor.getPrevDup()  

  

在当前key中把指针移动到前一个data或后一个data.  

  

5) Cursor.count()  

  

获取当前key下的data总数。  

  

使用示例:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.Cursor;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseEntry;  

  

import com.sleepycat.je.DatabaseException;  

  

import com.sleepycat.je.LockMode;  

  

import com.sleepycat.je.OperationStatus;  

  

...  

  

Cursor cursor = null;  

  

try {  

  

    ...  

  

    // Create DatabaseEntry objects  

  

    // searchKey is some String.  

  

    DatabaseEntry theKey = new DatabaseEntry(searchKey.getBytes("UTF-8"));  

  

    DatabaseEntry theData = new DatabaseEntry();  

  

    cursor = myDatabase.openCursor(null, null);  

  

OperationStatus retVal = cursor.getSearchKey(theKey,  

  

theData, LockMode.DEFAULT);  

  

    // 如果count超过一个,则遍历  

  

    if (cursor.count() > 1) {  

  

        while (retVal == OperationStatus.SUCCESS) {  

  

            String keyString = new String(theKey.getData(), "UTF-8");  

  

            String dataString = new String(theData.getData(), "UTF-8");  

  

            System.out.println("Key | Data : " + keyString + " | " +  

  

                               dataString + "");  

  

            retVal = cursor.getNextDup(theKey, theData, LockMode.DEFAULT);  

  

        }  

  

    }  

  

} catch (Exception e) {  

  

    // Exception handling goes here  

  

} finally {  

  

   // Make sure to close the cursor  

  

   cursor.close();  

  

}  

  

l 通过游标来添加数据  

  

你可以通过游标来向database里添加数据  

  

你可以使用如下方法来向database里添加数据  

  

1) Cursor.put()  

  

如果database不存在key,则添加,如果database存在key但允许多重记录,则可以通过比较器在适当的位置插入数据,如果key已存在且不支持多重记录,则替换原有的数据。  

  

2) Cursor.putNoDupData()  

  

如果存在相同的key和data则返回OperationStatus.KEYEXIST.  

  

如果不存在key则添加数据。  

  

3) Cursor.putNoOverwrite()  

  

如果存在相同的key在database里则返OperationStatus.KEYEXIS,  

  

如果不存在key则添加数据。  

  

package je.gettingStarted;  

  

import com.sleepycat.je.Cursor;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseEntry;  

  

import com.sleepycat.je.OperationStatus;  

  

...  

  

String key1str = "My first string";  

  

String data1str = "My first data";  

  

String key2str = "My second string";  

  

String data2str = "My second data";  

  

String data3str = "My third data";  

  

Cursor cursor = null;  

  

try {  

  

    ...  

  

    DatabaseEntry key1 = new DatabaseEntry(key1str.getBytes("UTF-8"));  

  

    DatabaseEntry data1 = new DatabaseEntry(data1str.getBytes("UTF-8"));  

  

    DatabaseEntry key2 = new DatabaseEntry(key2str.getBytes("UTF-8"));  

  

    DatabaseEntry data2 = new DatabaseEntry(data2str.getBytes("UTF-8"));  

  

    DatabaseEntry data3 = new DatabaseEntry(data3str.getBytes("UTF-8"));  

  

    cursor = myDatabase.openCursor(null, null);  

  

OperationStatus retVal = cursor.put(key1, data1); // 添加成功  

  

    retVal = cursor.put(key2, data2); // 添加成功  

  

    retVal = cursor.put(key2, data3); // 如果允许多重记录则添加成功                                                                                      //否则添加失败  

  

} catch (Exception e) {  

  

    // Exception handling goes here  

  

} finally {  

  

   // Make sure to close the cursor  

  

   cursor.close();  

  

}  

  

l 使用游标来删除记录  

  

你可以通过调用Cursor.delete().方法来删除当前游标所指向的记录。删除后如果没有移动过指针这个时候调用Cursor.getCurrent()还是可以得到当前值的,但移动以后就不可以了。如果没有重设指针,对同一个位置多次调用删除方法,会返回OperationStatus.KEYEMPTY状态。  

  

使用示例:  

  

package je.gettingStarted;  

  

import com.sleepycat.je.Cursor;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseEntry;  

  

import com.sleepycat.je.LockMode;  

  

import com.sleepycat.je.OperationStatus;  

  

...  

  

Cursor cursor = null;  

  

try {  

  

    ...  

  

    DatabaseEntry theKey = new DatabaseEntry(searchKey.getBytes("UTF-8"));  

  

    DatabaseEntry theData = new DatabaseEntry();  

  

    cursor = myDatabase.openCursor(null, null);  

  

    OperationStatus retVal = cursor.getSearchKey(theKey, theData,                                        LockMode.DEFAULT);  

  

    //如果date不是多重记录.  

  

    if (cursor.count() == 1) {  

  

            System.out.println("Deleting " +  

  

                               new String(theKey.getData(), "UTF-8") +  

  

                               "|" +  

  

                               new String(theData.getData(), "UTF-8"));  

  

            cursor.delete();//删除当前记录  

  

    }  

  

} catch (Exception e) {  

  

    // Exception handling goes here  

  

} finally {  

  

   // Make sure to close the cursor  

  

   cursor.close();  

  

}  

  

l 修改当前游标所在位置的值  

  

可以通过Cursor.putCurrent()方法来修改,这个方法只有一个参数就是将要修改的值。这个方法不能用在多重记录。  

  

使用示例:  

  

import com.sleepycat.je.Cursor;  

  

import com.sleepycat.je.Database;  

  

import com.sleepycat.je.DatabaseEntry;  

  

import com.sleepycat.je.LockMode;  

  

import com.sleepycat.je.OperationStatus;  

  

...  

  

Cursor cursor = null;  

  

try {  

  

    ...  

  

    DatabaseEntry theKey = new DatabaseEntry(searchKey.getBytes("UTF-8"));  

  

    DatabaseEntry theData = new DatabaseEntry();  

  

    cursor = myDatabase.openCursor(null, null);  

  

    OperationStatus retVal = cursor.getSearchKey(theKey, theData,  

  

LockMode.DEFAULT);  

  

    //将要被替换的值  

  

    String replaceStr = "My replacement string";  

  

    DatabaseEntry replacementData =  

  

        new DatabaseEntry(replaceStr.getBytes("UTF-8"));  

  

    cursor.putCurrent(replacementData);//把当前位置用新值替换  

  

} catch (Exception e) {  

  

    // Exception handling goes here  

  

} finally {  

  

   // Make sure to close the cursor  

  

   cursor.close();  

  

}  



附录2

1.创建Manager。

public class Application extends android.app.Application {

    private Manager manager;

    private static Context mContext;

    

    ...

    

    @Override

    public void onCreate() {

        super.onCreate();

        mContext = getApplicationContext();

        try {

            /*

             * In Java the Manager instance and all the objects descending

             * from it may be used on any thread.

             */

            manager = new Manager(new AndroidContext(mContext), Manager.DEFAULT_OPTIONS);

        } catch (IOException e) {

            Log.e(TAG, "Cannot create Manager instance", e);

            return;

        }

    }

}

2.open a database.

try {

     Manager manager = new Manager(new AndroidContext(mContext), Manager.DEFAULT_OPTIONS);

     this.db = manager.getDatabase("my-database");

 } catch (IOException e) {

     Log.e(TAG, "Cannot create database", e);

     return;

 }

3.如果数据有做过改动,可以添加一个说明(database notification)

try {

     Manager manager = new Manager(new AndroidContext(mContext), Manager.DEFAULT_OPTIONS);

     

     Database db = manager.getExistingDatabase("my-database");

     

     if(db != null) {

         db.addChangeListener(new ChangeListener() {

             public void changed(ChangeEvent event) {

                 //

                 // Process the notification here

                 //

             }

         });

     }

 

 } catch (IOException e) {

     Log.e(TAG, "Cannot delete database", e);

     return;

 }

4.删除database。

try {

     myDatabase.delete();

} catch (IOException e) {

     Log.e(TAG, "Cannot delete database", e);

     return;

}

5.创建document。

Map<String, Object> properties = new HashMap<String, Object>();

properties.put("type", "list");

properties.put("title", title);

properties.put("created_at", currentTimeString);

properties.put("owner", "profile:" + userId);

properties.put("members", new

ArrayList<String>());

Document document = database.createDocument();

document.putProperties(properties); 

6.读取document。

Document doc = database.getDocument(myDocId);

// We can directly access properties from the document object:

doc.getProperty("title");

// Or go through its properties dictionary:

Map<String, Object> properties = doc.getProperties();

String owner = (String) properties.get("owner");

7.更新document。

Document doc = database.getDocument(myDocId);

doc.update(new Document.DocumentUpdater() {

    @Override

    public boolean update(UnsavedRevision newRevision) {

        Map<String, Object> properties = newRevision.getUserProperties();

        properties.put("title", title);

        properties.put("notes", notes);

        newRevision.setUserProperties(properties);

        return true;

    }

})

8.删除document。

Document task = (Document) database.getDocument("task1");

task.delete(); 





附录3

public class DBHelper extends SQLiteOpenHelper{

  private static final String DB_NAME="coll.db";

  private static final String TBL_NAME="CollTbl";

  private staic final String CREATE_TBL="create table"+"CollTbl(_id integer primary key autoincrement,name text,url text,desc text)";

  private SQLiteDatabase db;

  

  DBHelper(Context c){

   super(c,DB_NAME,null,2);

  }


 @Override

public void onCreate(SQLiteDatabase db) {

// TODO Auto-generated method stub

db.execSQL(CREATE_TBL);

}


  @Override

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

// TODO Auto-generated method stub

}

public insert(ContentValues values){

SQLiteDatabase db=getWritableDatabase();

db.insert(TBL_NAME,null,values);

db.close();

}

public Cursor query(){

 SQLiteDatabase db=getWritableDatabase();

 Cursor c=db.query(TBL_NAME,null,null,null,null,null,null);

}

public void del(int id){

 if(db==null){

  db=getWritableDatabase();

  db.delete(TBL_NAME,"_id=?",new String[]{String.valueOf(id)});

 }

}

public void close(){

if(db!=null){

  sb.close();

}

}


}


附录4

1.打开关闭database

Options options = new Options();

options.createIfMissing(true);

DB db = factory.open(new File("example"), options);

try {

  // Use the db in here....

} finally {

  // Make sure you close the db to shutdown the 

  // database and avoid resource leaks.

  db.close();

}

2.添加、获取、删除key/values.

  db.put(bytes("Tampa"), bytes("rocks"));

  String value = asString(db.get(bytes("Tampa")));

  db.delete(bytes("Tampa"));

3.执行批量更新

WriteBatch batch = db.createWriteBatch();

try {

  batch.delete(bytes("Denver"));

  batch.put(bytes("Tampa"), bytes("green"));

  batch.put(bytes("London"), bytes("red"));


  db.write(batch);

} finally {

  // Make sure you close the batch to avoid resource leaks.

  batch.close();

}

4.遍历key/value


DBIterator iterator = db.iterator();

try {

  for(iterator.seekToFirst(); iterator.hasNext(); iterator.next()) {

    String key = asString(iterator.peekNext().getKey());

    String value = asString(iterator.peekNext().getValue());

    System.out.println(key+" = "+value);

  }

} finally {

  // Make sure you close the iterator to avoid resource leaks.

  iterator.close();

}

5.自定义key值大小比较

DBComparator comparator = new DBComparator(){

    public int compare(byte[] key1, byte[] key2) {

        return new String(key1).compareTo(new String(key2));

    }

    public String name() {

        return "simple";

    }

    public byte[] findShortestSeparator(byte[] start, byte[] limit) {

        return start;

    }

    public byte[] findShortSuccessor(byte[] key) {

        return key;

    }

};

Options options = new Options();

options.comparator(comparator);

DB db = factory.open(new File("example"), options);




  

  


 



你可能感兴趣的:(数据库,服务器,Objects,应用程序,掌上电脑)