This commit is contained in:
tursom 2020-02-19 05:05:17 +08:00
parent 79ed71efae
commit 61e221857c
2 changed files with 64 additions and 20 deletions

View File

@ -1,5 +1,6 @@
package cn.tursom.mongodb package cn.tursom.mongodb
import cn.tursom.core.isStatic
import cn.tursom.core.isTransient import cn.tursom.core.isTransient
import cn.tursom.mongodb.annotation.Ignore import cn.tursom.mongodb.annotation.Ignore
import com.mongodb.client.MongoCollection import com.mongodb.client.MongoCollection
@ -14,25 +15,22 @@ import kotlin.reflect.KProperty1
@Suppress("MemberVisibilityCanBePrivate", "CanBeParameter", "unused") @Suppress("MemberVisibilityCanBePrivate", "CanBeParameter", "unused")
class MongoOperator<T : Any>( class MongoOperator<T : Any>(
val collection: MongoCollection<T>, val collection: MongoCollection<Document>,
val clazz: Class<T> val clazz: Class<T>
) { ) {
constructor(clazz: Class<T>, database: MongoDatabase) : this(database.getCollection(MongoUtil.collectionName(clazz), clazz), clazz) constructor(clazz: Class<T>, database: MongoDatabase) : this(database.getCollection(MongoUtil.collectionName(clazz)), clazz)
private val fields = clazz.declaredFields.filter { private val fields = clazz.declaredFields.filter {
it.isAccessible = true it.isAccessible = true
!it.isTransient() && it.getAnnotation(Ignore::class.java) == null !it.isStatic() && !it.isTransient() && it.getAnnotation(Ignore::class.java) == null
} }
fun save(entity: T, options: InsertOneOptions = InsertOneOptions()) { fun save(entity: T, options: InsertOneOptions = InsertOneOptions()) {
collection.insertOne(entity, options) collection.insertOne(convertToBson(entity), options)
} }
fun save(entities: Collection<T>, options: InsertManyOptions = InsertManyOptions()) { fun save(entities: Collection<T>, options: InsertManyOptions = InsertManyOptions()) {
collection.insertMany(when (entities) { collection.insertMany(entities.map { convertToBson(it) }, options)
is List<T> -> entities
else -> entities.toList()
}, options)
} }
fun update(update: Bson, where: Bson, options: UpdateOptions = UpdateOptions()): UpdateResult { fun update(update: Bson, where: Bson, options: UpdateOptions = UpdateOptions()): UpdateResult {
@ -64,11 +62,11 @@ class MongoOperator<T : Any>(
return add(field, 1, where) return add(field, 1, where)
} }
private fun convertToBson(entity: Any): Bson { private fun convertToBson(entity: Any): Document {
System.err.println(entity)
val bson = Document() val bson = Document()
fields.forEach { fields.forEach {
val value = it.get(entity) ?: return@forEach MongoUtil.injectValue(bson, it.get(entity) ?: return@forEach, it)
bson[MongoUtil.fieldName(it)] = value
} }
return bson return bson
} }

View File

@ -1,8 +1,10 @@
package cn.tursom.mongodb package cn.tursom.mongodb
import cn.tursom.core.isStatic
import cn.tursom.core.isTransient import cn.tursom.core.isTransient
import cn.tursom.mongodb.annotation.Collection import cn.tursom.mongodb.annotation.Collection
import cn.tursom.mongodb.annotation.Ignore import cn.tursom.mongodb.annotation.Ignore
import org.bson.BsonValue
import org.bson.Document import org.bson.Document
import org.bson.conversions.Bson import org.bson.conversions.Bson
import java.lang.reflect.Field import java.lang.reflect.Field
@ -25,15 +27,59 @@ object MongoUtil {
?: property.name ?: property.name
} }
fun convertToBson(entity: Any): Bson { fun convertToBson(entity: Any): Document {
return when (entity) {
is Map<*, *> -> entity.convert()
else -> {
val bson = Document() val bson = Document()
entity.javaClass.declaredFields.filter { entity.javaClass.declaredFields.filter {
it.isAccessible = true it.isAccessible = true
!it.isTransient() && it.getAnnotation(Ignore::class.java) == null !it.isStatic() && !it.isTransient() && it.getAnnotation(Ignore::class.java) == null
}.forEach { }.forEach {
val value = it.get(entity) ?: return@forEach injectValue(bson, it.get(entity) ?: return@forEach, it)
bson[fieldName(it)] = value
} }
return bson bson
}
}
}
fun injectValue(bson: Document, value: Any, field: Field) {
when (value) {
is Pair<*, *> -> bson[value.first?.toString() ?: return] = convertToBson(value.second ?: return)
is Map.Entry<*, *> -> bson[value.key?.toString() ?: return] =
convertToBson(value.value ?: return)
else -> bson[fieldName(field)] = value.convert() ?: return
}
}
private fun Iterator<*>.convert(): List<*> {
val list = ArrayList<Any?>()
forEach {
list.add(it.convert() ?: return@forEach)
}
return list
}
private fun Map<*, *>.convert(): Document {
val doc = Document()
forEach { any, u ->
any ?: return@forEach
doc[any.toString()] = u.convert() ?: return@forEach
}
return doc
}
private fun Any?.convert() = when (this) {
null -> null
is Enum<*> -> name
is Boolean -> this
is Number -> this
is String -> this
is Bson -> this
is BsonValue -> this
is Map<*, *> -> this.convert()
is Iterator<*> -> this.convert()
is Iterable<*> -> this.iterator().convert()
else -> convertToBson(this)
} }
} }