-
Notifications
You must be signed in to change notification settings - Fork 254
ServiceFramework MongoDB DataMapper Support
##ServiceFramework MongoDB Support
注: 文档中的具体类来自com.example.document ,如果你想看类的完整样子,可以移步到 项目中查看那。
这次我们的model类不需要任何Annotation和配置文件(当然mongodb的链接配置还是需要的)。完全使用声明式语法!
####mongodb 使用配置:
development:
datasources:
mysql:
host: 127.0.0.1
port: 3306
database: wow
username: mysql
password: ****
disable: false
mongodb:
host: 127.0.0.1
port: 27017
database: data_center
disable: false
redis:
host: 127.0.0.1
port: 6379
disable: true`
上面就是mongodb所有的被指选项。 你可以通过disable来关闭活着开启mongodb. 同理redis 和 mysql 都可以通过disable 选项进行开启活着关闭。
####mongodb 建模
mongodb 因为是schema free style的,存储结构是BSON结构,这就意味着mongodb的类关联有两种,分别为embedded 和 related. 我们一一举例(例子只是为了说明用法)
先说传统的related 模式,就是不同的model 对应不同的表。
public class Person extends Document {
//在静态代码块里做声明式配置。
static {
//说明mongodb中的表名称为persons
storeIn("persons");
//和Address 的多对一关系。你只要告诉关联的类名和外键id即可。
hasMany("addresses", new Options(map(
Options.n_kclass, Address.class,
Options.n_foreignKey, "person_id"
)));
//和IdCard的一对一关系。你依然需要提供关联的类名和外键id名称
hasOne("idcard", new Options(map(
Options.n_kclass, IdCard.class,
Options.n_foreignKey, "person_id"
)));
}
//你只要声明这个方法,方法名称对应hasMany的那个名字
public Association addresses() {
throw new AutoGeneration();
}
//你只要声明这个方法,方法名称对应hasOne的哪个名字
public Association idcard() {
throw new AutoGeneration();
}
//定义属性
private String name;
private Integer bodyLength;
//这些用IDE自动生成吧。记住生成后就不要动他们了。因为框架会自动对这些方法增强
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getBodyLength() {
return bodyLength;
}
public void setBodyLength(Integer bodyLength) {
this.bodyLength = bodyLength;
}
}
public class Address extends Document {
static {
storeIn("addresses");
belongsTo("person", new Options(
map(
Options.n_kclass, Person.class,
Options.n_foreignKey, "person_id"
)
));
}
public Association person() {
throw new AutoGeneration();
}
private String location;
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
大部分功能使用已经写在了代码注释中了。 这次我们发现比 传统的ORM model略微繁琐点。其实去掉get/set也没多少。然后就是属性定义和关联关系声明了。属性你其实可以完全不定义,没有关系。但是如果你需要访问属性的话,建议还是定义一下,这样方方便IDE生成get/set方法,生成get/set方法有啥好处呢?就是方便你访问属性贝。
上面就把所有的配置好了。 接着开始讲解使用方式。
新建一个Person 实例并且存储它。
Person person = Person.create(map(
"_id", 100,
"name", "google",
"bodyLength", 10
));
person.save();
现在添加一个新的Address给我们刚才存储的人。
person.addresses().build(map("_id", 77, "location", "天国的世界")).save();
那如果我们根据name 查询那些人呢?
List<Person> persons = Person.where(map("name","google")).fetch();
根据ID查询:
Person person = Person.findById(100);
//你也可以一次查询多个id
List<Person> persons = Person.find(list(100,1000));
如果我已经有person对象,想找到这个人的id为77的地址怎么办?
person.addresses().filter().findById(77);
//其实你还可以使用where条件语句,比如
person.addresses().filter().where(map("_id",77)).singleFetch();
是不是觉得查询挺爽的。
如果我要删除呢?
person.remove();//就这么一句话
好了,我们现在看看embedded 文档是怎么样的。
public class Blog extends Document {
static {
storeIn("blogs");
//和related 唯一的区别就是使用hasManyEmbedded而不是hasMany
hasManyEmbedded("articles", new Options(map(
Options.n_kclass, Article.class
)));
}
public AssociationEmbedded articles() {
throw new AutoGeneration();
}
//属性啦
private String userName;
private String blogTitle;
//properties and their access methods
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getBlogTitle() {
return blogTitle;
}
public void setBlogTitle(String blogTitle) {
this.blogTitle = blogTitle;
}
}
ublic class Article extends Document {
static {
storeIn("articles");
belongsToEmbedded("blog", new Options(map(
Options.n_kclass, Blog.class
)));
}
public AssociationEmbedded blog() {
throw new AutoGeneration();
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String title;
public String body;
}
我们直接看看使用吧。
首先假设客户端传来的数据类似:
Map blogMap = map(
"_id", 100,
"userName", "jack",
"blogTitle", "this is a test blog",
"articles", list(
map(
"title", "article",
"body", "article body"
),
map(
"title", "article1",
"body", "article body1"
)
)
);
我们看到这事比较复杂的嵌套结构。那么如何保存到mongodb呢?
Blog blog = Blog.create(blogMap);
blog.save();
blog = Blog.findById(100);
List<Article> articles = blog.articles().find();
用法上和前面完全一样。
如何删除呢?
List<Article> articles = blog.articles().find();
articles.get(0).remove();//这样就把子元素删除掉啦。
记住 embedded 如果删除最外层的类,会把所有的子元素删除掉。因为毕竟他们是一条记录,其实。