Словари
Введение
Словарь - это объект jandcode.core.dbm.dict.Dict
, который содержит соответствие между
неким кодом (id) и его текстовым представлением.
Работа со словарями осуществляется через сервис модели
jandcode.core.dbm.dict.DictService
.
Данные словаря представляют собой табличную структуру типа jandcode.core.store.Store
.
Поле id
- это идентификатор записи (код). Остальные поля - текстовые представления
идентификатора записи.
Сам объект jandcode.core.dbm.dict.Dict
данные не хранит, он содержит информацию о
структуре словаря и способах загрузки данных.
Описание словаря
Словарь описывается в модели. Пример:
<root>
<dbm>
<model name="my-model">
<!-- структура словаря - это домен -->
<domain name="dict.my" parent="dict.base">
<field name="text2" parent="string"/>
</domain>
<!-- словарь -->
<dict name="mydict1" parent="base" domain="dict.my"
handler="pak1.pak2.MyDict1_DictHandler"/>
</model>
</dbm>
</root>
Работа со словарями
Пример:
// получаем сервис словарей
DictService dictSvc = getModel().bean(DictService.class)
// получаем словарь
Dict dict1 = dictSvc.getDict("mydict1")
// загружаем данные словаря полностью, если он загружаемый
// т.е. может сразу загрузить все свои данные
if (dict1.isLoadable()) {
DictData dictdata = dictSvc.loadDictData("mydict1")
}
// загружаем только данные для указанных id
// работает для любых типов словарей
DictData dictdata = dictSvc.loadDictData("mydict1", [1, 2, 6])
// создаем какой-то store
Store store = mdb.createStore()
store.addField("id", "long")
store.addField("data", "string")
// для поля mydict1 устанавливаем связь со словарем
store.addField("mydict1", "long").setDict("mydict1")
// ... как то заполняем store
// для словарных полей ставим соотвествии между id и текстом
dictSvc.resolveDicts(store)
// берем запись из store
StoreRecord rec = store.get(0)
// получаем текст из поля text для id, которое хранится в поле mydict1
String text = rec.getDictText("mydict1")
// получаем текст из поля text2 для id, которое хранится в поле mydict1
String text2 = rec.getDictText("mydict1", "text2")
// создаем пустой store со структурой словаря
Store store1 = dict1.createStore()
// создаем пустой dictdata для словаря
DictData dictdata1 = dict1.createDictData()
Загрузка данных для словаря
Данные для словаря загружаются через его обработчик, которые реализует интерфейс
jandcode.core.dbm.dict.DictHandler
.
При реализации обработчика необходимо для словаря dict загрузить в data строки, которые соответсвуют набору id, переданному в параметре ids. Для загрузки можно использовать объект mdb, соединение с базой данных установлено.
Простейший пример:
import jandcode.core.dbm.dict.*
import jandcode.core.dbm.mdb.*
import jandcode.core.store.*
class MyDict1Handler implements DictHandler {
void resolveIds(Mdb mdb, Dict dict, Store data, Collection ids) throws Exception {
for (id in ids) {
data.add(id: id, text: "${dict.name}-text-${id}")
}
}
}
Полностью загружаемые словари
Существуют словари, данные для которых можно загружать сразу полностью. Это обычно часто
используемые и небольшие словари. Для реализации полной загрузки обработчик должен
дополнительно реализовывать интерфейс
jandcode.core.dbm.dict.IDictHandlerLoadDict
.
В случае полностью загружаемого словаря метод Dict@isLoadable()
возвращает true
.
Простейший пример:
import jandcode.core.dbm.dict.*
import jandcode.core.dbm.mdb.*
import jandcode.core.store.*
class MyDict1LoadDictHandler implements DictHandler, IDictHandlerLoadDict {
void resolveIds(Mdb mdb, Dict dict, Store data, Collection ids) throws Exception {
for (id in ids) {
data.add(id: id, text: "${dict.name}-text-${id}")
}
}
void loadDict(Mdb mdb, Dict dict, Store data) throws Exception {
for (id in 1..10) {
data.add(id: id, text: "${dict.name}-text-${id}")
}
}
}
Базовые классы обработчиков для словаря
Для упрощения разработки имеются 2 базовых класса обработчиков словарей:
jandcode.core.dbm.dict.BaseDictHandlerResolve
- для обычных словарей, которые не могут быть полностью загруженнымиjandcode.core.dbm.dict.BaseDictHandlerLoadable
- для словарей, которые могут быть полностью загруженными
Примеры:
import jandcode.core.dbm.dict.*
import jandcode.core.dbm.mdb.*
import jandcode.core.store.*
class BaseDictHandlerResolveExample1 extends BaseDictHandlerResolve {
BaseDictHandlerResolveExample1() {
// размер блока, который будет передан в метод resolveIdsBlock
// по умолчанию размер блока равен 200
setBlockSize(100)
}
// этот метод загружает блок ids, вызывается несколько раз в зависимости
// от количества нужных ids
protected void resolveIdsBlock(Mdb mdb, Dict dict, Store data, Collection<Object> ids) throws Exception {
for (id in ids) {
data.add(id: id, text: "${dict.name}-text-${id}")
}
}
}
import jandcode.core.dbm.dict.*
import jandcode.core.dbm.mdb.*
import jandcode.core.store.*
class BaseDictHandlerLoadableExample1 extends BaseDictHandlerLoadable {
void loadDict(Mdb mdb, Dict dict, Store data) throws Exception {
for (id in 1..10) {
data.add(id: id, text: "${dict.name}-text-${id}")
}
}
}
Кеширование полностью загружаемых словарей
Данные полностью загружаемых словарей можно кешировать. Для этого нужно получать
данные словаря через DictService#getCache()
.
DictService dictSvc = getModel().bean(DictService.class)
Dict mydict1 = dictSvc.getDict("mydict1")
// получить закешированные данные словаря
DictData dictdata1 = dictSvc.getCache().getDictData(mydict1)
// сбросить кеш для указанного словаря
dictSvc.getCache().invalidate(mydict1)
Из кеша возвращаются оригинальные общие данные и разделяются между потоками, поэтому их нельзя модифицировать!
Словарь с данными из конфигурации
Имеются словари, чьи данные фиксированы и могут быть загружены из конфигурации.
Для поддержки таких словарей имеется специальный обработчик словаря
jandcode.core.dbm.dict.std.ConfDictHandler
. Он загружает данные словаря из
узла конфигурации словаря dictdata
.
Пример:
<root>
<dbm>
<model name="my-model">
<dict name="memdict1" parent="base"
handler="jandcode.core.dbm.dict.std.ConfDictHandler">
<dictdata>
<i id="1" text="YES"/>
<i id="2" text="NO"/>
</dictdata>
</dict>
</model>
</dbm>
</root>
Конфигурация module.cfx
dbm/model/dict
Описание словаря.
Формат:
<root>
<dbm>
<model name="MODEL-NAME">
<dict name="DICT-NAME"
parent="DICT-NAME"
domain="DOMAIN-NAME"
defaultField="FIELD-NAME"
handler="jandcode.core.dbm.dict.DictHandler"
/>
</model>
</dbm>
</root>
name
- имя словаряparent
- имя предка словаряdomain
- имя домена со структурой словаря. По умолчанию -dict.base
defaultField
- имя поля по умолчанию для получения текстового представления. По умолчанию -text
handler
- обработчик словаря для загрузки данных. Должен реализовывать интерфейсjandcode.core.dbm.dict.DictHandler
. Дополнительно может реализовывать интерфейсjandcode.core.dbm.dict.IDictHandlerLoadDict
dbm/model/dict/dictdata
Данные словаря для обработчика jandcode.core.dbm.dict.std.ConfDictHandler
.
Формат:
<root>
<dbm>
<model name="MODEL-NAME">
<dict name="DICT-NAME"
handler="jandcode.core.dbm.dict.std.ConfDictHandler">
<dictdata>
<i id="VALUE1" anyfield1="VALUE2"/>
<i id="VALUE2" anyfield1="VALUE2"/>
...
</dictdata>
</dict>
</model>
</dbm>
</root>
handler
- должен быть классомjandcode.core.dbm.dict.std.ConfDictHandler
или совместимым с ним по интерпретации конфигурацииdictdata
- данные словаря. Каждый дочерний узел - строка в словаре. Атрибуты узла - значения полей строки