EntityModel , a mechanism that determines the way of working with bins. The main incentive, for me personally, is to use the Collections API, this is the ability to work with completely clean, familiar data-class bins. Let's look at how to transfer the code from the previous article to this framework.Serializable interface. Everything is standard here, we want in-memory fields - we add the @Transient annotation to them. Anything not marked as @Transient will be serialized.Comparable interface as a key. Here the principle is the same: the selection will be sorted by keys. data class CustomerDBO( val id: String, val email: String, val country: String, val city: String, var balance: Long ) data class CustomerKey( val id: String ): Serializable data class CustomerData( val email: String, val country: String, val city: String, val balance: Long ): Serializable EnvironmentConfig , since it doesn’t differ in any way from the configuration for DPL. Differences begin immediately after them.Environment and wrap it in ClassCatalog . We can say that in Berkeley databases have about the same essence as tables in SQL. An example under a cat. private val databaseConfig by lazy { DatabaseConfig().apply { transactional = true allowCreate = true } } private val catalog by lazy { StoredClassCatalog(environment.openDatabase(null, STORAGE_CLASS_CATALOG, databaseConfig)) } val customersDatabase by lazy { environment.openDatabase(null, STORAGE_CUSTOMERS, databaseConfig) } Database itself has a very bad low-level API. Such adapters are the StoredSortedMap and StoredValueSet . It is most convenient to use the first one as an immobile point of contact with the database, and the second one is mutable. private val view = StoredSortedMap<CustomerKey, CustomerData>( customersDatabase, customerKeyBinding, customerDataBinding, false ) private val accessor = StoredValueSet<CustomerDBO>( customersDatabase, customerBinding, true ) (key, data) -> (dbo) and dbo -> (key, data) done. In order for the mapping to work, you need to implement one more mechanism for each of the bins — the binding. The interface is extremely simple - two methods, for mapping into data and into a key, and one into essence. class CustomerBinding( catalog: ClassCatalog ): SerialSerialBinding<CustomerKey, CustomerData, CustomerDBO>(catalog, CustomerKey::class.java, CustomerData::class.java) { override fun entryToObject(key: CustomerKey, data: CustomerData): CustomerDBO = CustomerDBO( id = key.id, email = data.email, country = data.country, city = data.city, balance = data.balance ) override fun objectToData(dbo: CustomerDBO): CustomerData = CustomerData( email = dbo.email, country = dbo.country, city = dbo.city, balance = dbo.balance ) override fun objectToKey(dbo: CustomerDBO): CustomerKey = CustomerKey( id = dbo.id ) } iterator these collections will be a copy of the current state, and will not change when the collection changes, while the collections themselves are mutable. Thus, the only thing that a programmer should think about is monitoring the relevance of the data.SecondaryDatabase , which will provide access to some entities by the key of others. An important note is the need to set the value of sortedDuplicates in DatabaseConfig to true if the link is not 1: 1 or 1: M. This action is quite logical, based on the fact that indexing will occur via a foreign key, and several entities will correspond to one key. val ordersByCustomerIdDatabase by lazy { environment.openSecondaryDatabase(null, STORAGE_ORDERS_BY_CUSTOMER_ID, ordersDatabase, SecondaryConfig().apply { transactional = true allowCreate = true sortedDuplicates = true keyCreator = OrderByCustomerKeyCreator(catalog = catalog) foreignKeyDatabase = customersDatabase foreignKeyDeleteAction = ForeignKeyDeleteAction.CASCADE }) } SecondaryKeyCreator , or SecondaryMultiKeyCreator interface (there are also more specific options, but it suffices to implement one of these two). class OrderByCustomerKeyCreator( catalog: ClassCatalog ): SerialSerialKeyCreator<OrderKey, OrderData, CustomerKey>(catalog, OrderKey::class.java, OrderData::class.java, CustomerKey::class.java) { override fun createSecondaryKey(key: OrderKey, data: OrderData): CustomerKey = CustomerKey( id = data.customerId ) } private val byCustomerKeyView = StoredSortedMap<CustomerKey, OrderData>( database.ordersByCustomerIdDatabase, database.customerKeyBinding, database.orderDataBinding, false ) Source: https://habr.com/ru/post/337024/
All Articles