linugb118--java space

          Java

          Object DataBase --DB4O之旅

          Object DataBase --DB4O之旅

          Object DataBase 出現(xiàn)有段時(shí)間了,最近對(duì)此有點(diǎn)興趣,想探索一下,于是開(kāi)始了我的db4o discovery 之旅。

          db4o的jar 以及 api 在他document中都有寫(xiě)到, 其實(shí)他的 example 在document中也能找到,但是因?yàn)楸救?br />也是在學(xué)習(xí)的過(guò)程,所以將用例也簡(jiǎn)單描述一下:

          1.First Step:

          define an object Class, this is Pilot object;

          public class Pilot { ?
          ? private String name;
          ? private int points;
          ?
          ? public Pilot(String name,int points) {
          ? ? this.name=name;
          ? ? this.points=points;
          ? }
          ? ?
          ? public int getPoints() {
          ? ? return points;
          ? }
          ?
          ? public void addPoints(int points) {
          ? ? this.points+=points;
          ? }
          ?
          ? public String getName() {
          ? ? return name;
          ? }
          ?
          ? public String toString() {
          ? ? return name+"/"+points;
          ? }
          }

          the next target is how to store, retrieve , update, delete the instance of the Pilot Class.

          2.open database:

          [accessDb4o]
          ObjectContainer db=Db4o.openFile(Util.YAPFILENAME);
          try {
          // do something with db4o
          }
          finally {
          db.close();
          }

          db4o 中通過(guò)創(chuàng)建一個(gè)file 來(lái)建立database,這是一個(gè)二進(jìn)制文件。這里就是通過(guò) Db4o.openFile(..)來(lái)得到一個(gè) ObjectContainer instance.
          ObjectContainer 就表示database。 實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的操作后, 可以通過(guò) close,來(lái)release all resource。

          3.store object

          [storeFirstPilot]
          Pilot pilot1=new Pilot("Michael Schumacher",100);
          db.set(pilot1);
          System.out.println("Stored "+pilot1);

          只需要簡(jiǎn)單的調(diào)用set method 就可以了。

          4.retrieve object

          db4o 提供了三種 quering systems.
          Query by Example (QBE)
          Native Queries (NQ)
          SODA Query API (SODA)

          這里先介紹QBE:
          首先需要構(gòu)造你需要query 的對(duì)象的 prototype

          To retrieve all pilots from our database, we provide an 'empty' prototype:
          [retrieveAllPilots]
          Pilot proto=new Pilot(null,0);
          ObjectSet result=db.get(proto);
          listResult(result);

          public static void listResult(ObjectSet result) {
          System.out.println(result.size());
          while(result.hasNext()) {
          System.out.println(result.next());
          }

          在 jdk 1.5中 可以這樣寫(xiě)
          List <Pilot> pilots = db.query(Pilot.class);

          如果想查詢(xún) pilot name is Bobbi, 可以構(gòu)造這樣的prototype:
          Pilot proto=new Pilot("Bobbi",0);

          同樣如果想查詢(xún) Point 是100的 可以這樣 construct prototype:
          Pilot proto=new Pilot(null,100);

          5.update object

          updating objects is just as easy as storing them,In fact, you can use retrieve a object and modify it, set it to database again.

          [updatePilot]
          ObjectSet result=db.get(new Pilot("Michael Schumacher",0));
          Pilot found=(Pilot)result.next();
          found.addPoints(11);
          db.set(found);
          System.out.println("Added 11 points for "+found);
          retrieveAllPilots(db);

          6. Delete objects
          Objects are removed from the database using the delete() method.
          [deleteFirstPilotByName]
          ObjectSet result=db.get(new Pilot("Michael Schumacher",0));
          Pilot found=(Pilot)result.next();
          PDF by iText, generated by Doctor, courtesy of db4objects Inc.
          db.delete(found);
          System.out.println("Deleted "+found);

          -------------------------------------------
          Query:

          對(duì)應(yīng)數(shù)據(jù)庫(kù)來(lái)說(shuō),Query是很復(fù)雜 很重要的。
          剛才我們只是簡(jiǎn)單的 做了一個(gè)QBE的 introduce。現(xiàn)在我們來(lái)進(jìn)一步學(xué)習(xí)db4o的Query

          db4o 提供了三種 quering systems.
          Query by Example (QBE) 表示簡(jiǎn)單的查詢(xún),只做簡(jiǎn)單的CRUD(Create Read Update Delete)
          Native Queries (NQ) 接口層的調(diào)用,是db4o query的主要用法。
          SODA Query API (SODA) 內(nèi)部的接口層調(diào)用, 對(duì)db4o 更進(jìn)一步的深入了解,可以做出更復(fù)雜的query,可以動(dòng)態(tài)生成query

          其實(shí)對(duì)應(yīng)一般的數(shù)據(jù)庫(kù)操作, 第二種 query (NQ) 才是最常用的。
          NQ:
          http://www.cs.utexas.edu/users/wcook/papers/NativeQueries/NativeQueries8-23-05.pdf
          http://www.cs.utexas.edu/users/wcook/papers/SafeQuery/SafeQueryFinal.pdf
          (所謂navtive queries 從字面上的意思,我們的查詢(xún)可以通過(guò)native language 來(lái)query 數(shù)據(jù),而不需要象傳統(tǒng)的做法,需要develpment language
          和 query language 兩種語(yǔ)言來(lái)實(shí)現(xiàn)query。)
          NQ 看上去也 傳統(tǒng)的O/R mapping 看來(lái),他更能進(jìn)行對(duì)象直接的操作,但NQ 也有一個(gè)弊端,當(dāng)我們需要檢查一段很復(fù)雜的logic,如果我們是用的傳統(tǒng)
          的JDBC 我們可以找出query string 直接通過(guò)db UI Tool 去check logic 的正確性,但是如果是NQ 那就不行了, 我們需要運(yùn)行這段code, 那當(dāng)然需
          要初始化涉及到的persistence Object, 這可能也是NQ 的很大的一個(gè)drawback。

          SODA Query API:

          The SODA query API is low level quering api, allowing direct access to nodes of query graphs. It can generate drynamic queries.

          [retrieveAllPilots]
          Query query=db.query();
          query.constrain(Pilot.class);
          ObjectSet result=query.execute();
          listResult(result);

          通過(guò)query method 來(lái)創(chuàng)建Query instance,然后通過(guò) constrain instances 來(lái) execute出 相應(yīng)的result。
          a query graph made up of query nodes and constraints. A query node is a placeholder for a
          candidate object, a constraint decides whether to add or exclude candidates from the result.

          ////////////////////////////////
          //Three query method example
          ///////////////////////////////

          //QBE
          just do CRUD simple operation, The code show above.

          //NQ
          public static void retrieveComplexNQ(ObjectContainer db) {
          ObjectSet result=db.query(new Predicate() {
          public boolean match(Pilot pilot) {
          return pilot.getPoints()>99
          && pilot.getPoints()<199
          || pilot.getName().equals("Rubens Barrichello");
          }
          });
          listResult(result);
          }

          //SODA
          public static void retrieveComplexSODA(ObjectContainer db) {
          Query query=db.query();
          query.constrain(Pilot.class);
          Query pointQuery=query.descend("points");
          query.descend("name").constrain("Rubens Barrichello")
          .or(pointQuery.constrain(new Integer(99)).greater()
          .and(pointQuery.constrain(new
          Integer(199)).smaller()));
          ObjectSet result=query.execute();
          listResult(result);
          }
          4.Structed Object

          如果一個(gè)對(duì)象中不僅僅有常見(jiàn)的java類(lèi)型還包含其他的對(duì)象,那么在modify 被包含的對(duì)象的時(shí)候,就會(huì)出現(xiàn)一個(gè)問(wèn)題。如果我更新了這些被包含的對(duì)象,那么在update delete 的時(shí)候,他們會(huì)不會(huì)被操作到?db4o中 提供了一個(gè) depth的概念。所有object 的默認(rèn)的update depth為1,這就意味著該object 中的primitive 和 string members 能被update,其他類(lèi)型的對(duì)象將不被upda
          te。 同樣對(duì)應(yīng)delete 如果想實(shí)現(xiàn) 對(duì)象中的遞歸刪除, 那同樣需要利用db4o中的 delete depth


          這是update depth:
          [updatePilotSeparateSessionsImprovedPart1]
          Db4o.configure().objectClass("com.db4o.f1.chapter2.Car")
          .cascadeOnUpdate(true);

          這是delete depth:
          [deleteDeepPart1]
          Db4o.configure().objectClass("com.db4o.f1.chapter2.Car")
          .cascadeOnDelete(true);

          Again: Note that all configuration must take place before the ObjectContainer is opened.

          其實(shí)這里還沒(méi)有結(jié)束,對(duì)于delete 會(huì)出現(xiàn)這么一個(gè)問(wèn)題,當(dāng)我通過(guò) delet depth 將一個(gè)instance 刪除了,他里面包含的某個(gè)其他類(lèi)型的object instance 也被刪除了,但是這個(gè)
          對(duì)象還在被其他對(duì)象引用,那這個(gè)問(wèn)題怎么辦? 現(xiàn)在db4o 還沒(méi)有解決方法。我們現(xiàn)在只能
          小心操作delete。



          5. Transactions
          對(duì)應(yīng)數(shù)據(jù)庫(kù)來(lái)說(shuō),transaction 是必須的,下面我們來(lái)看看object dataBase--db4o是怎么
          來(lái)處理transcation的。

          當(dāng)open a container的時(shí)候,一個(gè)transaction 就隱型地開(kāi)始了,而當(dāng)close 這個(gè)container,
          那么當(dāng)前的transaction就隱型地提交了。

          那么如果顯型地commit 和 rollback呢? 下面有這么兩個(gè)例子:

          public static void storeCarCommit(ObjectContainer db) {
          Pilot pilot=new Pilot("Rubens Barrichello",99);
          Car car=new Car("BMW");
          car.setPilot(pilot);
          db.set(car);
          db.commit();
          }


          public static void storeCarRollback(ObjectContainer db) {
          Pilot pilot=new Pilot("Michael Schumacher",100);
          Car car=new Car("Ferrari");
          car.setPilot(pilot);
          db.set(car);
          db.rollback();
          }

          與JDBC相比,好像有一個(gè)區(qū)別就是,db4o不需要來(lái)設(shè)置commit的模式, setAutoCommit()

          她就是如果db.close(),那么就autoCommit了。

          對(duì)于Object Database,因?yàn)樗麄兌际怯胦bject 來(lái)存取,那么當(dāng)object 被set 相應(yīng)的值后,但沒(méi)有save到database,也就說(shuō)
          current transaction 被rollback,那么為了保持?jǐn)?shù)據(jù)的一致性,需要refresh live object.那么這個(gè)怎么來(lái)實(shí)現(xiàn)呢?

          public static void carSnapshotRollbackRefresh(ObjectContainer db)
          {
          ObjectSet result=db.get(new Car("BMW"));
          Car car=(Car)result.next();
          car.snapshot();
          db.set(car);
          db.rollback();
          PDF by iText, generated by Doctor, courtesy of db4objects Inc.
          db.ext().refresh(car,Integer.MAX_VALUE);
          System.out.println(car);
          }

          6.Embedded server
          對(duì)應(yīng) Embedded server,open一個(gè)port為0的server。

          [accessLocalServer]
          ObjectServer server=Db4o.openServer(Util.YAPFILENAME,0);
          try {
          PDF by iText, generated by Doctor, courtesy of db4objects Inc.
          ObjectContainer client=server.openClient();
          // Do something with this client, or open more clients
          client.close();
          }
          finally {
          server.close();
          }

          7.Networking

          [accessRemoteServer]
          ObjectServer server=Db4o.openServer(Util.YAPFILENAME,PORT);
          server.grantAccess(USER,PASSWORD);
          try {
          ObjectContainer
          client=Db4o.openClient("localhost",PORT,USER,PASSWORD);
          // Do something with this client, or open more clients
          client.close();
          }
          finally {
          server.close();
          }

          posted on 2006-11-29 13:21 linugb118 閱讀(1353) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           

          My Links

          Blog Stats

          常用鏈接

          留言簿(1)

          隨筆檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 长岛县| 菏泽市| 安陆市| 临沧市| 白城市| 中江县| 崇礼县| 上虞市| 河曲县| 无锡市| 汾阳市| 尼玛县| 临清市| 玉屏| 佛教| 洪湖市| 元氏县| 资阳市| 汶上县| 吴桥县| 民权县| 德令哈市| 明溪县| 岳阳县| 巴楚县| 西乌珠穆沁旗| 朝阳县| 东宁县| 稻城县| 龙陵县| 呼图壁县| 出国| 昌平区| 北票市| 阿荣旗| 尼玛县| 浦北县| 灌阳县| 旌德县| 中阳县| 班戈县|