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

          EMF-Query 的查詢語句結構也是很簡單的

          SELECT
              FROM [source]
                 WHERE [condition]

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

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

          看看類的結構吧:

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

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

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

          數據有下面來確定:

                  ShopFactory shopFactory = ShopFactory.eINSTANCE;
                  
          // 商品種類
                  Category food = shopFactory.createCategory();
                  food.setName(
          "食物");
                  Category commodity 
          = shopFactory.createCategory();
                  commodity.setName(
          "日用品");
                  
          // 食品類產品
                  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);
                  
          // 日用品類產品
                  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);

           

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

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

           

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

                  //假定查詢需求:查“人人樂”產品名為“毛巾”的產品品種類
                  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);
                  }

           

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

          在這里,我用繼承EObjectCondition的子類來構造條件:

              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;
                  }

              }

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

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

           

          接著看看UPDATE:

          UPDATE是SELECT的一個子類,它是通過關聯SET來達到更新數據的目的。數據更新是在查詢的基礎上實施的。

          假定更新數據需求:將產品數小于3的產品種類改名為“被修改后的種類名稱”。

                  //將產品數小于3的產品種類改名為“被修改后的種類名稱”
                  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);
          //看看是不是將名稱改了
                      }

                  }

           

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

          很快經入OCL了,興奮ing~~~~~~~~~

           

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

          評論:
          # re: [emf-query與emf-ocl] EMF-Query與EMF-OCL學習筆記系列六(Executing Queries) 2007-12-12 14:56 | JetGeng
          強,學習了。  回復  更多評論
            
          # re: [emf-query與emf-ocl] EMF-Query與EMF-OCL學習筆記系列六(Executing Queries) 2007-12-19 10:55 | drnstar
          請問博主,emf-query和ocl-query之間有什么區別?  回復  更多評論
            
          主站蜘蛛池模板: 聂拉木县| 漳平市| 印江| 乐都县| 时尚| 万山特区| 攀枝花市| 白银市| 凯里市| 大竹县| 寻乌县| 诸城市| 玉山县| 长葛市| 吕梁市| 汽车| 鲁山县| 博罗县| 北票市| 墨竹工卡县| 乡城县| 铁力市| 江津市| 苍山县| 堆龙德庆县| 新绛县| 清新县| 泾阳县| 扎兰屯市| 阿克陶县| 深水埗区| 桦甸市| 当涂县| 兴国县| 榆树市| 屏东市| 湾仔区| 富平县| 黄冈市| 三门县| 民丰县|