mongodb的morphia框架学习笔记(补充)
morphia的更新操作详解:
-------------------------
用id字段匹配是最快的,因为mongodb默认为id列做了索引:
Query<Hotel> updateQuery = datastore.createQuery(Hotel.class).field("_id").equal(hotel.getId());
除了"_id"外,还有一种静态常量描述ID的方式:
Query<Hotel> updateQuery = datastore.createQuery(Hotel.class).field(Mapper.ID_KEY).equal(hotel.getId());
注意,用的是equal()方法,而不是equals()方法!
-------------------------
set和unset方法:
改旅店名:
ops = datastore.createUpdateOperations(Hotel.class).set("name", "Fairmont Chateau Laurier");
改旅店地址名:
ops = datastore.createUpdateOperations(Hotel.class).set("address.city", "Ottawa");
删除name属性,会导致下次读取时name=null
ops = datastore.createUpdateOperations(Hotel.class).unset("name");
-------------------------
inc和dec方法:
星级加1:
ops = datastore.createUpdateOperations(Hotel.class).inc("stars");
星级加4:
ops = datastore.createUpdateOperations(Hotel.class).inc("stars", 4);
-------------------------
add和addAll方法:
将11加入房间号数组中:
ops = datastore.createUpdateOperations(Hotel.class).add("roomNumbers", 11);
这与add("roomNumbers", 11, false)等价
在非数组字段上执行add操作将报错。
add的第三个参数标识“是否加入重复元素”。若为true,如果已存在相同元素,不会加入,也不会报错。
-------------------------
removeFirst/Last/All方法:
假设目前是[ 1, 2, 3, 3 ],运行以下方法之后:
ops = datastore.createUpdateOperations(Hotel.class).removeAll("roomNumbers", 3);
就剩下了[ 1, 2 ]——所有的3都被移除了。
假设目前是[ 1, 2, 3, 3 ],运行以下方法之后:
ops = datastore.createUpdateOperations(Hotel.class).removeAll("roomNumbers", Arrays.asList(2, 3));
就剩下了[ 1 ] ——所有的2和3都被移除了。
-------------------------
多重操作:
ops = datastore.createUpdateOperations(Hotel.class).set("city", "Ottawa").inc("stars");
如果在同一个updateOperation对象上对同一个字段多次操作,结果是不定的。
-------------------------
update/updateFirst方法:
在默认driver里,使用update默认只更新第一个元素(multi默认为false)。
但是在morphia里,update影响所有记录(对应的底层driver里的update第四个参数multi为true),updateFirst才是影响第一个元素(对应的底层driver里的update第四个参数multi为false)。
-------------------------
createIfMissing参数:
morphia里所有的方法都重载,最后可以附加一个参数“createIfMissing”
对应的底层driver或者shell里的操作是upsert = true:
db.collection.update( criteria, objNew, true, multi );
-------------------------------------------------
乐观锁注解@Version的使用:
http://code.google.com/p/morphia/wiki/MongoNewsletterArticleDec2010
class Person {
@Id String name;
String phone;
@Version
long version;
}
Person me = new Person("Scott Hernandez");
ds.save(me) //保存一个person
Person meAgain = ds.get(Person.class, "Scott Hernandez"); //把这个person读出来先放着
me.setPhone("111-376-7379");
ds.save(me); //把原来的me修改一下再存进去,版本号已经变化
meAgain.setPhone("123-376-7379");
ds.save(meAgain); //刚次读出来的meAgain是老版本号,此时存储将抛出并发异常
注:目前乐观锁的版本号实现方式是时间戳,根据作者的回答:
http://code.google.com/p/morphia/wiki/MongoNewsletterArticleDec2010
下一个版本的morphia将使用自增数字来代替时间戳作为乐观锁的版本号使用,以避免多服务器时间不一致等问题。