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