morphia进阶

注解原始和级别类型的属性    

                 保存原始和基本类型的属性到Mongo中,你不必为他们添加任何注解:            

...  
private int myInt;  
private Date myDate;  
private List<String> myStrings;  
private String[] stringArray;  

  默认情况下,Morphia将会试着映射所有支持的基本和原始类型到Mongo,包括这些类型的数组。

 

          MongoDB仅仅有一下数据类型:

 

  • Integer(32位有符号值)
  • Long(64有符号值)  
  • Double(64位IEEE745浮点值)
  • String (字符串)               

 

      这里有些有价值的转换:

 

  • float → double
  • byte →  int
  • short →  int
  • char →  String        

 

    并且,依赖于你的模型中存在的类型和数据库将会试着自动为你转换。我的意思是,因为在MongoDB数据库中只存在三种数字类型(32/64有符号, 64位FP)这将相当

  容易转换。下面的列表为当前什么样的基本和原始类型可以被保存:

 

  • enum(在Mongo中作为String保存)
  • java.util.Date(在Mongo中保存为从新纪元UTC的毫秒数)
  • java.util.Locale(作为字符串保存)
  • com.mongodb.DBRef
  • com.mongodb.ObjectId                   

 

   正如我我们上面的例子所示,Morphia还支持java.util.List, java.util.Set和java.util.Map容器, 和任何支持的原始类型的数组。

    如果你想把一个属性排除映射到Mongo中, 你可以使用@Transient注解

import com.google.code.morphia.annotations.Transient;  
...  
@Transient private int myTransientInt; 

默认情况下,Morphia把属性名作为Mongo中的字段名。这个可以通过@Property注解进行修改,指定一个名称。

import com.google.code.morphia.annotations.Property;  
...  
@Property("my_integer")  
private int myInt;   //在MongoDB中为my_integer  

User Collections(使用容器)

Morphia 支持容器(List, Set, Map) 和数组(Integer)

  
private Set<String> tags;  
  
private Map<String,Translation> translations;  
  
@Reference  
private List<Article> relatedArticles;  

   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;  

映射对象

 Create a Morphia instance(创建一个Morphia实例)
首先你要做的就是创建一个Morphia实例,并且告诉他你要映射的类。建议你仅创建一次Morphia实例,重复使用。映射的任何一个类都将会进行验证,如果由于某些原因你映射的类不合法将会抛出一个MappingException异常

import com.google.code.morphia.Morphia;  
...  
Morphia morphia = new Morphia();  
morphia.map(BlogEntry.class)  
             .map(Author.class);  
...  

 指定Morphia去扫描一个包,映射包中的所有类。

morphia.mapPackage("my.package.with.only.mongo.entities");  

 Mapping a java for Persistence

         保存一个实例对象到Mongo数据库中的一个容器中。调用Morphia中的toDBObject()方法,把java对象传入。

         我们可以把返回的DBObject对象直接保存到Mongo中。

// map the blog entry to a Mongo DBObject  
DBObject blogEntryDbObj = morphia.toDBObject(blogEntry);  
  
// and then save that DBObject in a Mongo collection  
db.getCollection("BlogEntries").save(blogEntryDbObj);  

Retrieving a java from MongoDB(从Mongo中回复一个Java对象)

        从Mongo数据库中的一个文档创建一个Java对象。调用Morphia中的fromDBObject()方法即可,传入要返回的DBObject对象。

// load the DBObject from a Mongo collection  
BasicDBObject blogEntryDbObj = (BasicDBObject) db.getCollection("BlogEntries")  
                          .findOne(new BasicDBObject("_id", new ObjectId(blogEntryId));  
  
// and then map it to our BlogEntry object  
BlogEntry blogEntry = morphia.fromDBObject(BlogEntry.class, blogEntryDbObj);  

使用Morphia管理Mongdo中的Java对象的非常清楚的方法是使用DAO 支持。DAO包含了操作Mongo和Morphia的抽象方法,所以业务逻辑不用依赖Morphia。

接口使用

          当我们从mongodb恢复一个对象时,如果它是一个接口,我们怎么知道它由哪个实现类实现的呢?
Morphia通过在Mongo的文档中保存一个叫“className”的属性,这个属性值对应的是java对象的一个类全名。我们必须将接口的所有实现类全部映射到Morphia实例中。

Morphia morphia = new Morphia();  
    morphia.map(Circle.class)  
           .map(Rectangle.class)  
           .map(ShapeShifter.class);  

容器可以保存为一个嵌套集合:

ublic class ShapeContainer {  
    @Embedded  
    private List<Shape> shapes;  
    ...  
}  

或者保存为一个应用集合:

public class ShapeContainer {  
    @Reference  
    private List<Shape> shapes;  
    ...  
}  

使用DAO
       DAO封装了存储和调用的代码,控制类只要注入一个DAO对象,使用它就不需要关心数据持久化和恢复了。
       Morphia基于DAO接口提供了BasicDAO实现类,它使用Datastore对象来存储和查询POJO对象,可以通过BasicDAO的方法来create/update, read, and delete 对象,可以参考它提供的例子和模式。
意味着你的DAO类只要继承BasicDAO,只需要写一个普通的查询方法,就能查询你自己的对象。

public class BlogEntryDAO extends BasicDAO<BlogEntry, ObjectId> {  
    public BlogEntryDAO( Morphia morphia, Mongo mongo ) {  
        super(mongo, morphia, "myBlogDb");  
    }  
}  

所有的方法都为我们实现了,我们只需做两件重要的事:
     写一个构造器,构造器将信息传递给DAO的父类;
     写查询方法。

BlogEntryDAO blogEntryDAO = new BlogEntryDAO(...);  
// get one specific blog entry  
ObjectId  blogEntryId = ...;  
BlogEntry myBlogEntry = blogEntryDAO.get(blogEntryId);  
// update it  
myBlogEntry.setTitle("My Blog Entry");  
blogEntryDAO.save(myBlogEntry);  
// or just delete it  
blogEntryDAO.deleteById(myBlogEntry.getId());  

控制类中的DAO可能由依赖注入框架注入,所以不需要关心细节。

自定义查询方法:

public List<BlogEntry> findByTitle( String title ) {  
    Pattern regExp = Pattern.compile(title + ".*", Pattern.CASE_INSENSITIVE);  
    return ds.find(entityClazz).filter("title", regExp).sort("title").asList();  
}  

Validation  验证
Morphia使用JSR303验证注释

在应用启动或者创建Morphia对象的时候,调用

new ValidationExtension(morphia); 

 

posted @ 2015-07-28 13:23  偷月光的贼  阅读(2702)  评论(0编辑  收藏  举报