Morphia注解

来源:互联网 发布:破解版阅读软件 编辑:程序博客网 时间:2024/06/05 09:02

官方 Java 驱动程序可用于与 MongoDB 交互。该驱动程序提供 Map 的实现 BasicDBObject,用于在数据存储中表示文档。虽然Map 表示法很方便,尤其是在读对 JSON 序列化和反序列化时,但是能够将文档表示为 Java 类层次也具有其优点。例如,反复从 Java 域模型映射文档,允许您在 Java 层上强行执行类型安全,同时通过 MongoDB 享受无模式(schema)开发的好处。

Morphia 是基于 Apache 许可证的 Google Code 项目,让您在 MongoDB 上持久保存、检索、删除和查询作为文档存储的 POJO。通过提供一系列围绕 Mongo Java 驱动程序的注释和包装程序,Morphia 完成了这些操作。Morphia 概念上类似于对象关系映射器(ORM),如 Java Persistence API (JPA) 或 Java 数据对象(Java Data Objects,JDO)实现。

注释域模型

@DB("base")@Entity(value = "params", noClassnameStored=true)public class SysParams implements SimpleBean{    @Id    private String paramId;    private String paramName;
    @Reference(lazy = true)    private List<District> districts;
    @Embedded    private Location loc;
public static class Dao extends MorphiaDao<SysParams>{ public Dao(){ super(SysParams.class); } }}
说明:

1、@DB

@DB("base")
@DB指定使用哪个数据库,数据库名称是在配置文件中的其中一个

db.instances=mysql,base,ads
这里是base数据库。

2、@Entity

@Entity(value = "params",noClassnameStored=true)

@Entity 注释是必需的。其声明了在专用MongoDB集合上该类作为文档将持久保存。在默认情况下,Morphia使用类名称来命名集合。

value 注释MongoDB集合名称。

noClassNameStored:

使用morphia保存持久化对象:

创建 Band 实例:

Band band = new Band();band.setName("Love Burger");band.getMembers().add("Jim");band.getMembers().add("Joe");band.getMembers().add("Frank");band.getMembers().add("Tom");band.setGenre("Rock");
拥有了 Band 实例,可以使用 datastore 来持久保存它:
datastore.save(band);
band 现在应该保存在 bandmanager 数据库中被称为 bands 的集合中。通过使用 Mongo 命令行界面客户端,可以查看一下以便确保:
> db.bands.find();{ "_id" : ObjectId("4cf7cbf9e4b3ae2526d72587"), "className" : "com.bandmanager.model.Band", "name" : "Love Burger", "genre" : "Rock", "members" : [ "Jim", "Joe", "Frank", "Tom" ] }
看上面数据,Band对象的所有字段都正常保存到集合中了,但是集合中多了一个className。
Morphia 自动创建此字段以便记录 MongoDB 中的对象类型。其主要用于确定在编译时不必知道的对象类型(例如,在您从具有混合类型的集合中加载对象时)。

如果这个困扰了您且您知道您不需要该功能,那么通过将 noClassnameStored 值添加到 @Entity 注释,您可以禁用持久保存className

@Entity(value = "params",noClassnameStored=true)
3、@ID

@Id 注释指示 Morphia 哪个字段用作文档 ID。如果您试图持久保存对象(其 @Id 注释的字段为 null),则 Morphia 会为您自动生成 ID 值。

id 可以时ObjectId,也可以时String类型。

4、没有注解的字段

Morphia 试图持久保存每一个它遇到的没有注释的字段,除非它们标有 @Transient 注释。例如,在文档中 namegenre 属性将被保存为string,并具有namegenre 键。

5、@Embedded

使用此注解说明成员对象将被视为嵌入的(embedded)。它会显示为集合中父文档的子集。

注释说明Morphia将此对象实例嵌入到另一个对象中去。而不单独的放到一个MongoDB集合。

例如,在持久保存时,members List 看上去如下所示:

"members" : [ "Jim", "Joe", "Frank", "Tom"]
同时,在类名上加该注解,表示该类是嵌入的:

@Embeddedpublic class Location {    private String lat;    private String lng;}
6、@Reference

@Reference 注释说明对象是对另外一个集合中的文档的引用。在从 MongoDB集合中加载对象时,Morphia遵循着这些引用来建立对象关系。
使用 @Reference 注释说明对象是对另外一个集合中的文档的引用。在从 Mongo 集合中加载对象时,Morphia 遵循着这些引用来建立对象图。例如,在持久保存的文档中,distributor 属性看起来如下所示:

"distributor" : { "$ref" : "distributors", "$id" : ObjectId("4cf7ba6fd8d6daa68a510e8b") }
这是MongoDB的DBRef应用。

@Reference("catalog") List<Song> songs = new ArrayList<Song>();
正如@Embedded 注释一样,@Reference 可以采用一个值来覆盖默认命名。

@Reference有lazy属性,默认为false,当为false时,会自动加载关联的数据,跟hibernate类似。理论上Reference会引发死循环,最简单的业务模式,就是好友业务,用户A通过Reference加载关联的好友B,B通过Reference加载关联的好友A,就形成了死循环。因此在确定类似这样的业务或者业务复杂到开发人员不能掌控时,非常有必要把lazy=true。如果形成死循环,会造成链接池耗尽,请求被阻塞,占用较多的cpu,整个应用变的极慢。因此强列建议慎用@Reference,如果要用,一定要搞清楚业务,在没必要实时加载引用数据的情况下,务必加上lazy=true。
7、@Property

类属性标记@ Property注释,表明为此属性在MongoDB数据库取一个别名。

8、@Transient

类属性标记@Transient注释则表明这个字段将不被持久化到数据库。

9、下面代码是一个内部类:
public static class Dao extends MorphiaDao<SysParams>{    public Dao(){        super(SysParams.class);    }}
下面是使用方法:

public class SysParamsServiceImpl extends BaseService implements SysParamsService {    @Inject    private SysParams.Dao sysParamsDao;    public SysParams getSysParamsById(String paramId) {        return sysParamsDao.findById(paramId);    }}

索引

类属性标记@Indexed注释,表明为此属性增加索引。

您将注意到随着您的集合增长查询性能将会降低。Mongo 集合(非常像关系数据库表)需要正确进行索引以便确保合理的查询性能。

通过 @Indexed 注释对属性进行注释会对该字段应用索引。这里,我对 Bandgenre 属性创建了一个名为genreName 的升序索引:

@Indexed(value = IndexDirection.ASC, name = "genreName")String genre;
索引还可用于避免将重复项插入到集合中。例如,通过在 band 名称的 @Indexed 注释上设置unique 属性,我可以确保在该集合中只有一个具有给定名称的band
@Indexed(value = IndexDirection.ASC, name = "bandName", unique = true)String name;
随后同名的 band 将被丢弃。