`
cloudeagle
  • 浏览: 112600 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论

java之BerkeleyDB(二)--绑定(Binding)技术、游标(Cursor)

 
阅读更多

转自: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了

  • Database.put()

  • Database.putNoOverwrite()

  • Database.putNoDupData()

  • Database.get() 这个利用key来找

  • Database.getSearchBoth() 这个利用Key和value共同找记录

delete函数:如果记录是支持duplicate,则删除所有满足的key的记录,如果想删除某一条,还是得用cursor


上篇我们简单的打开了数据库和进行简单的存储

这个对于我们存储数据的基本类型还行,但是涉及到用户自定义类的时候,单靠之前的转换函数来从string转换程对象是不妨便的,我们来看看BDB为我们准备来什么?

引自使用手册:

DatabaseEntrycan hold any kind of data from simple Java primitive types to complex Java objects so long as that data can be represented as a Javabytearray. Note that due to performance considerations,you should not use Java serialization to convert a Java object to abytearray. 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:

  1. Implement java.io.Serializable in the class whose instances that you want to store.

  2. 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.

  3. 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.

  4. Create an entry binding that usescom.sleepycat.bind.serial.SerialBinding.

  5. Instantiate an instance of the object that you want to store, and place it in aDatabaseEntryusing the entry binding that you created in the previous step.

其实绑定技术就是用了反射。

没看源码,也没什么好展开的,大家就把方法记着吧,以后再一步步来

由于需要用到Class这个类,所以构造函数多了一个value的Class

这样就可以使得我们自己数据完整的存入了


  1. importjava.io.File;
  2. importjava.io.Serializable;
  3. importjava.io.UnsupportedEncodingException;
  4. importcom.sleepycat.bind.EntryBinding;
  5. importcom.sleepycat.bind.serial.SerialBinding;
  6. importcom.sleepycat.bind.serial.StoredClassCatalog;
  7. importcom.sleepycat.bind.serial.TupleSerialBinding;
  8. importcom.sleepycat.bind.tuple.TupleBase;
  9. importcom.sleepycat.bind.tuple.TupleBinding;
  10. importcom.sleepycat.bind.tuple.TupleTupleBinding;
  11. importcom.sleepycat.je.Database;
  12. importcom.sleepycat.je.DatabaseConfig;
  13. importcom.sleepycat.je.DatabaseEntry;
  14. importcom.sleepycat.je.Environment;
  15. importcom.sleepycat.je.EnvironmentConfig;
  16. importcom.sleepycat.je.LockMode;
  17. importcom.sleepycat.je.OperationStatus;
  18. publicclassMain{
  19. /**
  20. *@paramargs
  21. */
  22. staticEnvironmentenv=null;
  23. publicstaticvoidmain(String[]args){
  24. BDBUtil<Integer,Student>bDB=newBDBUtil<Integer,Student>("testDB",Student.class);
  25. Students1=newStudent(1,"ylf");
  26. Students2=newStudent(2,"dsb");
  27. Students3=newStudent(3,"dbc");
  28. bDB.put(1,s1);
  29. bDB.put(2,s2);
  30. bDB.put(3,s3);
  31. Students=bDB.get(3);
  32. System.out.println("mynameis"+s.getName()+"nois"+s.getNo());
  33. System.out.println(bDB.size());
  34. bDB.close();
  35. }
  36. }
  37. /**
  38. *我们的BDB工具
  39. *目前对外提供添加数据和取得数据,删除数据3个接口
  40. *类似HashMap的使用方法
  41. *注意:
  42. *这里的K和V两个类都必须实现来Serializable
  43. *而且也实现来toString
  44. *使用结束记得调用close()
  45. *@authorylf
  46. *
  47. *版本2:
  48. *采用动态的数据类型绑定,不是利用我们的toString()来转换对象和Entry
  49. *用到EntryBinding和StoredClassCatalog
  50. *以及binding.OnjectToEntry()EntryToObject()
  51. *
  52. */
  53. classBDBUtil<K,V>{
  54. privateEnvironmentenv=null;
  55. privateEnvironmentConfigenvCfig=null;
  56. privateDatabasedb=null;
  57. privateDatabaseConfigdbCfig=null;
  58. privateDatabaseclassDB=null;
  59. privateStoredClassCatalogclassCatalog=null;
  60. privateEntryBindingvalueBinding=null;
  61. privateFilefile=null;
  62. publicBDBUtil(StringdbName,ClassvalueClass){
  63. envCfig=newEnvironmentConfig();
  64. envCfig.setAllowCreate(true);
  65. file=newFile("./test/");
  66. env=newEnvironment(file,envCfig);
  67. dbCfig=newDatabaseConfig();
  68. dbCfig.setAllowCreate(true);
  69. db=env.openDatabase(null,dbName,dbCfig);
  70. //首先创建一个我们类的数据库
  71. classDB=env.openDatabase(null,"classDB",dbCfig);
  72. //实例化一个Catalog
  73. classCatalog=newStoredClassCatalog(classDB);
  74. //实例化一个binding来转换
  75. valueBinding=newSerialBinding(classCatalog,valueClass);
  76. }
  77. publicbooleanput(Kkey,Vvalue){
  78. DatabaseEntrykeyEntry=newDatabaseEntry(key.toString().getBytes());
  79. DatabaseEntryvalueEntry=newDatabaseEntry();
  80. valueBinding.objectToEntry(value,valueEntry);
  81. db.put(null,keyEntry,valueEntry);
  82. returntrue;
  83. }
  84. publicVget(Kkey){
  85. DatabaseEntrykeyEntry;
  86. Vvalue=null;
  87. try{
  88. keyEntry=newDatabaseEntry(key.toString().getBytes("gb2312"));
  89. DatabaseEntryvalueEntry=newDatabaseEntry();
  90. if(db.get(null,keyEntry,valueEntry,LockMode.DEFAULT)==OperationStatus.SUCCESS){
  91. value=(V)valueBinding.entryToObject(valueEntry);
  92. returnvalue;
  93. }
  94. }catch(UnsupportedEncodingExceptione){
  95. e.printStackTrace();
  96. }
  97. returnvalue;
  98. }
  99. publicbooleandel(KkeyStr){
  100. DatabaseEntrykey;
  101. try{
  102. key=newDatabaseEntry(keyStr.toString().getBytes("gb2312"));
  103. if(OperationStatus.SUCCESS==db.delete(null,key))
  104. returntrue;
  105. }catch(UnsupportedEncodingExceptione){
  106. e.printStackTrace();
  107. }
  108. returnfalse;
  109. }
  110. publiclongsize(){
  111. returndb.count();
  112. }
  113. publicvoidclose(){
  114. db.close();
  115. classDB.close();
  116. env.cleanLog();
  117. env.close();
  118. }
  119. }
  120. /**
  121. *序列化了的类
  122. *实现toString()
  123. *@authorylf
  124. *
  125. */
  126. classStudentimplementsSerializable{
  127. /**
  128. *
  129. */
  130. privatestaticfinallongserialVersionUID=7333239714054069867L;
  131. privateStringname;
  132. privateintno;
  133. publicStudent(){
  134. }
  135. publicStudent(intno,Stringname){
  136. this.no=no;
  137. this.name=name;
  138. }
  139. publicStringgetName(){
  140. returnname;
  141. }
  142. publicvoidsetName(Stringname){
  143. this.name=name;
  144. }
  145. publicintgetNo(){
  146. returnno;
  147. }
  148. publicvoidsetNo(intno){
  149. this.no=no;
  150. }
  151. @Override
  152. publicStringtoString(){
  153. return"Student"+no+":"+name;
  154. }
  155. publicvoidfromString(Stringstr){
  156. inti=str.indexOf(':');
  157. StringnoStr=str.substring(7,i);
  158. this.no=Integer.parseInt(noStr);
  159. this.name=str.substring(i+1);
  160. }
  161. }


  1. mynameisdbcnois3
  2. 3


(2)自定义绑定

官方还推荐使用custom tuple binding

就是我们实现TupleBinding,实现里面的objectToEntry() EntryToObject()

这里就不需要维护第二个数据库了,有木有又回到远点的赶脚!!

还不如上一篇里直接在类里实现转换

只不过官方推荐的这种是用字节流来存储,省流量,我们类里也可以利用ArrayByteInputStream好像是这个。。。我忘了,就字节流来实现就好了


(二)游标cursor

游标操作类似数据库的游标。

这里通过getNext() getPrev()来实现遍历

同时,cursor还提供了查找和插入数据的功能,我这里就不再一一写出来了,具体用到的时候在设计吧,现在全部封装一遍也不见得很好。。


  1. interfaceBDBIterator{
  2. publicObjectcurrentValue();
  3. publicObjectcurrentKey();
  4. publicbooleanhasNext();
  5. publicbooleanhasPrev();
  6. publicvoidclose();
  7. }


这里迭代器实现的是BDBUtil的内部类,迭代器的实现大家可以参考Java的迭代器实现方法。

  1. publicBDBIteratorgetIterator(){
  2. IteratorImplit=newIteratorImpl();
  3. returnit;
  4. }
  5. /**
  6. *这个内部类模拟iterator遍历器
  7. *@authorylf
  8. *迭代器使用方法
  9. *首先利用BDBUtil获得迭代器
  10. *hasNext()如果下一个元素存在,游标下移动,值通过currentKeycurrentValue获取
  11. *hasPrev()向前移动
  12. *最后记得close()虽然我这里已经通过null来保证自动close()但不是线程安全的
  13. *
  14. */
  15. classIteratorImplimplementsBDBIterator{
  16. KcurrentKey=null;
  17. VcurrentValue=null;
  18. DatabaseEntrykeyEntry=null;
  19. DatabaseEntryvalueEntry=null;
  20. publicIteratorImpl(){
  21. if(cursor!=null){
  22. cursor.close();
  23. cursor=null;
  24. }
  25. cursor=db.openCursor(null,null);//这里不配值CursorConfig了
  26. }
  27. @Override
  28. publicvoidclose(){
  29. cursor.close();
  30. cursor=null;
  31. }
  32. @Override
  33. publicObjectcurrentKey(){
  34. returncurrentKey;
  35. }
  36. @Override
  37. publicObjectcurrentValue(){
  38. returncurrentValue;
  39. }
  40. @Override
  41. publicbooleanhasNext(){
  42. keyEntry=newDatabaseEntry();
  43. valueEntry=newDatabaseEntry();
  44. cursor.getNext(keyEntry,valueEntry,LockMode.DEFAULT);
  45. returnhas();
  46. }
  47. @Override
  48. publicbooleanhasPrev(){
  49. keyEntry=newDatabaseEntry();
  50. valueEntry=newDatabaseEntry();
  51. cursor.getPrev(keyEntry,valueEntry,LockMode.DEFAULT);
  52. returnhas();
  53. }
  54. publicbooleanhas(){
  55. if(keyEntry.getData()==null)
  56. returnfalse;
  57. try{
  58. currentKey=(K)newString(keyEntry.getData(),"gb2312");
  59. currentValue=(V)valueBinding.entryToObject(valueEntry);
  60. if(currentValue!=null)
  61. returntrue;
  62. }catch(UnsupportedEncodingExceptione){
  63. e.printStackTrace();
  64. }
  65. returnfalse;
  66. }
  67. }


调用方式如下:主要还是这个Iterator迭代器的实现遍历看下吧

  1. publicstaticvoidmain(String[]args){
  2. BDBUtil<Integer,Student>bDB=newBDBUtil<Integer,Student>("testDB",Student.class);
  3. Students1=newStudent(1,"ylf");
  4. Students2=newStudent(2,"dsb");
  5. Students3=newStudent(3,"dbc");
  6. bDB.put(1,s1);
  7. bDB.put(2,s2);
  8. bDB.put(3,s3);
  9. BDBIteratorit=bDB.getIterator();
  10. Students=null;
  11. intno=0;
  12. while(it.hasNext()){
  13. s=(Student)it.currentValue();
  14. no=Integer.parseInt((String)it.currentKey());
  15. System.out.println("mynameis"+s.getName()+"nois"+s.getNo()+""+no);
  16. }
  17. while(it.hasPrev()){
  18. s=(Student)it.currentValue();
  19. no=Integer.parseInt((String)it.currentKey());
  20. System.out.println("mynameis"+s.getName()+"nois"+s.getNo()+""+no);
  21. }
  22. it.close();
  23. BDBIteratorit2=bDB.getIterator();
  24. while(it2.hasNext()){
  25. s=(Student)it2.currentValue();
  26. no=Integer.parseInt((String)it2.currentKey());
  27. System.out.println("mynameis"+s.getName()+"nois"+s.getNo()+""+no);
  28. }
  29. it2.close();
  30. System.out.println(bDB.size());
  31. s=bDB.find(2);
  32. System.out.println("findmynameis"+s.getName());
  33. bDB.close();
  34. }

分享到:
评论

相关推荐

    BerkeleyDB-Core-JAVA-GSG.pdf

    ### Berkeley DB for Java:概述与入门指南 #### 一、Berkeley DB简介 Berkeley DB (BDB) 是一个高性能的嵌入式数据库系统,它以其高效的数据存储和检索能力而闻名。根据提供的文档信息,“BerkeleyDB-Core-JAVA-...

    Berkeley DB JE-7.0.6

    Berkeley DB JE(Java Edition)是Oracle公司提供的一款开源、嵌入式、基于Java的键值对数据库系统。它以其轻量级、高性能和高可用性而受到广泛的青睐,尤其适合于需要在内存中管理大量数据的应用场景。在版本7.0.6...

    BerkeleyDB-Core-C-GSG.pdf

    通过本手册的学习,开发者可以掌握 Berkeley DB 的核心概念和技术细节,包括数据库管理、记录操作、游标使用和二级数据库等。这些知识将有助于开发者构建高性能、可靠的数据存储解决方案。Berkeley DB 的灵活性和...

    BerkeleyDB_java_jar包

    标题中的"BerkeleyDB_java_jar包"指的是适用于Java开发的BerkeleyDB库的jar文件,这个jar包包含了运行和开发BerkeleyDB Java应用所需的类和方法。 描述中提到的"7.5.11版本"是BerkeleyDB的一个特定发行版,每个版本...

    Berkeley DB -- Access Method Configuration_iyangjian200599

    (二) Berkeley DB -- Access Method Configuration_iyangjian2005997_新浪博客.mht

    Java-Edition-BerkeleyDB-3.1.0.zip_BerkeleyDB

    **Java版BerkeleyDB 3.1.0详解** BerkeleyDB是一款由Oracle公司开发的开源、嵌入式数据库系统,特别适用于Java开发者。在Java-Edition-BerkeleyDB-3.1.0版本中,它提供了高效、可靠的数据存储解决方案,尤其适合于...

    berkeley db db-6.1.26.tar.gz

    db-6.1.26.tar.gz berkeley db

    Berkeley DB -- 入门知识和一个小例子_iyangjian2005997_新浪博客.mht

    Berkeley DB -- 入门知识和一个小例子_iyangjian2005997_新浪博客.mht

    Berkeley DB4.8以上各版本

    Berkeley DB是一款由Oracle公司开发的嵌入式数据库系统,被广泛应用于许多软件项目中,尤其是在需要快速、轻量级数据存储解决方案的场景下。它提供了键值对存储模式,适用于构建高性能的数据缓存和数据库应用程序。...

    Berkeley DB C++编程入门教

    Berkeley DB是一个由Oracle公司开发的开源嵌入式数据库系统,支持多种编程语言接口,其中C++是其中之一。它为开发者提供了一个轻量级的数据库解决方案,适用于多种应用程序。Berkeley DB允许开发者在应用程序中直接...

    berkeley db je-6.4.9.gz

    在这个“berkeley db je-6.4.9.gz”压缩包中,包含了BDB Java Edition(JE)的6.4.9版本。这个版本的发布可能包含了性能优化、新功能、bug修复以及对先前版本的改进。下面将详细探讨BDB JE的相关知识点。 1. **键值...

    db-4.7.25-master_db-4.7.25-master_berkeleydbvxworks_BerkeleyDB_源

    Berkeley DB是一个开源的文件数据库,介于关系数据库与内存数据库之间,使用方式与内存数据库类似,它提供的是一系列直接访问数据库的函数,而不是像关系数据库那样需要网络通讯、SQL解析等步骤,本文件是早期版本

    Berkeley DB参考手册PDF版本

    - **定义与作用**:游标是Berkeley DB提供的一种高效访问数据库记录的方式,通过游标可以实现对数据库中记录的查找、修改和删除等操作。 - **应用场景**:适用于需要频繁读写数据库的应用场景。 #### 1.2 Getting ...

    BerkeleyDB-Core-Cxx-GSG.rar_Berkeley DB_berkeley Db cxx

    《Berkeley DB核心技术指南——C++接口篇》 Berkeley DB(简称BDB)是由Oracle公司开发的一款开源、轻量级、嵌入式数据库系统,主要用于处理键值对存储问题。它广泛应用于需要快速访问数据的环境,如网络服务器、...

    Berkeley DB参考资料

    - **定义与作用**:在Berkeley DB中,游标(Cursor)是用于导航和操作数据库记录的一种机制。通过游标,用户可以按需检索、修改或删除记录。 - **应用场景**:适用于需要对数据库进行复杂查询或遍历的场景,如数据...

    BerkeleyDB-JE je-6.0.11

    Oracle BerkeleyDB-JE je-6.0.11

    java berkeley-db demo

    Berkeley DB(BDB)是一个高效的嵌入式数据库编程库,C语言、C++、Java、Perl、Python、Tcl以及其他很多语言都有其对应的API。Berkeley DB可以保存任意类型的键/值对(Key/Value Pair),而且可以为一个键保存多个...

    BerkeleyDB-Core-Cxx-GSG.rar

    **Berkeley DB (BDB)** 是一款开源的、嵌入式数据库系统,由Oracle公司提供。它被广泛用于需要高效本地存储和简单数据管理的软件应用程序中,特别是在那些对性能和可靠性有高要求的场景。BDB的核心特性包括事务处理...

    berkeley-db-v-relational-066565

    ### Berkeley DB与关系型数据库管理系统的对比分析 #### 引言 Oracle公司以其业界领先的数据库引擎——Oracle Database闻名于世。Oracle Database是一款极其可靠、高度可扩展的客户端-服务器关系型数据库管理系统...

Global site tag (gtag.js) - Google Analytics