Mongodb 的ORM框架 Morphia之注解


@Entity("bands")
public class Band {
 
    @Id
    ObjectId id;
 
    String name;
 
    String genre;
 
    @Reference
    Distributor distributor;
 
    @Reference("catalog")
    List<Song> songs = new ArrayList<Song>();
 
    @Embedded
    List<String> members = new ArrayList<String>();
 
    @Embedded("info")
    ContactInfo info;
@Entity("songs")
public class Song {
 
    @Id
    ObjectId id;
 
    String name;
}
@Entity("distributors")
public class Distributor {

    @Id
    ObjectId id;
    String name;
}

 

@Entity

注釋是必需的。其聲明了在專用MongoDB集合上該類作為文檔將持久保存。在默認情況下,Morphia使用類名稱來命名集合。

可以使用value 注釋MongoDB集合名稱,設置noClassNameStored為true,

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

@ID

@Id 注釋指示 Morphia 哪個字段用作文檔 ID。如果您試圖持久保存對象(其 @Id 注釋的字段為 null),則 Morphia 會為您自動生成 ID 值。

id 可以時ObjectId,也可以時String類型。

 @Transient

類屬性標記@Transient注釋則表明這個字段將不被持久化到數據庫。

Morphia 試圖持久保存每一個它遇到的沒有注釋的字段,除非它們標有 @Transient 注釋,才會不保存到數據庫中。

沒有任何注解的,就會默認持久化到數據庫中,相當於使用 @Embedded注解,只不過用 @Embedded可以指定別名。

 @Embedded

使用此注解說明成員對象將被視為嵌入的(embedded)。它會顯示為集合中父文檔的子集。

除非注釋有@Transient@Reference,否則默認成員對象將被視為嵌入的(embedded)

@Entity("bands")
public class Band {
 
     @Id
     ObjectId id;
 
     String name;
 
     String genre;
 
     @Reference
     Distributor distributor;
 
     @Reference("catalog")
     List< Song > songs = new ArrayList< Song >();
 
     @Embedded
     List< String > members = new ArrayList< String >();
 
     @Embedded("info")
     ContactInfo info;
}
public class ContactInfo {
 
     public ContactInfo() {
     }
 
     String city;
 
     String phoneNumber;
}
執行如下代碼:
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");
datastore.save(band);

 

 members List 看上去如下所示

"members" : [ "Jim", "Joe", "Frank", "Tom"]

info 屬性是另外一個嵌入的對象。在本例中,我通過 info 值明確地設置 @Embedded 注釋。這會覆蓋文檔中子集的默認命名,否則就會被稱為 contactInfo。例如:

"info" : { "city" : "Brooklyn", "phoneNumber" : "718-555-5555" }

查詢結果:

> db.bands.find();
{ "_id" : ObjectId("4cf7cbf9e4b3ae2526d72587"), "className" :
"com.bandmanager.model.Band", "name" : "Love Burger", "genre" : "Rock",
"members" : [ "Jim", "Joe", "Frank", "Tom" ] }
 
可以看到:ContactInfo 類缺少 @Entity 注釋。這是故意而為的,因為我不需要 ContactInfo 的專用集合。它實例總是被嵌入 band 文檔。
再舉一個@Embedded注解的例子
@Entity(value = "MCH_Community_Clew", noClassnameStored = true)
public class CommunityClew extends MongoBaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;
    private long id;//id
    private String mobile; 
    private String community;//社區
    private String status;
    private Date createTime;//加入時間
    private Date modifyTime;//修改時間
    private String modifyUser;//修改人
    private String remark; //記錄最新一次備注
}
public class CommunityClewRecord extends MongoBaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    private long id;//id
    private long fatherId;
    private String beforeStatus;//之前狀態
    private String status;//當前狀態
    private String remark;//備注
    private Date modifyTime;//時間
    private String modifyUser;//修改人
@Embedded("records")
private List<CommunityClewRecord> communityClewRecords;

}
CommunityClewRecord record=new CommunityClewRecord(1, 1, "測試", status, remark,now,user);
CommunityClew clew=new CommunityClew();
clew.setId(communityClewMongo.getMaxId()+1);
clew.setCommunity(community);
clew.setMobile(mobile);
clew.setCreateTime(new Date());
clew.setStatus("待溝通");
clew.setCommunityClewRecords(record);
communityClewMongo.insert(clew);

 

