隨筆-35  評論-97  文章-0  trackbacks-0

          EMF-Query 的查詢語句結(jié)構(gòu)也是很簡單的

          SELECT
              FROM [source]
                 WHERE [condition]

          很像我們平常的SQL語句吧,但是不同的是SELECT、FROM 和WHERE 都是由對象來組合的。

          查詢的策略是:將所需要檢索的對象源(EObject Source)轉(zhuǎn)換成一棵對象樹,通過遍歷這棵對象樹,依次將樹中的對象與所需要檢索的條件進行匹配,選擇匹配成功的。在這個過程中,對象數(shù)會依據(jù)一定的算法來對對象樹進行裁減,目的是減少不必要的枝遍歷,提高查詢效率。EMF Query在構(gòu)造Condition的時候,提供了PruneHandler接口,用于判斷當前的eObject對象是否需要進行裁減遍歷行為。

          看看類的結(jié)構(gòu)吧:

          SELECT是通過與WHERE和FROM關(guān)聯(lián)(WHERE和FROM為SELECT的兩個屬性)來完成查詢語句的構(gòu)造的,而WHERE又通過與EObjectCondition關(guān)聯(lián)來完成條件的注入。注意這里是EObjectCondition,如果你的條件值類型的,可以通過條件適配器來轉(zhuǎn)換,前面帖子有介紹。對于查詢是否發(fā)生例外,你可以通過查詢的結(jié)果IQueryResult來的getException獲取例外,如果獲取內(nèi)容為null,說明沒有例外發(fā)生。

          查詢的對象源可以是單個的EObject,也可以是EObject的集合,還可以是IEObjectSource。

          看看具體的例子來體會一下究竟如何使用SELECT查詢。 模型還是前面用到的模型。

          數(shù)據(jù)有下面來確定:

                  ShopFactory shopFactory = ShopFactory.eINSTANCE;
                  
          // 商品種類
                  Category food = shopFactory.createCategory();
                  food.setName(
          "食物");
                  Category commodity 
          = shopFactory.createCategory();
                  commodity.setName(
          "日用品");
                  
          // 食品類產(chǎn)品
                  Product creamery = shopFactory.createProduct();
                  creamery.setName(
          "牛奶");
                  Product apple 
          = shopFactory.createProduct();
                  apple.setName(
          "蘋果");
                  Product pork 
          = shopFactory.createProduct();
                  pork.setName(
          "豬肉");
                  food.getProducts().add(creamery);
                  food.getProducts().add(apple);
                  food.getProducts().add(pork);
                  creamery.setCategory(food);
                  apple.setCategory(food);
                  pork.setCategory(food);
                  
          // 日用品類產(chǎn)品
                  Product towel = shopFactory.createProduct();
                  towel.setName(
          "毛巾");
                  commodity.getProducts().add(towel);
                  towel.setCategory(commodity);
                  
                  Shop shop 
          = shopFactory.createShop();
                  shop.setName(
          "人人樂");
                  shop.getCategories().add(food);
                  shop.getCategories().add(commodity);

           

          假定查詢需求:查“人人樂”中種類為“食品”的所有產(chǎn)品(方法有多種,下面給出其中一種)

                  //假定查詢需求:查“人人樂”中種類為“食品”的所有產(chǎn)品(方法有多種,下面給出其中一種)
                  
          //1、從名稱入手,首先,確定種類的名稱
                  Condition nameForFoodCategory = new SubStringValue("食物");
                  
          //2、名稱是什么呢?種類的屬性,所以用“屬性值條件” EObjectAttributeValueCondition
                  EObjectCondition foodCategory = new EObjectAttributeValueCondition(
                                                  ShopPackage.Literals.NAMED_ELEMENT__NAME,nameForFoodCategory);
                  
          //3、但是,你的入口地方是“人人樂”商店shop哦,商品與產(chǎn)品種類是什么關(guān)系?關(guān)聯(lián)! 那就用“關(guān)聯(lián)條件” EObjectReferenceValueCondition 吧
                  EObjectCondition foodProducts = new EObjectReferenceValueCondition(ShopPackage.eINSTANCE.getProduct_Category(),foodCategory);
                  
          //最后、執(zhí)行語句:從“人人樂”商店里按條件(種類名稱為“食物”的產(chǎn)品)查詢
                  SELECT statement = new SELECT(new FROM(shop), new WHERE(foodProducts));
                  Collection results 
          = statement.execute();
                  
          for(Object object : results)
                  
          {
                      System.out.println(object);
                  }

           

          假定查詢需求:查“人人樂”產(chǎn)品名為“毛巾”的產(chǎn)品品種類

                  //假定查詢需求:查“人人樂”產(chǎn)品名為“毛巾”的產(chǎn)品品種類
                  Condition nameForProductTowel = new SubStringValue("毛巾");
                  EObjectCondition towelProduct 
          = new EObjectAttributeValueCondition(
                                                                                     ShopPackage.Literals.NAMED_ELEMENT__NAME,nameForProductTowel);
                  EObjectCondition categoryForTowerl 
          = new EObjectReferenceValueCondition(ShopPackage.eINSTANCE.getCategory_Products(),towelProduct,ConditionPolicy.ANY,EStructuralFeatureValueGetter.getInstance());
                  statement 
          = new SELECT(new FROM(shop), new WHERE(categoryForTowerl));
                  results 
          = statement.execute();
                  
          for(Object object : results)
                  
          {
                      System.out.println(object);
                  }

           

          假定查詢需求:查“人人樂”產(chǎn)品種類中少于3的產(chǎn)品種類

          在這里,我用繼承EObjectCondition的子類來構(gòu)造條件:

              private static  class ProductsLessThan3Condition extends EObjectCondition {
                  
          public ProductsLessThan3Condition() {
                      
          super(PruneHandler.NEVER);
                  }

                  @Override
                  
          public boolean isSatisfied(EObject eObject) {
                      
          if (eObject instanceof Category) {
                          Category category 
          = (Category) eObject;
                          EList products 
          = category.getProducts();
                          
          if (products.size() < 3)
                              
          return true;
                      }

                      
          return false;
                  }

              }

          然后像平常一樣的查詢就可以了:

                  //假定查詢需求:查“人人樂”產(chǎn)品種類中少于3的產(chǎn)品種類
                  statement = new SELECT(new FROM(shop), new WHERE(new ProductsLessThan3Condition()));
                  results 
          = statement.execute();
                  
          for(Object object : results)
                  
          {
                      System.out.println(object);
                  }

           

          接著看看UPDATE:

          UPDATE是SELECT的一個子類,它是通過關(guān)聯(lián)SET來達到更新數(shù)據(jù)的目的。數(shù)據(jù)更新是在查詢的基礎(chǔ)上實施的。

          假定更新數(shù)據(jù)需求:將產(chǎn)品數(shù)小于3的產(chǎn)品種類改名為“被修改后的種類名稱”。

                  //將產(chǎn)品數(shù)小于3的產(chǎn)品種類改名為“被修改后的種類名稱”
                  IQueryResult updateResult = new UPDATE(new FROM(shop),new WHERE(new ProductsLessThan3Condition()),new SET(){
                      @Override
                      
          public boolean set(EObject eObject)
                      
          {
                          
          if(eObject instanceof Category)
                          
          {
                              Category category 
          = (Category)eObject;
                              category.setName(
          "被修改后的種類名稱");
                              
          return true;
                          }

                          
          return false;
                      }
          }
          ).execute();
                  
          if(updateResult.getException() != null){
                      System.out.println(updateResult.getException().getMessage());
                  }
          else{
                      
          for(Iterator it = updateResult.iterator(); it.hasNext();)
                      
          {
                          Object object 
          = (Object)it.next();
                          System.out.println(object);
          //看看是不是將名稱改了
                      }

                  }

           

          在查詢的過程進行對樹的裁剪留到下一節(jié)。EMF-Query查詢可以結(jié)合Hibernate和JDO來進行持久化,這些也留在后面吧。

          很快經(jīng)入OCL了,興奮ing~~~~~~~~~

           

          posted on 2007-06-12 22:42 三告習習 閱讀(1386) 評論(2)  編輯  收藏 所屬分類: emf/gef/gmf

          評論:
          # re: [emf-query與emf-ocl] EMF-Query與EMF-OCL學習筆記系列六(Executing Queries) 2007-12-12 14:56 | JetGeng
          強,學習了。  回復(fù)  更多評論
            
          # re: [emf-query與emf-ocl] EMF-Query與EMF-OCL學習筆記系列六(Executing Queries) 2007-12-19 10:55 | drnstar
          請問博主,emf-query和ocl-query之間有什么區(qū)別?  回復(fù)  更多評論
            
          主站蜘蛛池模板: 内丘县| 安乡县| 商水县| 青海省| 承德市| 丰顺县| 新化县| 潜江市| 兴业县| 安塞县| 阿拉尔市| 循化| 辽宁省| 友谊县| 深州市| 伊通| 阿图什市| 平塘县| 昌乐县| 静安区| 察哈| 宝兴县| 石家庄市| 犍为县| 苗栗县| 文昌市| 山阴县| 海丰县| 玉门市| 沂南县| 阿巴嘎旗| 谢通门县| 西城区| 乌拉特前旗| 香港| 乐至县| 宝鸡市| 外汇| 太保市| 怀柔区| 太谷县|