linugb118--java space

          Java

          Object DataBase --DB4O之旅

          Object DataBase --DB4O之旅

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

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

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

          3.store object

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

          只需要簡單的調(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中 可以這樣寫
          List <Pilot> pilots = db.query(Pilot.class);

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

          同樣如果想查詢 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ù)庫來說,Query是很復(fù)雜 很重要的。
          剛才我們只是簡單的 做了一個(gè)QBE的 introduce。現(xiàn)在我們來進(jìn)一步學(xué)習(xí)db4o的Query

          db4o 提供了三種 quering systems.
          Query by Example (QBE) 表示簡單的查詢,只做簡單的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ù)庫操作, 第二種 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 從字面上的意思,我們的查詢可以通過native language 來query 數(shù)據(jù),而不需要象傳統(tǒng)的做法,需要develpment language
          和 query language 兩種語言來實(shí)現(xiàn)query。)
          NQ 看上去也 傳統(tǒng)的O/R mapping 看來,他更能進(jìn)行對(duì)象直接的操作,但NQ 也有一個(gè)弊端,當(dāng)我們需要檢查一段很復(fù)雜的logic,如果我們是用的傳統(tǒng)
          的JDBC 我們可以找出query string 直接通過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);

          通過query method 來創(chuàng)建Query instance,然后通過 constrain instances 來 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ì)象中不僅僅有常見的java類型還包含其他的對(duì)象,那么在modify 被包含的對(duì)象的時(shí)候,就會(huì)出現(xiàn)一個(gè)問題。如果我更新了這些被包含的對(duì)象,那么在update delete 的時(shí)候,他們會(huì)不會(huì)被操作到?db4o中 提供了一個(gè) depth的概念。所有object 的默認(rèn)的update depth為1,這就意味著該object 中的primitive 和 string members 能被update,其他類型的對(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í)這里還沒有結(jié)束,對(duì)于delete 會(huì)出現(xiàn)這么一個(gè)問題,當(dāng)我通過 delet depth 將一個(gè)instance 刪除了,他里面包含的某個(gè)其他類型的object instance 也被刪除了,但是這個(gè)
          對(duì)象還在被其他對(duì)象引用,那這個(gè)問題怎么辦? 現(xiàn)在db4o 還沒有解決方法。我們現(xiàn)在只能
          小心操作delete。



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

          當(dāng)open a container的時(shí)候,一個(gè)transaction 就隱型地開始了,而當(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不需要來設(shè)置commit的模式, setAutoCommit()

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

          對(duì)于Object Database,因?yàn)樗麄兌际怯胦bject 來存取,那么當(dāng)object 被set 相應(yīng)的值后,但沒有save到database,也就說
          current transaction 被rollback,那么為了保持?jǐn)?shù)據(jù)的一致性,需要refresh live object.那么這個(gè)怎么來實(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 閱讀(1355) 評(píng)論(0)  編輯  收藏


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


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

          My Links

          Blog Stats

          常用鏈接

          留言簿(1)

          隨筆檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 雷波县| 岢岚县| 高阳县| 太和县| 涞水县| 丁青县| 柳州市| 竹北市| 平邑县| 深水埗区| 宣化县| 工布江达县| 安乡县| 南溪县| 连南| 江孜县| 稻城县| 虹口区| 霸州市| 甘谷县| 玉龙| 陆丰市| 灵石县| 元朗区| 福州市| 山西省| 信宜市| 历史| 宁南县| 根河市| 高青县| 西充县| 沁源县| 松阳县| 靖西县| 名山县| 工布江达县| 和林格尔县| 太康县| 类乌齐县| 河东区|