如何创建查询数据库的自定义 writer/reader?
How to create a custom writer/reader that queries the DB?
我有一个classSong
和一个classAlbum
。我的目标是拥有两个单独的集合并通过 BSONObjectID
在数据库中保留引用,但在我的代码中我想将这些 ID 映射到它们各自的实体。
这是我当前的模型:
case class Song(var _id: Option[BSONObjectID] = None,
name: String,
albumId: BSONObjectID,
var created: Option[DateTime] = None,
var updated: Option[DateTime] = None
)
我想用 album
替换 albumId
:
这是我当前的模型:
case class Song(var _id: Option[BSONObjectID] = None,
name: String,
album: Album,
var created: Option[DateTime] = None,
var updated: Option[DateTime] = None
)
如 documentation 所述,我必须为此创建自定义 writer/reader。但是,我的问题是我不知道如何在我的自定义 reader/writer 数据库中查询,以便检索所有必要的字段来实例化我的 Album
实例。这是它应该如何工作的吗?正在模型中查询数据库?
object Song {
import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._
import reactivemongo.play.json.BSONFormats.BSONObjectIDFormat
implicit val songReads: Reads[Song] = (
(__ \ "_id").readNullable[BSONObjectID].map(_.getOrElse(BSONObjectID.generate)).map(Some(_)) and
(__ \ "album").read[BSONObjectID].map(x => Album(_id = Option(_), ...)) and // ???
(__ \ "created").readNullable[DateTime].map(_.getOrElse(new DateTime())).map(Some(_)) and
(__ \ "updated").readNullable[DateTime].map(_.getOrElse(new DateTime())).map(Some(_))
) (Song.apply _)
implicit val songWrites: OWrites[Song] = (
(__ \ "_id").writeNullable[BSONObjectID] and
(__ \ "album").write[BSONObjectID] and // ???
(__ \ "created").writeNullable[DateTime] and
(__ \ "updated").writeNullable[DateTime]
) (unlift(Song.unapply))
}
正如有人讨论的那样,ReactiveMongo 中的 BSONHandlers 负责序列化/反序列化单个对象,而不是管理对象关系。
管理关系与序列化关系不大,您需要编写一个单独的层来处理它。
def loadSong(songName:String) : Future[Song] = // query coll 1 then query coll2 then build Song object
我有一个classSong
和一个classAlbum
。我的目标是拥有两个单独的集合并通过 BSONObjectID
在数据库中保留引用,但在我的代码中我想将这些 ID 映射到它们各自的实体。
这是我当前的模型:
case class Song(var _id: Option[BSONObjectID] = None,
name: String,
albumId: BSONObjectID,
var created: Option[DateTime] = None,
var updated: Option[DateTime] = None
)
我想用 album
替换 albumId
:
这是我当前的模型:
case class Song(var _id: Option[BSONObjectID] = None,
name: String,
album: Album,
var created: Option[DateTime] = None,
var updated: Option[DateTime] = None
)
如 documentation 所述,我必须为此创建自定义 writer/reader。但是,我的问题是我不知道如何在我的自定义 reader/writer 数据库中查询,以便检索所有必要的字段来实例化我的 Album
实例。这是它应该如何工作的吗?正在模型中查询数据库?
object Song {
import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._
import reactivemongo.play.json.BSONFormats.BSONObjectIDFormat
implicit val songReads: Reads[Song] = (
(__ \ "_id").readNullable[BSONObjectID].map(_.getOrElse(BSONObjectID.generate)).map(Some(_)) and
(__ \ "album").read[BSONObjectID].map(x => Album(_id = Option(_), ...)) and // ???
(__ \ "created").readNullable[DateTime].map(_.getOrElse(new DateTime())).map(Some(_)) and
(__ \ "updated").readNullable[DateTime].map(_.getOrElse(new DateTime())).map(Some(_))
) (Song.apply _)
implicit val songWrites: OWrites[Song] = (
(__ \ "_id").writeNullable[BSONObjectID] and
(__ \ "album").write[BSONObjectID] and // ???
(__ \ "created").writeNullable[DateTime] and
(__ \ "updated").writeNullable[DateTime]
) (unlift(Song.unapply))
}
正如有人讨论的那样,ReactiveMongo 中的 BSONHandlers 负责序列化/反序列化单个对象,而不是管理对象关系。
管理关系与序列化关系不大,您需要编写一个单独的层来处理它。
def loadSong(songName:String) : Future[Song] = // query coll 1 then query coll2 then build Song object