Mongodb 的ORM框架 Morphia 之 Updating

   

           简介
           这个有两个修改你的数据库的方法。你可以insert/save一个完整的实体,或者通过update操作。我们将在一下讨论。
        Updating(On the server)
             总之,当你通过Datesote调用update方法时就会向MongoDB服务器发送一个修改已存在数据的指令。
             
              
                   
 interface Datastore {
     ...
  

        /** updates all entities found with the operations*/
        <T> UpdateResults<T> update(Query<T> query, UpdateOperations<T> ops);
        /** updates all entities found with the operations; if nothing is found insert the update as an entity if "createIfMissing" is true*/
        <T> UpdateResults<T> update(Query<T> query, UpdateOperations<T> ops, boolean createIfMissing);
        /** updates the first entity found with the operations*/
        <T> UpdateResults<T> updateFirst(Query<T> query, UpdateOperations<T> ops);
        /** updates the first entity found with the operations; if nothing is found insert the update as an entity if "createIfMissing" is true*/
        <T> UpdateResults<T> updateFirst(Query<T> query, UpdateOperations<T> ops, boolean createIfMissing);
        /** updates the first entity found with the operations; if nothing is found insert the update as an entity if "createIfMissing" is true*/
        <T> UpdateResults<T> updateFirst(Query<T> query, T entity, boolean createIfMissing);
}
public interface UpdateOperations<T> {
        /** sets the field value */
        UpdateOperations<T> set(String fieldExpr, Object value);
        /** removes the field */
        UpdateOperations<T> unset(String fieldExpr);


        /** adds the value to an array field*/
        UpdateOperations<T> add(String fieldExpr, Object value);
        UpdateOperations<T> add(String fieldExpr, Object value, boolean addDups);
        /** adds the values to an array field*/
        UpdateOperations<T> addAll(String fieldExpr, List<?> values, boolean addDups);
        
        /** removes the first value from the array*/
        UpdateOperations<T> removeFirst(String fieldExpr);
        /** removes the last value from the array*/
        UpdateOperations<T> removeLast(String fieldExpr);
        /** removes the value from the array field*/
        UpdateOperations<T> removeAll(String fieldExpr, Object value);
        /** removes the values from the array field*/
        UpdateOperations<T> removeAll(String fieldExpr, List<?> values);


        /** decrements the numeric field by 1*/
        UpdateOperations<T> dec(String fieldExpr);
        /** increments the numeric field by 1*/
        UpdateOperations<T> inc(String fieldExpr);
        /** increments the numeric field by value (negatives are allowed)*/
        UpdateOperations<T> inc(String fieldExpr, Number value);
}

               
         The Field Expression
           属性表达式是用在所有的操作上的,可以是单个的属性名,也可以是用点“.”连接的嵌套属性。在表达式中你也可以使用位置操作副($)。在属性
          表达式中没有标准,你可以使用任何在MongoDB服务端有效符号。
         
         事例初始化
              一下所有的实例创建的连接和Morphia实例都使用的一下代码。
                    
Morphia morphia = new Morphia();
morphia.map(Hotel.class).map(Address.class);
Datastore datastore = morphia.createDatastore("MorphiaSampleDb");
Hotel hotel = new Hotel("Fairmont", 3, new Address("1 Rideau Street", "Ottawa", "K1N8S7", "Canada"));
datastore.save(hotel);
UpdateOperations<Hotel> ops;

// This query will be used in the samples to restrict the update operations to only the hotel we just created.
// If this was not supplied, by default the update() operates on all documents in the collection.
// We could use any field here but _id will be unique and mongodb by default puts an index on the _id field so this should be fast!
Query<Hotel> updateQuery = datastore.createQuery(Hotel.class).field("_id").equal(hotel.getId());

// The Mapper class also provides a public static of the default _id field name for us...
Query<Hotel> updateQuery = datastore.createQuery(Hotel.class).field(Mapper.ID_KEY).equal(hotel.getId());

         注意: 使用的是 equal() 而不是 equals()
              
@Entity("hotels")
public class Hotel
{
   @Id
   private ObjectId id;


   private String name;
   private int stars;


   @Embedded
   private Address address;


   @Embedded
   List<Integer> roomNumbers = new ArrayList<Integer>();


   // ... getters and setters
}


@Embedded
public class Address
{
   private String street;
   private String city;
   private String postalCode;
   private String country;


   // ... getters and setters
}
      
     set/unset
            
// 改变Hotel的name属性值
ops = datastore.createUpdateOperations(Hotel.class).set("name", "Fairmont Chateau Laurier");
datastore.update(updateQuery, ops);

//也可以操作嵌套文档, 改变address的city属性值
ops = datastore.createUpdateOperations(Hotel.class).set("address.city", "Ottawa");
datastore.update(updateQuery, ops);

// 删除Hotel的name属性值
// 当下会访问Hotel时name属性为null
ops = datastore.createUpdateOperations(Hotel.class).unset("name");
datastore.update(updateQuery, ops);
   
       inc/dec
          
// 'stars'属性增长一
ops = datastore.createUpdateOperations(Hotel.class).inc("stars");
datastore.update(updateQuery, ops);

// 'stars'属性值增长4
ops = datastore.createUpdateOperations(Hotel.class).inc("stars", 4);
datastore.update(updateQuery, ops);

// 'stars'属性值减少1
ops = datastore.createUpdateOperations(Hotel.class).dec("stars");  // 和 .inc("stars", -1) 相同
datastore.update(updateQuery, ops);

// 'stars'属性值减少4
ops = datastore.createUpdateOperations(Hotel.class).inc("stars", -4);
datastore.update(updateQuery, ops);
    
      add/All
            
