Я создал таблицу с вашей структурой и заполнил ее образцами данных:
insert into app_category_agg (category, app_count, sp_count, subscriber_count, window_revenue, top_apps)
values('test', 2, 1, 10, 100, [{'t1':1, 't2':2}]);
Для средства отображения объектов из драйвера Java 3 рабочий код выглядит следующим образом.
Объявление класса:
import com.datastax.driver.mapping.MappingManager
import com.datastax.driver.mapping.annotations.Column
import com.datastax.driver.mapping.annotations.PartitionKey
import com.datastax.driver.mapping.annotations.Table
@Table(keyspace = "test", name = "app_category_agg")
class AppCategoryAggData {
@PartitionKey
lateinit var category: String
@Column(name = "app_count")
var appCount: Int = 0
@Column(name = "sp_count")
var spCount: Int = 0
@Column(name = "subscriber_count")
var subscriberCount: Int = 0
@Column(name = "window_revenue")
var windowRevenue: Long = 0
@Column(name = "top_apps")
var topApps: List<Map<String, Int>> = emptyList()
override fun toString(): String {
return "AppCategoryAggData(category='$category', appCount=$appCount, spCount=$spCount, subscriberCount=$subscriberCount, windowRevenue=$windowRevenue, topApps=$topApps)"
}
}
Основная функция — она сначала вставляет данные из кода Kotlin, а потом читает данные, которые я заранее вставил:
import com.datastax.driver.core.Cluster
object KtTestObjMapper {
@JvmStatic
fun main(args: Array<String>) {
val cluster = Cluster.builder()
.addContactPoint("10.101.34.176")
.build()
val session = cluster.connect()
val manager = MappingManager(session)
val mapper = manager.mapper(AppCategoryAggData::class.java)
val appObj = AppCategoryAggData()
appObj.category = "kotlin"
appObj.appCount = 5
appObj.spCount = 10
appObj.subscriberCount = 50
appObj.windowRevenue = 10000
appObj.topApps = listOf(mapOf("t2" to 2))
mapper.save(appObj)
val obj2 = mapper.get("test")
print("obj2=$obj2")
session.close()
cluster.close()
}
}
Когда я запускаю этот код, я получаю следующий вывод:
Object from =AppCategoryAggData(category='test', appCount=2, spCount=1, subscriberCount=10, windowRevenue=100, topApps=[{t1=1, t2=2}])
и когда я выбираю данные из таблицы с помощью cqlsh
, я вижу, что данные были вставлены Kotlin:
cqlsh:test> SELECT * from app_category_agg ;
category | app_count | sp_count | subscriber_count | top_apps | window_revenue
----------+-----------+----------+------------------+----------------------+----------------
test | 2 | 1 | 10 | [{'t1': 1, 't2': 2}] | 100
kotlin | 5 | 10 | 50 | [{'t2': 2}] | 10000
(2 rows)
полный код находится в моем репозитории. Единственным недостатком этого решения является то, что оно основано на драйвере Java 3.x, который является предыдущим основным выпуском драйвера. Если у вас нет строгих требований к этому, рекомендуется использовать последний основной выпуск - 4.x, который работает как с Cassandra, так и с DSE и имеет много новых функций.
Хотя картограф объектов в новой версии работает по-другому - вместо аннотаций времени выполнения используются аннотации компиляции, поэтому код выглядит по-другому, и нам нужно настроить процесс компиляции по-другому и может быть сложнее по сравнению с драйвером 3.x, но сам код может быть проще (полный код здесь).
Нам нужно определить класс данных (сущность):
@Entity
@CqlName("app_category_agg")
data class AppCategoryAggData(
@PartitionKey var category: String,
@CqlName("app_count") var appCount: Int? = null,
@CqlName("sp_count") var spCount: Int? = null,
@CqlName("subscriber_count") var subscriberCount: Int? = null,
@CqlName("window_revenue") var windowRevenue: Long? = null,
@CqlName("top_apps") var topApps: List<Map<String, Int>>? = null
) {
constructor() : this("")
}
Определите интерфейс DAO с помощью двух операций. (insert
и findByCategory
):
@Dao
interface AppCategoryAggDao {
@Insert
fun insert(appCatAgg: AppCategoryAggData)
@Select
fun findByCategory(appCat: String): AppCategoryAggData?
}
Определите Mapper для получения DAO :
@Mapper
interface AppCategoryMapper {
@DaoFactory
fun appCategoryDao(@DaoKeyspace keyspace: CqlIdentifier?): AppCategoryAggDao?
}
И используйте его:
object KtTestObjMapper {
@JvmStatic
fun main(args: Array<String>) {
val session = CqlSession.builder()
.addContactPoint(InetSocketAddress("10.101.34.176", 9042))
.build()
// get mapper - please note that we need to use AppCategoryMapperBuilder
// that is generated by annotation processor
val mapper: AppCategoryMapper = AppCategoryMapperBuilder(session).build()
val dao: AppCategoryAggDao? = mapper.appCategoryDao(CqlIdentifier.fromCql("test"))
val appObj = AppCategoryAggData("kotlin2",
10, 11, 12, 34,
listOf(mapOf("t2" to 2)))
dao?.insert(appObj)
val obj2 = dao?.findByCategory("test")
println("Object from =$obj2")
session.close()
}
}
Отличие по сравнению с Java заключается в том, что нам нужно использовать сгенерированный класс AppCategoryMapperBuilder
для получения экземпляра AppCategoryMapper
в:
val mapper: AppCategoryMapper = AppCategoryMapperBuilder(session).build()
person
Alex Ott
schedule
02.07.2020