转自:http://blog.csdn.net/ylf13/article/details/15337957
有几个注意的,在BDB数据库里,默认是不能有重复的两个相同的键,当然可以通过config配置sortedDupli...来设置可以,所以在读取数据库值的时候必须考虑两种情况,是否存在相同的键的记录
JE provides two basic mechanisms for the storage and retrieval of database key/data pairs:
-
TheDatabase.put()
andDatabase.get()
methods provide the easiest access for all non-duplicate records in the database. These methods are described in this section.
-
Cursors provide several methods for putting and getting database records. Cursors and their database access methods are described inUsing
Cursors.
看完上段OK,如果是设置non-duplicate,那就直接用db.get() db.put()来操作记录。否则就得用Cursor了
delete函数:如果记录是支持duplicate,则删除所有满足的key的记录,如果想删除某一条,还是得用cursor
上篇我们简单的打开了数据库和进行简单的存储
这个对于我们存储数据的基本类型还行,但是涉及到用户自定义类的时候,单靠之前的转换函数来从string转换程对象是不妨便的,我们来看看BDB为我们准备来什么?
引自使用手册:
DatabaseEntry
can hold any kind of data from simple Java primitive types to complex Java objects so long as that data can be represented as a Javabyte
array.
Note that due to performance considerations,you should not use Java serialization to convert a Java object to abyte
array. Instead,
use the Bind APIs to perform this conversion(seeUsing
the BIND APIsfor more information).
看到加粗这段了把,官方推荐我们用Bind
(一)Bind技术
(1)SeriaBinding
先说下序列化的绑定技术,言外之意,我们的数据类型就必须实现Serializable才能进行下面的绑定
Serializing Objects
To store a serializable complex object using the Bind APIs:
-
Implement java.io.Serializable in the class whose instances that you want to store.
-
Open (create) your databases. You need two. The first is the database that you use to store your data. The second is used to store the class information.
-
Instantiate a class catalog. You do this withcom.sleepycat.bind.serial.StoredClassCatalog
, and at that time you must provide a handle to an open database that is used to store the class information.
-
Create an entry binding that usescom.sleepycat.bind.serial.SerialBinding
.
-
Instantiate an instance of the object that you want to store, and place it in aDatabaseEntry
using the entry binding that you created in the previous step.
其实绑定技术就是用了反射。
没看源码,也没什么好展开的,大家就把方法记着吧,以后再一步步来
由于需要用到Class这个类,所以构造函数多了一个value的Class
这样就可以使得我们自己数据完整的存入了
-
importjava.io.File;
-
importjava.io.Serializable;
-
importjava.io.UnsupportedEncodingException;
-
-
importcom.sleepycat.bind.EntryBinding;
-
importcom.sleepycat.bind.serial.SerialBinding;
-
importcom.sleepycat.bind.serial.StoredClassCatalog;
-
importcom.sleepycat.bind.serial.TupleSerialBinding;
-
importcom.sleepycat.bind.tuple.TupleBase;
-
importcom.sleepycat.bind.tuple.TupleBinding;
-
importcom.sleepycat.bind.tuple.TupleTupleBinding;
-
importcom.sleepycat.je.Database;
-
importcom.sleepycat.je.DatabaseConfig;
-
importcom.sleepycat.je.DatabaseEntry;
-
importcom.sleepycat.je.Environment;
-
importcom.sleepycat.je.EnvironmentConfig;
-
importcom.sleepycat.je.LockMode;
-
importcom.sleepycat.je.OperationStatus;
-
-
-
publicclassMain{
-
-
-
-
-
staticEnvironmentenv=null;
-
-
publicstaticvoidmain(String[]args){
-
BDBUtil<Integer,Student>bDB=newBDBUtil<Integer,Student>("testDB",Student.class);
-
Students1=newStudent(1,"ylf");
-
Students2=newStudent(2,"dsb");
-
Students3=newStudent(3,"dbc");
-
-
bDB.put(1,s1);
-
bDB.put(2,s2);
-
bDB.put(3,s3);
-
-
Students=bDB.get(3);
-
System.out.println("mynameis"+s.getName()+"nois"+s.getNo());
-
-
System.out.println(bDB.size());
-
bDB.close();
-
}
-
-
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
classBDBUtil<K,V>{
-
privateEnvironmentenv=null;
-
privateEnvironmentConfigenvCfig=null;
-
privateDatabasedb=null;
-
privateDatabaseConfigdbCfig=null;
-
-
privateDatabaseclassDB=null;
-
privateStoredClassCatalogclassCatalog=null;
-
privateEntryBindingvalueBinding=null;
-
-
privateFilefile=null;
-
-
publicBDBUtil(StringdbName,ClassvalueClass){
-
envCfig=newEnvironmentConfig();
-
envCfig.setAllowCreate(true);
-
file=newFile("./test/");
-
env=newEnvironment(file,envCfig);
-
dbCfig=newDatabaseConfig();
-
dbCfig.setAllowCreate(true);
-
db=env.openDatabase(null,dbName,dbCfig);
-
-
-
classDB=env.openDatabase(null,"classDB",dbCfig);
-
-
classCatalog=newStoredClassCatalog(classDB);
-
-
valueBinding=newSerialBinding(classCatalog,valueClass);
-
}
-
-
publicbooleanput(Kkey,Vvalue){
-
DatabaseEntrykeyEntry=newDatabaseEntry(key.toString().getBytes());
-
DatabaseEntryvalueEntry=newDatabaseEntry();
-
valueBinding.objectToEntry(value,valueEntry);
-
-
db.put(null,keyEntry,valueEntry);
-
returntrue;
-
}
-
-
publicVget(Kkey){
-
DatabaseEntrykeyEntry;
-
Vvalue=null;
-
try{
-
keyEntry=newDatabaseEntry(key.toString().getBytes("gb2312"));
-
DatabaseEntryvalueEntry=newDatabaseEntry();
-
if(db.get(null,keyEntry,valueEntry,LockMode.DEFAULT)==OperationStatus.SUCCESS){
-
value=(V)valueBinding.entryToObject(valueEntry);
-
returnvalue;
-
}
-
}catch(UnsupportedEncodingExceptione){
-
e.printStackTrace();
-
}
-
returnvalue;
-
-
}
-
-
publicbooleandel(KkeyStr){
-
DatabaseEntrykey;
-
try{
-
key=newDatabaseEntry(keyStr.toString().getBytes("gb2312"));
-
if(OperationStatus.SUCCESS==db.delete(null,key))
-
returntrue;
-
}catch(UnsupportedEncodingExceptione){
-
e.printStackTrace();
-
}
-
returnfalse;
-
}
-
-
publiclongsize(){
-
returndb.count();
-
}
-
-
publicvoidclose(){
-
db.close();
-
classDB.close();
-
env.cleanLog();
-
env.close();
-
}
-
}
-
-
-
-
-
-
-
-
classStudentimplementsSerializable{
-
-
-
-
privatestaticfinallongserialVersionUID=7333239714054069867L;
-
privateStringname;
-
privateintno;
-
-
publicStudent(){
-
}
-
publicStudent(intno,Stringname){
-
this.no=no;
-
this.name=name;
-
}
-
publicStringgetName(){
-
returnname;
-
}
-
publicvoidsetName(Stringname){
-
this.name=name;
-
}
-
publicintgetNo(){
-
returnno;
-
}
-
publicvoidsetNo(intno){
-
this.no=no;
-
}
-
@Override
-
publicStringtoString(){
-
return"Student"+no+":"+name;
-
}
-
-
publicvoidfromString(Stringstr){
-
inti=str.indexOf(':');
-
StringnoStr=str.substring(7,i);
-
this.no=Integer.parseInt(noStr);
-
this.name=str.substring(i+1);
-
}
-
-
}
(2)自定义绑定
官方还推荐使用custom tuple binding
就是我们实现TupleBinding,实现里面的objectToEntry() EntryToObject()
这里就不需要维护第二个数据库了,有木有又回到远点的赶脚!!
还不如上一篇里直接在类里实现转换
只不过官方推荐的这种是用字节流来存储,省流量,我们类里也可以利用ArrayByteInputStream好像是这个。。。我忘了,就字节流来实现就好了
(二)游标cursor
游标操作类似数据库的游标。
这里通过getNext() getPrev()来实现遍历
同时,cursor还提供了查找和插入数据的功能,我这里就不再一一写出来了,具体用到的时候在设计吧,现在全部封装一遍也不见得很好。。
-
interfaceBDBIterator{
-
publicObjectcurrentValue();
-
publicObjectcurrentKey();
-
publicbooleanhasNext();
-
publicbooleanhasPrev();
-
publicvoidclose();
-
}
这里迭代器实现的是BDBUtil的内部类,迭代器的实现大家可以参考Java的迭代器实现方法。
-
publicBDBIteratorgetIterator(){
-
IteratorImplit=newIteratorImpl();
-
returnit;
-
}
-
-
-
-
-
-
-
-
-
-
-
-
classIteratorImplimplementsBDBIterator{
-
KcurrentKey=null;
-
VcurrentValue=null;
-
DatabaseEntrykeyEntry=null;
-
DatabaseEntryvalueEntry=null;
-
-
publicIteratorImpl(){
-
if(cursor!=null){
-
cursor.close();
-
cursor=null;
-
}
-
cursor=db.openCursor(null,null);
-
}
-
-
@Override
-
publicvoidclose(){
-
cursor.close();
-
cursor=null;
-
}
-
@Override
-
publicObjectcurrentKey(){
-
returncurrentKey;
-
}
-
@Override
-
publicObjectcurrentValue(){
-
returncurrentValue;
-
}
-
-
@Override
-
publicbooleanhasNext(){
-
keyEntry=newDatabaseEntry();
-
valueEntry=newDatabaseEntry();
-
cursor.getNext(keyEntry,valueEntry,LockMode.DEFAULT);
-
returnhas();
-
}
-
@Override
-
publicbooleanhasPrev(){
-
keyEntry=newDatabaseEntry();
-
valueEntry=newDatabaseEntry();
-
cursor.getPrev(keyEntry,valueEntry,LockMode.DEFAULT);
-
returnhas();
-
}
-
-
publicbooleanhas(){
-
if(keyEntry.getData()==null)
-
returnfalse;
-
try{
-
currentKey=(K)newString(keyEntry.getData(),"gb2312");
-
currentValue=(V)valueBinding.entryToObject(valueEntry);
-
if(currentValue!=null)
-
returntrue;
-
}catch(UnsupportedEncodingExceptione){
-
e.printStackTrace();
-
}
-
returnfalse;
-
}
-
-
}
调用方式如下:主要还是这个Iterator迭代器的实现遍历看下吧
-
publicstaticvoidmain(String[]args){
-
BDBUtil<Integer,Student>bDB=newBDBUtil<Integer,Student>("testDB",Student.class);
-
Students1=newStudent(1,"ylf");
-
Students2=newStudent(2,"dsb");
-
Students3=newStudent(3,"dbc");
-
-
bDB.put(1,s1);
-
bDB.put(2,s2);
-
bDB.put(3,s3);
-
-
BDBIteratorit=bDB.getIterator();
-
Students=null;
-
intno=0;
-
while(it.hasNext()){
-
-
s=(Student)it.currentValue();
-
no=Integer.parseInt((String)it.currentKey());
-
System.out.println("mynameis"+s.getName()+"nois"+s.getNo()+""+no);
-
}
-
while(it.hasPrev()){
-
-
s=(Student)it.currentValue();
-
no=Integer.parseInt((String)it.currentKey());
-
System.out.println("mynameis"+s.getName()+"nois"+s.getNo()+""+no);
-
}
-
it.close();
-
BDBIteratorit2=bDB.getIterator();
-
while(it2.hasNext()){
-
-
s=(Student)it2.currentValue();
-
no=Integer.parseInt((String)it2.currentKey());
-
System.out.println("mynameis"+s.getName()+"nois"+s.getNo()+""+no);
-
}
-
it2.close();
-
-
System.out.println(bDB.size());
-
-
s=bDB.find(2);
-
System.out.println("findmynameis"+s.getName());
-
-
bDB.close();
-
}
分享到:
相关推荐
Berkeley DB JE-7.0.6 jar包
BerkeleyDB-Core-C-GSG.pdf bdb c开发手册 英文版
(二) Berkeley DB -- Access Method Configuration_iyangjian2005997_新浪博客.mht
db-6.1.26.tar.gz berkeley db
berkeley db je-6.4.9.gz
Java-Edition-BerkeleyDB-3.1.0,国外的开源数据库,供大家参考
Berkeley DB -- 入门知识和一个小例子_iyangjian2005997_新浪博客.mht
使用BerkeleyDB数据库,java语言开发需要的jar包资源,7.5.11版本
Oracle BerkeleyDB-JE je-6.0.11
Berkeley DB(BDB)是一个高效的嵌入式数据库编程库,C语言、C++、Java、Perl、Python、Tcl以及其他很多语言都有其对应的API。Berkeley DB可以保存任意类型的键/值对(Key/Value Pair),而且可以为一个键保存多个...
关于berkeley db 4.6.2的介绍性文章,是了解berkeley db的技术文档。
building-ha-scalable-applications-with-berkeley-db-whitepaper
berkeley-db- performace test specification white paper .pdf
介绍DB API的设置与使用的快速入门手册,目标是提供一个快速有效地机制,能让你进入Berkeley DB研发的世界。在本文中侧重于C++语言的研发人员,以及研究进城内数据管理解决方案的资深架构师。
游标支持 ">Berkeley DB Java Edition JE 是一个完全用JAVA写的 它适合于管理海量的 简单的数据 能够高效率的处理1到1百万条记录 制约JE数据库的往往是硬件系统 而不是JE本身 多线程支持 JE使用超时的方式来处理...
有关嵌入式数据库berkeley db的参考资料
文件类型的DB,存取速度快,操作方便,是以map方式key-value方式存取数据.兄弟大家共享!
BerkeleyDB和Sqlite是当前最流行的嵌入式开源数据库。
Berkeley DB Java Edition (JE)是一个完全用JAVA写的,它适合于管理海量的,简单的数据。 能够高效率的处理1到1百万条记录,制约JE数据库的往往是硬件系统,而不是JE本身。 多线程支持,JE使用超时的方式来处理...
Oracle Berkeley DB Java 版是一个开源的、可嵌入的事务存储引擎,是完全用 Java 编写的。与 Oracle Berkeley DB 类似,Oracle Berkeley DB Java 版在应用程序的地址空间中执行,没有客户端/服务器通信的开销,从而...