// 把一个值放入到数组中 array() (+v 0.95) 
// same as .add("roomNumbers", 11, false)
ops = datastore.createUpdateOperations(Hotel.class).add("roomNumbers", 11);
datastore.update(updateQuery, ops); // [ 11 ]
    当在一个不是数组的属性上进行数组操作时MongoDB将会抛出错误。
      
ops = datastore.createUpdateOperations(Hotel.class).set("roomNumbers", 11);
datastore.update(updateQuery, ops);

// 由于没有rooNumbers数组将会引起错误
ops = datastore.createUpdateOperations(Hotel.class).add("roomNumbers", 11, false);
datastore.update(updateQuery, ops);  // causes error

// 删除roomNummbers属性
ops = datastore.createUpdateOperations(Hotel.class).unset("roomNumbers");
datastore.update(updateQuery, ops);

// use the 3rd parameter to add duplicates

// add to end of array, same as add()
ops = datastore.createUpdateOperations(Hotel.class).add("roomNumbers", 11, false);
datastore.update(updateQuery, ops);  // [ 11 ]

// no change since its a duplicate... doesn't cause error
ops = datastore.createUpdateOperations(Hotel.class).add("roomNumbers", 11, false);
datastore.update(updateQuery, ops);  // [ 11 ]

// push onto the end of the array
ops = datastore.createUpdateOperations(Hotel.class).add("roomNumbers", 12, false);
datastore.update(updateQuery, ops); // [ 11, 12 ]

// add even if its a duplicate
ops = datastore.createUpdateOperations(Hotel.class).add("roomNumbers", 11, true);
datastore.update(updateQuery, ops); // [ 11, 12, 11 ]

     removeFirst/Last/All

            
//given roomNumbers = [ 1, 2, 3 ]
ops = datastore.createUpdateOperations(Hotel.class).removeFirst("roomNumbers");
datastore.update(updateQuery, ops);  // [ 2, 3 ]


//given roomNumbers = [ 1, 2, 3 ]
ops = datastore.createUpdateOperations(Hotel.class).removeLast("roomNumbers");
datastore.update(updateQuery, ops);  // [ 1, 2 ]
ops = datastore.createUpdateOperations(Hotel.class).removeLast("roomNumbers");
datastore.update(updateQuery, ops);  // [ 1 ]
ops = datastore.createUpdateOperations(Hotel.class).removeLast("roomNumbers");
datastore.update(updateQuery, ops);  // []   empty array


//given roomNumbers = [ 1, 2, 3, 3 ]
ops = datastore.createUpdateOperations(Hotel.class).removeAll("roomNumbers", 3);
datastore.update(updateQuery, ops);  // [ 1, 2 ]

//given roomNumbers = [ 1, 2, 3, 3 ]
ops = datastore.createUpdateOperations(Hotel.class).removeAll("roomNumbers", Arrays.asList(2, 3));
datastore.update(updateQuery, ops);  // [ 1 ]
    

   Multiple Operations

           你也可以在一个update指令中执行多个updae操作。
           
//设置城市名称为Ottawa和是stars的增长1
ops = datastore.createUpdateOperations(Hotel.class).set("city", "Ottawa").inc("stars");
datastore.update(updateQuery, ops);

//如果你在同一个属性上执行多次同样的指令操作,结果将会变化,即:只有最后一次有效
ops = datastore.createUpdateOperations(Hotel.class).inc("stars", 50).inc("stars");  //stars只增长1
ops = datastore.createUpdateOperations(Hotel.class).inc("stars").inc("stars", 50);  //stars只增长50

//你不能在同一个属性上执行相矛盾的操作。
ops = datastore.createUpdateOperations(Hotel.class).set("stars", 1).inc("stars", 50); //引起错误
       updateFirst方法            在默认的驱动和shell上这是默认的行为。在Morphia中我们认为修改所有的符合条件的结果是最好的默认选择(如下)。
              {name: "Fairmont", stars: 5}, {name: "Last Chance", stars: 3}
              
ops = datastore.createUpdateOperations(Hotel.class).inc("stars", 50);

// (+v 0.95 now takes into account the order())
// morphia 执行updateFirst方法仅仅执行第一个符合查询条件的数据项
datastore.updateFirst(datastore.find(Hotel.class).order("stars"), ops);  //仅仅修改Last Chance
datastore.updateFirst(datastore.find(Hotel.class).order("-stars"), ops); // 仅仅修改 Fairmont
//default shell version is to match first
//shell version has a multi to indicate to update all matches, not just first
//to mimic morphia operation, set multi = false
db.collection.update( criteria, objNew, upsert, multi );

     update 方法
            
ops = datastore.createUpdateOperations(Hotel.class).inc("stars", 50);

// morphia 默认的update是修改所有的Hotels
datastore.update(datastore.createQuery(Hotel.class), ops);  //所有的hotel都会增长
//equivalent morphia shell version is... upsert = false, multi = true
db.collection.update( criteria, objNew, false, true );
     createIfMissing (overload parameter)
        所有的update都被重载支持一个"createIfMissing"参数。
       
ops = datastore.createUpdateOperations(Hotel.class).inc("stars", 50);

//修改, 如果没有找到就添加一个。
datastore.updateFirst(datastore.createQuery(Hotel.class).field("stars").greaterThan(100), ops, true);  

// creates { "_id" : ObjectId("4c60629d2f1200000000161d"), "stars" : 50 }
//equivalent morphia shell version is... upsert = true
db.collection.update( criteria, objNew, true, multi );
      英语水平有限,敬请大侠 斧正
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值