對CommunityClew的communityClewRecords列表添加兩條CommunityClewRecord記錄,查詢monggo標,結果如下:

 

@Reference

@Reference 注釋說明對象是對另外一個集合中的文檔的引用。在從 MongoDB集合中加載對象時,Morphia遵循着這些引用來建立對象關系。即引用的字段會根據內部建立的關系圖,自動加載。

這就要求被引用的對象先保存,然后再把被對象賦值給引用的字段,包含引用字段的對象再保存。

如:

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");
datastore.save(band); //持久化

查詢:
> db.bands.find();
{ "_id" : ObjectId("4cf7cbf9e4b3ae2526d72587"), "className" :
"com.bandmanager.model.Band", "name" : "Love Burger", "genre" : "Rock",
"members" : [ "Jim", "Joe", "Frank", "Tom" ] }
 
對被引用的對象做持久化:
Song song1 = new Song("Stairway");
Song song2 = new Song("Free Bird");
 
datastore.save(song1);
datastore.save(song2);
 
Mongo 中查看 songs 集合,應該看到如下所示:
> db.songs.find();
{ "_id" : ObjectId("4cf7d249c25eae25028ae5be"), "className" :
"com.bandmanager.model.Song", "name" : "Stairway" }
{ "_id" : ObjectId("4cf7d249c25eae25038ae5be"), "className" :
"com. bandmanager.model.Song", "name" : "Free Bird" }
 
 
請注意 Song 還沒有被 band 引用。我將它們添加到 band 並查看發生了什么:
band.getSongs().add(song1);
band.getSongs().add(song2);
datastore.save(band);
查詢 bands 集合時,應該看到 songs 集合被保存為一個被稱為 catalog 的數組,作為兩個 DBRef。因為 @Reference("catalog")起了一個別名,如果不設置括號中的名稱,存儲的引用 catalog 的數組應該是songs。
{ "_id" : ObjectId("4cf7d249c25eae25018ae5be"), "name" : "Love Burger", "genre" : "Rock",
    "catalog" : [
    {
       "$ref" : "songs",
       "$id" : ObjectId("4cf7d249c25eae25028ae5be")
    },
    {
       "$ref" : "songs",
       "$id" : ObjectId("4cf7d249c25eae25038ae5be")
    }
], "members" : [ "Jim", "Joe", "Frank", "Tom"] }
 
再舉一個 @Reference例子:
@Entity(value = "MCH_Community_Clew", noClassnameStored = true)
public class CommunityClew extends MongoBaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;
    private long id;//id
    private String mobile; 
    private String community;//社區
    private String status;
    private Date createTime;//加入時間
    private Date modifyTime;//修改時間
    private String modifyUser;//修改人
    private String remark; //記錄最新一次備注
    @Reference
    private List<CommunityClewRecord> communityClewRecords;
}
@Entity(value = "MCH_Community_Clew_Record", noClassnameStored = true)
public class CommunityClewRecord extends MongoBaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;
    private long id;//id
    private long fatherId;
    private String beforeStatus;//之前狀態
    private String status;//當前狀態
    private String remark;//備注
    private Date modifyTime;//時間
    private String modifyUser;//修改人
}
public boolean saveCommunityClewRecordAndCommunityClew(Map<String, Object> map) {
        long id=MapUtils.getLong(map, "id");
        String status = MapUtils.getString(map,"status");
        String remark = MapUtils.getString(map,"remark");
        String user = MapUtils.getString(map,"user");
        long recordMaxId = communityClewRecordMongo.getMaxId();
        CommunityClew clew = communityClewMongo.queryCommunityClew(id);
        Date now=new Date();
        CommunityClewRecord record=new CommunityClewRecord(recordMaxId+1, clew.getId(), clew.getStatus(), status, remark,now,user);
        communityClewRecordMongo.insert(record);
        return communityClewMongo.saveCommunityClewByUpdate(record,user,id);
    }
MCH_Community_Clew_Record數據

MCH_Community_Clew數據
展開顯示:

 

注意:被引用的對象必須先被保存,然后其他對象才能引用它們。這解釋了為什么我先保存 song1song2,然后將它們添加到 band

 參考文章:

  1. https://www.ibm.com/developerworks/cn/java/j-morphia/ 
  2. https://blog.csdn.net/jsdxshi/article/details/73368937 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM