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

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

          SELECT
              FROM [source]
                 WHERE [condition]

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

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

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

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

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

          看看具體的例子來體會(huì)一下究竟如何使用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的一個(gè)子類,它是通過關(guān)聯(lián)SET來達(dá)到更新數(shù)據(jù)的目的。數(shù)據(jù)更新是在查詢的基礎(chǔ)上實(shí)施的。

          假定更新數(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);
          //看看是不是將名稱改了
                      }

                  }

           

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

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

           

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

          評論:
          # re: [emf-query與emf-ocl] EMF-Query與EMF-OCL學(xué)習(xí)筆記系列六(Executing Queries) 2007-12-12 14:56 | JetGeng
          強(qiáng),學(xué)習(xí)了。  回復(fù)  更多評論
            
          # re: [emf-query與emf-ocl] EMF-Query與EMF-OCL學(xué)習(xí)筆記系列六(Executing Queries) 2007-12-19 10:55 | drnstar
          請問博主,emf-query和ocl-query之間有什么區(qū)別?  回復(fù)  更多評論
            
          主站蜘蛛池模板: 集安市| 汉源县| 观塘区| 临安市| 日照市| 景宁| 灵丘县| 来宾市| 从化市| 广宁县| 云林县| 张家港市| 三亚市| 延安市| 天津市| 桂平市| 文昌市| 株洲县| 抚州市| 修武县| 抚宁县| 鲁甸县| 米脂县| 钟山县| 亳州市| 中阳县| 黎平县| 岳阳县| 云林县| 莱阳市| 广西| 青州市| 大同市| 兰溪市| 台中市| 建昌县| 万源市| 繁峙县| 通州区| 华安县| 竹山县|