本文是针对 MongoDB Java 驱动程序版本
4.2.0-beta
编写的。
想象一下我有一个像这样设置的 Mongo 数据库:
private val codecRegistry = fromRegistries(
MongoClientSettings.getDefaultCodecRegistry,
fromProviders(
PojoCodecProvider.builder()
.automatic(true)
.build()
));
private val client = MongoClients.create(Server.Config.mongoDbConnectionString)
private val database = client.getDatabase("myDatabase").withCodecRegistry(codecRegistry)
到目前为止非常简单。
现在想象一下我有
User.scala
看起来像这样:
case class User(val email: String)
现在,假设我有一个从这样的函数执行的数据库操作:
def CreateUser(document: User): InsertOneResult = {
val collection = database.getCollection("User", classOf[User])
collection.insertOne(document)
}
一切都很好,对吧?嗯,实际上,不......这给了我们一个:
org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class models.User.
原来
POJO
中PojoCodecProvider
的意思很字面意思...
如果我将
User.scala
替换为看起来像这样的 User.java
...
public class User {
public String email;
public String password;
}
不再有投诉!
我知道 Scala
class
/case class
不是 POJO。我的问题是,我该如何克服这个限制?让事情变得更复杂的是,如果我想制作上面给出的 Create
方法的通用版本,就像这样:
def Create[T](document: T)(implicit ctag: ClassTag[T]): InsertOneResult = {
val collection = getCollection[T]()
collection.insertOne(document)
}
我只是S.O.L.吗?除非我所有的数据库存储类都是 Java 类?
好吧,由于我现在找不到更好的解决方法,我将发布有效的方法。
正如@LuisMiguelMejiaSuarez 在他的评论中所说,docs 说要注册每个您需要编解码器的
class
,如下所示:
val codecRegistry = fromRegistries(
fromProviders(
classOf[User],
classOf[MyOtherClass]
),
DEFAULT_CODEC_REGISTRY)
虽然这种种类使我创建通用 CRUD 方法的希望变得复杂,但它仍然比为我希望存储在数据库中的每个类编写自定义编解码器的工作量要少。假设您已将该类注册为编解码器提供程序,则使用通用 CRUD 函数仍然可以使用此方法。
使用宏:
val customCodecs = CodecRegistries.fromProviders( Macros.createCodecProvider[TargetCaseClass] )