Словари

Связи
  • jandcode.core.dbm.dict.Dict (class)
  • jandcode.core.dbm.dict.DictService (class)

Введение

Словарь - это объект 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 - для словарей, которые могут быть полностью загруженными

Примеры:

jandcode.core.dbm.dict.BaseDictHandlerResolve
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}")
        }
    }

}
jandcode.core.dbm.dict.BaseDictHandlerLoadable
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)
Note

Из кеша возвращаются оригинальные общие данные и разделяются между потоками, поэтому их нельзя модифицировать!

Словарь с данными из конфигурации

Имеются словари, чьи данные фиксированы и могут быть загружены из конфигурации. Для поддержки таких словарей имеется специальный обработчик словаря 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 - данные словаря. Каждый дочерний узел - строка в словаре. Атрибуты узла - значения полей строки