Mongo的ORM框架的学习Morphia(annotations)
一:@Entity的使用
@Entity
value属性为
DBConllection设置名称。必须有一个无参的默认构造方法,可以是
public、protected、private等
noClassnameStored属性默认为存储类名。如果只存储单一的实体对象并且关心数据库大小,不存储类名是安全的。
保存类名的主要目的是在同一个链接中保存不同的实体对象,但是你想作为他们的基类或超类来读取。如果不在文档中保存类名,Morphia将不能正确的识别创建那个类。
如:
@Entity("animals") abstract class Animal { String name; }
@Entity("animals") Cat extends Animal { ... }
@Entity("animals") Dog extends Animal { ... }
//And then performing the following query...
List<Animal> animals = ds.createQuery(Animal.class).asList();
@Id
@Id将值注解为MongoDB的唯一ID字段,
MongoDB必须有一个唯一索引,mongo会自动生成id。如果使用其他类型,需要自己设置。
@Id
private ObjectId id;
@
Transient注解
如果你想把一个属性排除映射到Mongo中, 你可以使用@Transient注解:
import com.google.code.morphia.annotations.Transient;
...
@Transient private int myTransientInt;
@
Property
默认情况下,Morphia把属性名作为Mongo中的字段名。这个可以通过@Property注解进行修改,指定一个名称。
import com.google.code.morphia.annotations.Property;
...
@Property("my_integer")
private int myInt; //在MongoDB中为my_integer
package com.easyway.mash5.app.model;
import com.google.code.morphia.annotations.Entity;
/**
* Mongodb 的ORM框架 Morphia 注解一 —— @Entity .
* 定义实体
* 1、@Entity
* 如果你想通过Morphia把你的对象保存到Mongo中,你首先要做的是使用@Entity注解你的类:
*
* A、名称和构造方法
* 你可以为你的MongoDB DBConllection设置名称。必须有一个无参的默认构造方法。
* 注意:你的默认构造方法不一定是public,也可以是protected或private。
* B、在文档中的类名和怎样废弃使用类名
*在@Entity注解中提供了一个可选的参数用来标识是否在文档中保存类名。
*默认会在文档中保存类名。
* 为什么要使用他哪?保存类名的主要目的是,当你在同一个链接中保存不同的实体对象,但是你想
* 作为他们的基类或超类来读取。
*如:
* @Entity("animals") abstract class Animal { String name; }
* @Entity("animals") Cat extends Animal { ... }
* @Entity("animals") Dog extends Animal { ... }
*
*查询如下:
* List<Animal> animals = ds.createQuery(Animal.class).asList();
* 正如你看到的,如果不在文档中保存类名,Morphia将不能正确的识别创建那个类。
* 如果你在一个链接中只保存唯一的实体类型并且你还关心你的数据库大小,在你的@Entity注解上加
* 上noClassnameStored=true 参数将会是安全的。
*
* @Title:
* @Description: 实现TODO
* @Copyright:Copyright (c) 2011
* @Company:易程科技股份有限公司
* @Date:2012-3-1
* @author
* @version 1.0
*/
@Entity("TaskTemplate")
public class TaskTemplate extends BaseEntry {
private static final long serialVersionUID = 1L;
private String name;
private Boolean hasHeader;
private String positions;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getHasHeader() {
return hasHeader;
}
public void setHasHeader(Boolean hasHeader) {
this.hasHeader = hasHeader;
}
public String getPositions() {
return positions;
}
public void setPositions(String positions) {
this.positions = positions;
}
}
二:@R
eference 的用法
package com.easyway.mash5.app.model;
import java.util.List;
import java.util.Vector;
import com.google.code.morphia.annotations.Entity;
import com.google.code.morphia.annotations.Property;
import com.google.code.morphia.annotations.Reference;
/**
*@Reference 的用法:
* //引用对象 Mongo在同一个数据库引用一个文档(对象)到另一个。
*当使用引用时有很重要的一点我们必须提及:被引用的对像在被引用之前必须已经保存到了
*MongoDB数据库中。
* //默认情况下,Morphia使用属性名作为在数据库中保存的值。当然这个可以在@Reference注解中指定。
*
* 补充:注解使用的参数。
* concreteClass: 指定具体的实体类。
* ignoreMissing:忽略任何不能解决的参考。
* lazy: 为参考创建一个代理,这个将在第一次调用时加载(类似Hibernate中的lazy属性)
* value: 指定在Mongo中存储的属性名。
* @Title:
* @Description: 实现TODO
* @Copyright:Copyright (c) 2011
* @Company:易程科技股份有限公司
* @Date:2012-3-1
* @author
* @version 1.0
*/
@Entity("UserCollection")
public class UserCollection extends BaseEntry {
/**
*
*/
private static final long serialVersionUID = 1L;
@Property("member")
@Reference(concreteClass = Vector.class)
private List<User> memberList;
private String name;
private String owner;
private String isOrganization;
private String type;
private String isOrganiztion;
private String alphabet;
private String firstAlphabet;
private String tag;
private String avatarURLKey;
@Property("role")
@Reference(concreteClass = Vector.class)
private List<Role> roleList;
private String desc;
@Property("task")
@Reference(concreteClass = Vector.class)
private List<Task> privateTaskList;
private String organizationVersion;
private String organizationName;
private String customerTable;
public List<User> getMemberList() {
return memberList;
}
public void setMemberList(List<User> memberList) {
this.memberList = memberList;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getIsOrganization() {
return isOrganization;
}
public void setIsOrganization(String isOrganization) {
this.isOrganization = isOrganization;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getIsOrganiztion() {
return isOrganiztion;
}
public void setIsOrganiztion(String isOrganiztion) {
this.isOrganiztion = isOrganiztion;
}
public String getAlphabet() {
return alphabet;
}
public void setAlphabet(String alphabet) {
this.alphabet = alphabet;
}
public String getFirstAlphabet() {
return firstAlphabet;
}
public void setFirstAlphabet(String firstAlphabet) {
this.firstAlphabet = firstAlphabet;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public String getAvatarURLKey() {
return avatarURLKey;
}
public void setAvatarURLKey(String avatarURLKey) {
this.avatarURLKey = avatarURLKey;
}
public List<Role> getRoleList() {
return roleList;
}
public void setRoleList(List<Role> roleList) {
this.roleList = roleList;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public List<Task> getPrivateTaskList() {
return privateTaskList;
}
public void setPrivateTaskList(List<Task> privateTaskList) {
this.privateTaskList = privateTaskList;
}
public String getOrganizationVersion() {
return organizationVersion;
}
public void setOrganizationVersion(String organizationVersion) {
this.organizationVersion = organizationVersion;
}
public String getOrganizationName() {
return organizationName;
}
public void setOrganizationName(String organizationName) {
this.organizationName = organizationName;
}
public String getCustomerTable() {
return customerTable;
}
public void setCustomerTable(String customerTable) {
this.customerTable = customerTable;
}
}
三:使用容器(Using Lists, Sets, and Maps)
package com.easyway.mash5.app.model;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import com.google.code.morphia.annotations.Entity;
import com.google.code.morphia.annotations.Property;
import com.google.code.morphia.annotations.Reference;
/**
* Mongodb 的ORM框架 Morphia 之 使用容器(Using Lists, Sets, and Maps) .
* 集合的使用:
* Morphia 支持容器(List, Set, Map) 和数组(Integer)
* Morphia 将使用一下实现(默认)来创建容器:
*· java.util.ArrayList for List
*·java.util.HashSet for Set
*·java.util.hashMap for Map
* 如果你想使用其他的实现, 你可以在注解中重写他们
* @Property(concreteClass = java.util.TreeSet.class)
* private Set<String> tags;
*
* @Embedded(concreteClass = java.util.TreeMap.class)
* private Map<String,Translation> translations;
*
* @Reference(concreteClass = java.util.Vector.class)
* private List<Article> relatedArticles;
*
* //是否延时加载相关的关联应用对象
* @Property("userCollection")
*@Reference(concreteClass = java.util.Vector.class,lazy=true)
*private List<UserCollection> userCollectionList; //拥有该角色的团队
*
* 角色模型类
* @Title:
* @Description: 实现TODO
* @Copyright:Copyright (c) 2011
* @Company:易程科技股份有限公司
* @Date:2012-3-1
* @author
* @version 1.0
*/
@Entity("Role")
public class Role extends BaseEntry {
/**
*
*/
private static final long serialVersionUID = 1L;
private String name; //角色的名称
private String desc;//角色的描述
@Property("acl")
@Reference(concreteClass = Vector.class)
private List<ACL> priviligeList;//角色拥有的权限的引用对象
@Property("userCollection")
@Reference(concreteClass = java.util.Vector.class,lazy=true)
private List<UserCollection> userCollectionList; //拥有该角色的团队
@Property("member")
@Reference(concreteClass =java.util.TreeSet.class,lazy=false)
private Set<User> userList; //拥有该角色的用户的信息
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public List<ACL> getPriviligeList() {
return priviligeList;
}
public void setPriviligeList(List<ACL> priviligeList) {
this.priviligeList = priviligeList;
}
public List<UserCollection> getUserCollectionList() {
return userCollectionList;
}
public void setUserCollectionList(List<UserCollection> userCollectionList) {
this.userCollectionList = userCollectionList;
}
public Set<User> getUserList() {
return userList;
}
public void setUserList(Set<User> userList) {
this.userList = userList;
}
}
四:@Indexed的用法
@Indexed
当
datastore.ensureIndexes() 方法调用时,mongoDB将该值
生成索引。
@Indexed(value=IndexDirection.ASC, name="upc", unique=true, dropDups=true)
private String upcSymbol;
value :指定index的方向。默认ASC。
IndexDirection.ASC (ascending), IndexDirection.DESC (descending), IndexDirection.BOTH (both)
name :指定index的名称。默认由mongoDB产生
unique:是否为唯一索引。默认false。如果为true,插入重复值会报错。
dropDups:通知唯一索引删除重复值,只有第一条被保留,默认为false。
@Indexes&@Index
复合indexes可以指定多个字段,该注解是class级别。例如下面代码指定user为默认升序同时date为降序(-表示DESC)
@Entity // this is require to know where the indexes are to be created
@Indexes( @Index("user, -date") )
public class ChangeLog{
Date date;
String user;
Record changedRecord;
}
package com.easyway.mash5.app.model;
import java.util.List;
import java.util.Vector;
import com.google.code.morphia.annotations.Entity;
import com.google.code.morphia.annotations.Indexed;
import com.google.code.morphia.annotations.Property;
import com.google.code.morphia.annotations.Reference;
import com.google.code.morphia.utils.IndexDirection;
/**
* 索引的使用:
* @Indexed
* 此注解是为某个字段申请一个索引。 当datastore.ensureIndexes() 方法被调用时 这些索引就会被申请..
* @Indexed(value=IndexDirection.ASC, name="upc", unique=true, dropDups=true)
* private String upcSymbol;
* 参数说明如下:
value: 表名这个索引的方向; IndexDirection.ASC(升序),IndexDirection.DESC(降序), IndexDirection.BOTH(两者)
默认为 升序;
name: 被创建的索引的 名称; mongodb默认创建的索引名的格式为(key1_1/-1_key2_1)
unique: 创建一个唯一索引,当创建唯一索引后,当在此字段插入相同的值时将会报错。true:为唯一索引;false:不是唯一索引。
默认为:false
dropDups:此参数表明,当为某个字段创建唯一索引时,删除其他相同值的记录。只保留第一条记录。true:删除重复,
false:不删除重复(当有重复值时唯一索引创建失败);默认为false.
向MongoDB申请创建索引 Datastore.ensureIndexes()需要被调用。这个方法应该在你已经使用Morphia注册了你的实体类后
被调用。他将会异步创建你的所有索引。 这个动作也许会在你每次启动你的应用时都被执行。
注意:当在一个存在的系统上,创建已经存在的索引时,将不会花费任何事件(也不会做任何事情)。
Morphia m = .....
Datastore ds = ....
m.map(Product.class);
ds.ensureIndexes();//为被@Indexed注解的所有字段创建索引。
你可以在 http://www.mongodb.org/display/DOCS/Indexes 了解更多关于MongoDB索引的信息。
*
*
* @Title: 在Mongo数据库中User表的数据结构
* @Description: 实现TODO
* @Copyright:Copyright (c) 2011
* @Company:易程科技股份有限公司
* @Date:2012-2-25
* @author
* @version 1.0
*/
@Entity("User")
public class User extends BaseEntry {
private static final long serialVersionUID = 1L;
@Property
private String email;//邮箱
private String address;//地址
@Property
@Indexed(value=IndexDirection.ASC, name="idx_user_userCode", unique=true, dropDups=true)
private String userCode;//用户编码
@Property("myTaskId")
@Reference(concreteClass = Vector.class)
private List<Task> privateTaskList;
private String name;
private String cardInfo;
@Property
@Indexed(value=IndexDirection.ASC, name="idx_user_telphone", unique=true, dropDups=true)
private String telphone;
@Property("role")
@Reference(concreteClass = Vector.class)
private List<Role> roleList;
private String firstAlphabet;
private String langType;
@Property("userCollection")
@Reference(concreteClass = Vector.class)
private List<UserCollection> userCollectionList;
private String avatarURLKey;
@Property("feeds")
@Reference(concreteClass = Vector.class)
private List<Feed> feedList; //用户相关的动态集合
@Property("taskId")
@Reference(concreteClass = Vector.class)
private List<Task> publicTaskList; //用户的相关的公开的业务集合
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<Task> getPrivateTaskList() {
return privateTaskList;
}
public void setPrivateTaskList(List<Task> privateTaskList) {
this.privateTaskList = privateTaskList;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getUserCode() {
return userCode;
}
public void setUserCode(String userCode) {
this.userCode = userCode;
}
public String getCardInfo() {
return cardInfo;
}
public void setCardInfo(String cardInfo) {
this.cardInfo = cardInfo;
}
public String getTelphone() {
return telphone;
}
public void setTelphone(String telphone) {
this.telphone = telphone;
}
public List<Role> getRoleList() {
return roleList;
}
public void setRoleList(List<Role> roleList) {
this.roleList = roleList;
}
public String getFirstAlphabet() {
return firstAlphabet;
}
public void setFirstAlphabet(String firstAlphabet) {
this.firstAlphabet = firstAlphabet;
}
public String getLangType() {
return langType;
}
public void setLangType(String langType) {
this.langType = langType;
}
public List<UserCollection> getUserCollectionList() {
return userCollectionList;
}
public void setUserCollectionList(List<UserCollection> userCollectionList) {
this.userCollectionList = userCollectionList;
}
public String getAvatarURLKey() {
return avatarURLKey;
}
public void setAvatarURLKey(String avatarURLKey) {
this.avatarURLKey = avatarURLKey;
}
public List<Feed> getFeedList() {
return feedList;
}
public void setFeedList(List<Feed> feedList) {
this.feedList = feedList;
}
public List<Task> getPublicTaskList() {
return publicTaskList;
}
public void setPublicTaskList(List<Task> publicTaskList) {
this.publicTaskList = publicTaskList;
}
}
五:@Embedded的用法
package com.easyway.mash5.app.model;
import java.util.List;
import java.util.Vector;
import com.google.code.morphia.annotations.Embedded;
import com.google.code.morphia.annotations.Property;
/**
* @Embedded
* 你可以创建一个类被嵌套在实体类中,在这种情况下我们可以使用@Embedded注解。例如,在Hotel类中 可能会有一个Address。
* Address是Hotel不可分割的一部分,没有ID, 并且不会被存储在分开的collection中。在这种情况下我们可以使用@Embedded注解
*
* Address.
* @Entity
* public class Hotel{
* ...
* @Id
* private ObjectId id;
* @Embedded
* private Address address;
* }
* @Embedded
* publicclass Address{
* }
*正如你所看到的,被@Embedded注解的类没有@Id。 这是因为他们经常被嵌套在其他类中。事实上,被@Embedded注解的类也不允许有@Id
*
*
*
* @Title: TODO
* @Description: 实现TODO
* @Copyright:Copyright (c) 2011
* @Company:易程科技股份有限公司
* @Date:2012-3-1
* @author
* @version 1.0
*/
@Embedded
public class BO {
@Property("Name")
private String name;
@Property
private String description;
@Embedded(concreteClass = Vector.class)
private List<Field> fields;
public BO() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<Field> getFields() {
return fields;
}
public void setFields(List<Field> fields) {
this.fields = fields;
}
}
页:
[1]