1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/l0km-sql2java

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

sql2java

sql2java — это легковесный генератор кода доступа к базе данных SQL (Java), который был переписан на основе одноимённого открытого проекта (https://sourceforge.net/projects/sql2java), работающего за рубежом. Этот ORM-инструмент запускается в виде плагина Maven и успешно протестирован на MySQL, а также применяется в реальных проектах.

  • Генерируемые Java-bean классы таблиц поддерживают аннотации Thrift/Swift и Swagger, что позволяет использовать сгенерированные объекты Java-bean как типы данных для сервисов Thrift/Swift.
  • Поддерживается механизм внутреннего кэширования записей таблиц.
  • Реализован механизм слушателей (listeners) для уведомлений о событиях создания, удаления и изменения записей таблиц.
  • Поддерживается управление транзакциями.
  • Поддерживается автоматическое увеличение ключа (AUTO_INCREMENT).
  • Допускаются пользовательские расширяемые шаблоны (Velocity), позволяющие создавать расширенные части кода.
  • Поддерживается оптимистическая блокировка (optimistic lock).

Структура сгенерированного Java-кода

bean

Пример сгенерированного класса записи данных

bean

Компиляция проекта

Для компиляции требуется JDK 1.7 и версия Maven 3.5 или выше.

# Клонировать исходный код
git clone https://gitee.com/l0km/sql2java.git
cd sql2java 

# Компилировать все
mvn install 
```> SQL2Java-плагин Maven уже размещен в центральном репозитории Maven, поэтому если вам нужна только его запуск, нет необходимости компилировать этот проект.

## Быстрый справочник по использованию
### Создание конфигурационного файла
Создайте самый простой файл конфигурации (mysql2java.properties), чтобы указать sql2java, как следует генерировать Java-код. Символ '#' используется для начала строки-комментария.

```properties
# Указание JDBC-driver для соединения с базой данных
jdbc.driver=com.mysql.jdbc.Driver
# Для MySQL-базы данных, если useInformationSchema=false или не указано, то информация о полях таблиц не будет получена
jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useInformationSchema=true
jdbc.username=root
jdbc.password=
jdbc.schema=test

# Определение пакета для сгенерированного кода
codewriter.package=sql2java.test

Генерация кода

Выполните следующий плагин Maven, чтобы начать чтение структуры таблиц из базы данных и сгенерировать соответствующие Java-классы в текущую директорию (src/main):

$ mvn com.gitee.l0km:sql2java-maven-plugin:generate \
    -Dsql2java.classpath=lib/mysql-connector-java-5.1.43-bin.jar \
    -Dsql2java.propfile=mysql2java.properties
``````text
[INFO] Scanning for projects... 
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- sql2java-maven-plugin:1.0.6-SNAPSHOT:generate (default-cli) @ sql2java-test ---
        Инициализация свойств базы данных
[INFO] classpath: [file:/D:/j/sql2java.test/lib/mysql-connector-java-5.1.43-bin.jar]
Подключение к root на jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useInformationSchema=true...
        Подключено.
        Сервер базы данных: MySQL.
Загрузка списка таблиц в соответствии с шаблоном t_%...
        Найдена таблица t_book
        Найдена таблица t_user
samePrefix = [t_]
Загрузка столбцов...
        t_book.id INT значение по умолчанию: null
        t_book.name VARCHAR значение по умолчанию: null
        t_book.borrower INT значение по умолчанию: null
        t_book найдено 3 столбца
        t_user.id INT AUTO_INCREMENT значение по умолчанию: null
        t_user.name VARCHAR значение по умолчанию: null
        t_user.birthdate DATE значение по умолчанию: null
        t_user.phone VARCHAR значение по умолчанию: null
        t_user.address VARCHAR значение по умолчанию: null
        t_user найдено 5 столбцов
Database::loadPrimaryKeys
Найден первичный ключ (seq,name) (1,id) для таблицы 't_book'
Найден первичный ключ (seq,name) (1,id) для таблицы 't_user'
Загрузка импортированных ключей...
        t_book.id -> t_user.id найдено seq:1 внешний ключ fk_id
        UPDATE_RULE:NO_ACTION DELETE_RULE:RESTRICT
Загрузка индексов...
        Найден интересующий индекс phone_UNIQUE на phone для таблицы t_user
Загрузка процедур...
Создание шаблона /templates/velocity/java5g/perschema/constant.java.vm
... запись в src/main/java/sql2java/test/Constant.java
        java/sql2java/test/Constant.java завершено.
Создание шаблона /templates/velocity/java5g/perschema/database.properties
```vm
 . . .  запись в src/main/resources/conf/database.properties
         resources/conf/database.properties завершена.
 Создание шаблона /templates/velocity/java5g/perschema/gu.sql2java.irowmetadata.vm
 . . .  запись в src/main/resources/META-INF/services/gu.sql2java.IRowMetaData
         resources/META-INF/services/gu.sql2java.IRowMetaData завершена.
 Создание шаблона /templates/velocity/java5g/pertable/bean.java.vm
 . . .  запись в src/main/java/sql2java/test/BookBean.java
         java/sql2java/test/BookBean.java завершена.
 Создание шаблона /templates/velocity/java5g/pertable/manager.interface.java.vm
 ```запись в src/main/java/sql2java/test/IBookManager.java  
     java/sql2java/test/IBookManager.java завершена. 
   Генерация шаблона /templates/velocity/java5g/pertable/metadata.java.vm  
    . . .  запись в src/main/java/sql2java/test/BookMetaData.java  
       java/sql2java/test/BookMetaData.java завершена. 
   Генерация шаблона /templates/velocity/java5g/pertable/bean.java.vm  
    . . .  запись в src/main/java/sql2java/test/UserBean.java  
       java/sql2java/test/UserBean.java завершена. 
   Генерация шаблона /templates/velocity/java5g/pertable/manager.interface.java.vm  
    . . .  запись в src/main/java/sql2java/test/IUserManager.java  
       java/sql2java/test/IUserManager.java завершена. 
   Генерация шаблона /templates/velocity/java5g/pertable/metadata.java.vm  
    . . .  запись в src/main/java/sql2java/test/UserMetaData.java  
       java/sql2java/test/UserMetaData.java завершена. 
   [INFO] ------------------------------------------------------------------------
   [INFO] BUILD SUCCESS
   [INFO] ------------------------------------------------------------------------
   [INFO] Общее время: 1.248 с
   [INFO] Закончено в: 2019-12-16T13:51:20+08:00
   [INFO] Конечная память: 13M/308M
   [INFO] ------------------------------------------------------------------------l0km:sql2java-maven-plugin уже выпущен в центральный Maven-репозиторий, поэтому нет необходимости компилировать этот проект — его можно использовать сразу. В примерах выше версия плагина не указана, поэтому используется самая последняя версия плагина.
   
Параметры:| имя                | описание                                      |
| ------------------ | --------------------------------------------- |
| sql2java.classpath | Указывает путь к JAR-файлу JDBC-driver для подключения к базе данных |
| sql2java.propfile  | Указывает конфигурационный файл, необходимый для генерации кода sql2java |

## Полный пример
См. демонстрационный проект sql2java: [sql2java-example: Пример вызова sql2java (gitee.com)](https://gitee.com/l0km/sql2java-example)
Пользователи могут использовать этот демонстрационный проект как основу для создания своего проекта ORM.

## Пример практического применения
См. открытый проект facelog: [https://gitee.com/l0km/facelog/tree/master/db2](https://gitee.com/l0km/facelog/tree/master/db2 "https://gitee.com/l0km/facelog/tree/master/db2")

## Получение всех параметров
Для управления способом генерации Java-кода, в Sql2Java используется несколько десятков контрольных параметров; большинство из которых по умолчанию не требуют изменения. Если требуется изменение этих параметров, необходимо получить их названия и описание. Для этого можно выполнить команду Maven плагина:

```bash
mvn com.gitee.l0km:sql2java-maven-plugin:help

Выполнение следующей команды Maven плагина создаст файл конфигурации с параметрами по умолчанию, который будет назван my.properties. Вы можете использовать этот файл как основу для своих собственных настроек генерации кода:

mvn com.gitee.l0km:sql2java-maven-plugin:help -Dsql2java.output=my.properties

Пример вывода информации:```text [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building sql2java test 1.0.2 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- sql2java-maven-plugin:1.0.2:help (default-cli) @ sql2java-test --- [INFO] OUTPUT PROPERTIES TO J:\sql2java.test\my.properties [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.495 s [INFO] Finished at: 2019-11-20T15:25:27+08:00 [INFO] Final Memory: 10M/308M [INFO] ------------------------------------------------------------------------


## Описание параметров

Параметры конфигурации SQL2Java и их описание представлены ниже. Параметры задаются в виде `параметр_название = значение`, все строки начинающиеся с `#` являются комментариями.```properties
#______________________________________________
#
# (1/8) Конфигурация доступа к базе данных (обязательно)
#______________________________________________
# Класс JDBC-драйвера
#jdbc.driver=org.hsqldb.jdbcDriver
# URL доступа к базе данных
#jdbc.url=jdbc:hsqldb:hsql://localhost
# Логин пользователя базы данных
#jdbc.username=sa
# Пароль пользователя базы данных
#jdbc.password=
# Название базы данных
#jdbc.schema=null
#______________________________________________
#
# (2/8) Настройка метода получения автоинкрементных ключей (не обязательно)
#______________________________________________
# Эти параметры используются при вставке записей для получения значений автоинкрементных ключей
# Для JDBC версий bk 3.0 и выше, поддерживающих PreparedStatement.getGeneratedKeys(), эта секция не нужна
#
# Возможные значения для generatedkey.retrieve:
#
# auto - [по умолчанию] метод getGeneratedKeys автоматически получает ключи при использовании JDBC 3.0 драйвера.
#
# before - Получение значений автоинкрементных полей до вставки записи
#
# after - Получение значений автоинкрементных полей после вставки записи
#
# generatedkey.statement используется для определения SQL запроса получения значений автоинкрементных полей
# Если вы установите его значение в before или after, вам также потребуется настроить свойства
# generatedkey.statement
# <TABLE> плейсхолдер заменяет текущее имя таблицы
# <KEY> плейсхолдер заменяет текущее имя поля с автоинкрементом
#
#generatedkey.retrieve=auto
#generatedkey.statement=
#______________________________________________
#
# (3/8) Настройка генерации кода (необязательно)

#______________________________________________

Пакет для генерации Java кода

codewriter.package=gu.sql2java.demo

Директория для генерации Java кода

codewriter.destdir=src/main

Директория для расширенной генерации Java кода

#codewriter.destdir.extension=

Расширенный пакет для генерации Java кода

#codewriter.package.extension=

Определение полей, игнорируемых шаблоном bean.converter.utils.java.vm

#general.beanconverter.tonative.ignore=create_time,update_time

Поддерживает ли сгенерированный Java бин аннотации Facebook/Swift

#swift.annotation.bean=true

Поддерживает ли сгенерированный Java бин аннотации Swagger

#swagger.annotation.bean=true

Для полей с примитивными типами (Integer, Long, Double...) создается ли сеттер для примитивного типа?

codewriter.bean.primitiveSetter=true

Создается ли сеттер типа Long для полей типа java.util.Date?

codewriter.bean.dateLongSetter=true

Тип сериализации JSON для полей типа Date:

Long - время в миллисекундах

String - строка в формате ISO8601

Эффективна при указании аннотаций Swift или Jackson

codewriter.bean.dateSerializeType=Long

Формат даты при dateSerializeType равен String, по умолчанию ISO8601

codewriter.bean.dateStringFormat=yyyy-MM-dd'T'HH:mm:ss.SSSZ

Тип поля modified, initialized (не изменять)

bitstate.type=int

Тип данных для двоичных данных:

byte[]

java.nio.ByteBuffer

По умолчанию byte[], если не указано другое

#binary.type=byte[]

Добавляет аннотацию @JsonRawValue @JsonDeserialize для поля JSON

#json.jackson.rawvalue=false

Устанавливает имя файла конфигурации базы данных

database.properties.env=config_folder database.

database.properties.dir=resources/conf  
database.properties=database.properties  
# Флаг совместимости с axis2  
#bean. compatible_axis2=true  
#Файл свойств для инициализации Velocity  
#codewriter. velocityprops=somefile  
#Путь загрузки шаблонов по умолчанию (не менять)  
velocity. templates. loadingpath=/templates/velocity/includes  
#Путь загрузки вложенных шаблонов для каждой таблицы и каждого схемы (не менять)  
velocity. templates=/templates/velocity/  
############ Расширенные шаблоны ###############  
#Пользователи могут указать путь к расширенным шаблонам (.vm) через следующие параметры  
#sql2java генератор будет использовать эти параметры для выполнения расширенных шаблонов  
#Путь загрузки расширенных шаблонов  
#velocity. templates. loadingpath. extension=  
#Путь загрузки расширенных шаблонов для каждой таблицы и каждого схемы  
#velocity. templates. extension =  
#Устанавливает префикс для всех сгенерированных классов  
#полезно, если вы беспокоитесь о коллизиях пространства имён с зарезервированными словами  
#или классами java.lang  
codewriter. classprefix=  
#Создание значений по умолчанию для полей  
codewriter. generate. defaultvalue=true  
#______________________________________________  
#(4/8) Настройка фильтрации таблиц и шаблонов (опционально)  
#______________________________________________  
#Фильтрация по типу таблицы  
#Для указания типа таблиц, для которых требуется создание кода (список типов таблиц, разделённых запятыми)  
#Типы таблиц определяются как: TABLE, VIEW, SYSTEM TABLE, SYNONYM  
jdbc. tabletypes=TABLE, VIEW  
#Фильтрация по имени таблицы  
#Использует маску % для фильтрации имен таблиц, для которых требуется создание кода# Вы можете указать список масок, разделённых запятыми  
# Например, %_name, ul_% создаст код только для таблиц с суффиксом _name или префиксом ul_  
# По умолчанию создаётся код для всех таблиц в схеме  
jdbc.tablenamepattern=%  
# Белый список / чёрный список имен таблиц (этот функционал ещё не активирован)  
# Белый список  
# Список имен таблиц, разделённых пробелами, для которых будет создан код  
# Чёрный список  
# Список имен таблиц, разделённых пробелами, для которых не будет создан код  
# Можно указать либо белый список, либо чёрный список, но не оба одновременно  
# Белый список  
tables.include=  
# Чёрный список  
tables.exclude=  
# Белый список каталогов шаблонов  
# Белый список  
# Список разделенных пробелами имён таблиц, только те шаблоны в папках, чьи названия находятся в этом списке, будут генерироваться  
# Чёрный список  
# Список разделенных пробелами имён таблиц, шаблоны в папках с такими названиями не будут генерироваться  
# Можно указать либо белый, либо чёрный список, если указаны оба — игнорируется чёрный список  
template.folder.exclude=  
template.folder.include=java5g   
# java5g : общие шаблоны бинов и менеджеров для Java5  
# (6/8) ЧТО ДОЛЖНО БЫТЬ ВИДНО/НЕ ВИДНО НА КЛИЕНТЕ?  
#         пустое значение означает все поля  
#______________________________________________  
# Список полей, доступных только локально, разделенный запятыми  
# Список имен полей в определенной таблице, доступных только локально# Эквивалент определению в аннотации поля: 'SCOPE@LOCAL@EPOSC'
# Пример:
# table.user_info.scope.local=private_time,password
# Список полей, видимых LOCAL, разделенный запятыми
# Список имен полей в определенной таблице, доступных через локальный вызов
# Эквивалент определению в аннотации поля: 'SCOPE@THRIFT@EPOSC'
# Пример:
# table.user_info.scope.thrift=password
# Список полей, видимых THRIFT, разделенный запятыми
# Список имен полей в определенной таблице, доступных через RPC
# Эквивалент определению в аннотации поля: 'SCOPE@JSON@EPOSC'
# Пример:
# table.user_info.scope.json=private_time,password
# Список полей, видимых JSON, разделенный запятыми
# Список имен полей в определенной таблице, доступных для сериализации JSON#______________________________________________
#
# (7/8) Конфигурация типов JDBC (необязательно)
#______________________________________________
#
# Преобразование типа DATE JDBC в тип Java, возможные значения:
#  java.sql.Date
#  java.util.Date
jdbc2java.date=java.util.Date

# Преобразование типа TIME JDBC в тип Java, возможные значения:
#  java.sql.Time
#  java.util.Date
jdbc2java.time=java.util.Date

# Преобразование типа TIMESTAMP JDBC в тип Java, возможные значения:
#  java.sql.Timestamp
#  java.util.Date
jdbc2java.timestamp=java.util.Date

#______________________________________________
#
# (8/8) Конфигурация оптимистической блокировки (необязательно)
#______________________________________________
# optimisticlock.type имеет два возможных значения:
## none — механизм оптимистичной блокировки не активирован (по умолчанию).
#
# timestamp — поле оптимистичной блокировки содержит значение System.currentTimeMillis().
#
# optimisticlock.column определяет имя поля оптимистичной блокировки; если это имя отсутствует, механизм оптимистичной блокировки не будет активирован.
# тип поля оптимистичной блокировки может быть java.lang.Long или java.lang.String.
optimisticlock.type = timestamp
optimisticlock.column = version_time## Декодеры и кодеры столбцов базы данных
С версии 3.21.0 sql2java добавил интерфейс [ColumnCodec](sql2java-base/src/main/java/gu/sql2java/BaseColumnCodec.java) для применения слоев пользовательской сериализации и десериализации данных в столбцах таблиц. Метод сериализации (`ColumnCodec.serialize`) используется для преобразования пользовательских типов данных в типы хранения в базе данных, а метод десериализации (`ColumnCodec.deserialize`) — для обратного преобразования. Поддержка типа JSON реализуется с помощью [JsonColumnCodec](sql2java-base/src/main/java/gu/sql2java/json/JsonColumnCodec.java); приложения могут использовать этот декодер как пример для создания своих пользовательских декодеров и кодеров столбцов.## Поддержка пользовательских типов полей
С версии 3.21.0 sql2java добавил метки аннотаций `ANNOTATION` и `TYPE`. Приложение определяет типы полей и кодеры/декодеры для этих полей, а sql2java автоматически генерирует Java-поля и аннотацию `@ColumnCodecConfig` на основе этих меток.

### TYPE
Определяет тип поля, например `TYPE@net.facelib.eam.interpreter.Rectangle@EPYT` определяет тип поля как `net.facelib.eam.interpreter.Rectangle`.

### ANNOTATION
Определяет аннотации для поля, можно указывать несколько аннотаций, например `ANNOTATION@gu.sql2java.annotations.ColumnCodecConfig(net.facelib.eam.interpreter.sql2java.EamPlayColumnCodec.class)@NNAA` создаст аннотацию `@gu.sql2java.annotations.ColumnCodecConfig(net.facelib.eam.interpreter.sql2java.EamPlayColumnCodec.class)` для Java-поля.### Пример
В следующей таблице поле `rect` определяется через `TYPE@@EPYT` и `ANN@@NNA`.
```sql
CREATE TABLE IF NOT EXISTS dc_device_channel (
   `device_id`     int         NOT NULL COMMENT 'X@NAME: Устройство ID@X',
   `sid`           int         NOT NULL DEFAULT 0 COMMENT 'X@NAME: Физический экран ID@x',
   `area`          varchar(32) NOT NULL COMMENT 'X@NAME: Область отображения ID@x',
   `rect`          varchar(256) DEFAULT NULL COMMENT 'ANN@gu.sql2java.annotations.ColumnCodecConfig(net.facelib.eam.interpreter.sql2java.EamPlayColumnCodec.class)@NNATYPE@net.facelib.eam.interpreter.Rectangle@EPYT'
)
```eam. interpreter. Rectangle@EPYTX@Имя: Координаты области отображения@x, соответствует синтаксису defineChannel в EamPlayer',
   `канал`       varchar(32) NOT NULL COMMENT 'X@NAME: Канал ID@x, область отображения, связанная с этим каналом',
   `run_задачи`     text DEFAULT NULL COMMENT 'X@NAME: Задачи воспроизведения@X описание, описание задач воспроизведения, которое записывается устройством, соответствует методам definePlanTask и defineTrigger в EamPlayer',
   PRIMARY KEY (`device_id`, `sid`, `область`),
   FOREIGN KEY (device_id)  REFERENCES dc_device(id) ON DELETE CASCADE,
   INDEX (канал)
) COMMENT 'X@NAME: Записи канала области отображения устройства@X' DEFAULT CHARSET=utf8;

Пример генерируемого Java-класса для поля rect

/** комментарий: X@NAME: Координаты области отображения@x, соответствует синтаксису defineChannel в EamPlayer */
@ApiModelProperty(value = "X@NAME: Координаты области отображения@x, соответствует синтаксису defineChannel в EamPlayer", dataType = "Rectangle")
@CodegenLength(max = 256) @CodegenInvalidValue
@ExcelColumn(sort = 4)
@gu.sql2java.annotations.ColumnCodecConfig(net.facelib.eam.interpreter.sql2java.EamPlayColumnCodec.class)
private net.facelib.eam.interpreter.Rectangle rect;
```#### Получатель/Установщик методы для типа `net.facelib.eam.interpreter.Rectangle`
##### Получатель метод
```java
@ThriftField(value = 7)
@JsonProperty("rect")
public net.facelib.eam.interpreter.Rectangle getRect() {
    return rect;
}
Установщик метод
@ThriftField(name = "rect")
@JsonProperty("rect")
public void setRect(net.facelib.eam.interpreter.Rectangle newVal) {
    modified |= DC_DEVICE_CHANNEL_ID_RECT_MASK;
    initialized |= DC_DEVICE_CHANNEL_ID_RECT_MASK;
    if (Objects.equals(newVal, rect)) {
        return;
    }
    rect = newVal;
}

Методы чтения/записи для типа данных поля rect

Чтение метод
public String readRect() {
    return metaData.columnCodecs[DC_DEVICE_CHANNEL_ID_RECT].serialize(rect, String.class);
}
Запись метод
public void writeRect(String newVal) {
    modified |= DC_DEVICE_CHANNEL_ID_RECT_MASK;
    initialized |= DC_DEVICE_CHANNEL_ID_RECT_MASK;
    rect = metaData.columnCodecs[DC_DEVICE_CHANNEL_ID_RECT].deserialize(newVal, metaData.fieldOf(DC_DEVICE_CHANNEL_ID_RECT).getGenericType());
}

SCOPE@@EPOSC

Поле SCOPE@@EPOSC используется для определения видимости поля, его формат следующий:

SCOPE@(LOCAL|JSON|THRIFT)@EPOSC

Он позволяет определить три уровня видимости:

  • LOCAL — локальная видимость
  • JSON — видимость при сериализации/десериализации в JSON
  • THRIFT — видимость при сериализации/десериализации в Thrift RPC

Пример ниже показывает таблицу с определением столбца private_time, где используется метка SCOPE@@EPOSC. Это указывает на то, что поле доступно только локально, то есть только сам сервис может читать и писать в это поле.sql CREATE TABLE IF NOT EXISTS dc_device ( `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'X@NAME:ID устройства@X', `name` varchar(32) DEFAULT NULL COMMENT 'X@NAME:Название устройства@X, указано пользователем', `physical_address` varchar(32) NOT NULL UNIQUE COMMENT 'X@NAME:Физический адрес@X, MAC-адрес, IMEI или другой уникальный идентификатор устройства', `private_time` bigint DEFAULT 0 COMMENT 'SCOPE@LOCAL@EPOSC Временная метка создания токена устройства (миллисекунды), этот столбец будет обновлен каждый раз при создании токена устройства', `os_arch` varchar(64) DEFAULT NULL COMMENT 'X@NAME:Архитектура ОС@X, название операционной системы и версия, а также имя аппаратной архитектуры, например: Windows-x86_64, Linux-x86_64, Android-arm...' ) COMMENT 'X@NAME:Запись устройств для фронтенда@X, основная информация об устройствах для фронтенда' DEFAULT CHARSET=utf8; Класс DeviceBean, сгенерированный sql2java-generator, содержит поле privateTime, которое соответствует столбцу private_time таблицы dc_device. Код определения этого поля представлен ниже:

/**
 * Комментарий: временная метка создания токена устройства (миллисекунды). Этот столбец будет обновлен каждый раз при создании токена устройства.
 */
@ApiModelProperty(value = "временная метка создания токена устройства (миллисекунды). Этот столбец будет обновлен каждый раз при создании токена устройства.", dataType = "Long")
@CodegenDefaultvalue("0") @CodegenInvalidValue("-1")
@ExcelColumn(sort = 9)
@JsonField(serialize = false, deserialize = false)
@JsonIgnore
private Long privateTime;

/**
 * Метод получения значения поля {@link #privateTime}.
 *
 * Информация метаданных (в процессе):
 * <ul>
 * <li>полное имя: dc_device.private_time</li>
 * <li>комментарий: временная метка создания токена устройства (миллисекунды). Этот столбец будет обновлен каждый раз при создании токена устройства.</li>
 * <li>значение по умолчанию: '0'</li>
 * <li>размер колонки: 19</li>
 * <li>тип данных JDBC, возвращаемый драйвером: Types.BIGINT</li>
 * </ul>
 *
 * @return значение поля privateTime
 */
@JsonIgnore
public Long getPrivateTime() {

Можно заметить, что член privateTime имеет Jackson аннотацию @JsonIgnore и FastJson аннотацию @JSONField, указывающие на то, что это поле должно игнорироваться при сериализации и десериализации в JSON. В то же время метод getter для privateTime также не имеет аннотации Thrift @ThriftField, что означает, что это поле не было определено как член Thrift.Плагин swift2thrift-maven-plugin не будет содержать поля privateTime в сгенерированном IDL:

struct DeviceBean {
   1: required bool _new;
   2: required i32 modified;
   3: required i32 initialized;
   4: optional i32 id;
   5: optional string name;
   6: optional string physicalAddress;
   7: optional string osArch;
}

Поддержка булевых полей

3.19.0 версия и выше позволяют более детально определять типы данных для целочисленных полей, таких как TINYINT, SMALLINT, INT. Пример таблицы:

SQL Тип Java Поле Тип Описание
TINYINT/BOOL/BOOLEAN Byte /Boolean Если базовый комментарий поля (COMMENT) содержит [NUM,Boolean], генерируемое поле Java будет типа Boolean, в противном случае — Byte
SMALLINT Short
INT Integer

Пример:

CREATE TABLE IF NOT EXISTS dc_device (
	id       int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'Уникальный идентификатор устройства',
	online   boolean DEFAULT false COMMENT '[NUM,Boolean], метка онлайн'
);

Согласно вышеприведенному определению, если поле типа boolean/bool или TINYINT имеет комментарий [NUM,Boolean], то в сгенерированном Java Bean поле online будет иметь тип Boolean.

Внимание: Маркер [NUM,Boolean] должен находиться в начале строки комментария.

Поддержка JSON полей

С версии 3.8, sql2java поддерживает автоматическую сериализацию и десериализацию строковых полей, содержащих JSON данные.### Включение json.jackson.rawvalue

Для активации этой возможности требуется выполнение следующих двух шагов:

Генерируемый при этом код требует наличия библиотек fastjson и jackson.

  • Измените файл sql2java.properties. Установите значение json.jackson.rawvalue равным true, добавив следующую строку:```properties

Добавление аннотаций @JsonRawValue @JsonDeserialize для JSON полей

#json.jackson.rawvalue = true


- Изменение DDL-запроса на создание таблицы
    В комментариях к полям, предназначенным для хранения данных в формате JSON, добавьте префикс [JSON_STR,...]. Этот префикс указывает, что поле предназначено для хранения данных в формате JSON (только для полей типа String).
    Пример:
    ```sql
    CREATE TABLE IF NOT EXISTS dc_device_group (
      `id`          int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'ID группы устройств',
      `name`        varchar(32) NOT NULL COMMENT 'Название группы устройств',
      `address`     varchar(128) DEFAULT NULL COMMENT 'Адрес группы устройств: район/улица/номер дома',
      `props`       text DEFAULT NULL COMMENT '[JSON_STR,obj] Расширенные поля в формате JSON (максимальный размер bcm 64КБ), используемые для определения расширений информации, online_time: время включения, offline_time: время выключения, close_time: время закрытия станции, operator: оператор',
      `create_time` timestamp DEFAULT CURRENT_TIMESTAMP,
      `update_time` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    ) COMMENT 'Информация о группах устройств' DEFAULT CHARSET=utf8;
    ```
    В приведённом выше примере комментарий к полю `props` начинается с `[JSON_STR,obj]`, что указывает на то, что это поле является полем JSON, тип которого Object.
    После выполнения этих двух шагов достаточно просто перезапустить процесс Sql2java для генерации нового кода.
```### [JSON_STR]
При генерации кода будет использоваться префикс `[JSON_STR,...]` для определения типа поля JSON.
| Формат [JSON_STR]                         | Тип поля JSON                   |
|-------------------------------------------|-------------------------------|
| [JSON_STR,array]                          | com.alibaba.fastjson.JSONArray |
| [JSON_STR,object]                         | com.alibaba.fastjson.JSONObject |
| [JSON_STR,obj]                            | com.alibaba.fastjson.JSONObject |
| [JSON_STR]                                | com.alibaba.fastjson.JSON       |
| [JSON_STR,com.mycompany.product.User]     | com.mycompany.product.User      |

### Пример генерируемого кода
Код определения поля `props`:
```java
/** Комментарий: [JSON_STR] Расширенные поля в формате JSON (максимальный размер 64 КБ), используемые для определения расширений информации, online_time: время включения, offline_time: время выключения, close_time: время закрытия станции, operator: оператор */
@ApiModelProperty(value = "[JSON_STR] Расширенные поля в формате JSON (максимальный размер 64 КБ), используемые для определения расширений информации, online_time: время включения, offline_time: время выключения, close_time: время закрытия станции, operator: оператор", dataType = "String")
@CodegenLength(max = 65535)
@CodegenInvalidValue
@JsonRawValue
@com.fasterxml.jackson.databind.annotation.JsonSerialize
@JsonDeserialize(using = gu.sql2java.json.RawJsonDeserializer.class)
private com.alibaba.fastjson.JSONObject props;

Getter/Setter методы для чтения/записи поля в виде строки:

@ThriftField(value = 16)
@JsonProperty("props")
public String getProps() {
    return null == props ? null : props.toJSONString();
}

@ThriftField(name = "props")
@JsonProperty("props")
public void setProps(String newVal) {
    modified |= DC_DEVICE_GROUP_ID_PROPS_MASK;
    initialized |= DC_DEVICE_GROUP_ID_PROPS_MASK;
    props = com.alibaba.fastjson.JSONObject.parseObject(newVal, com.alibaba.fastjson.JSONObject.class);
}
```### Дополнительно сгенерированные методы для прямого чтения/записи JSON объекта:

```java
/**
 * Метод чтения для {@link #props}.
 */
public com.alibaba.fastjson.JSONObject readProps() {
    return props;
}

/**
 * Метод записи для {@link #props}, использует JSON объект.
 */
public void writeProps(com.alibaba.fastjson.JSONObject newVal) {
    modified |= DC_DEVICE_GROUP_ID_PROPS_MASK;
    initialized |= DC_DEVICE_GROUP_ID_PROPS_MASK;
    if (Objects.equals(newVal, props)) {
        return;
    }
    props = newVal;
}

Пример сериализованного объекта

{
    "modified": 0,
    "initialized": 65535,
    "new": false,
    "id": 5,
    "name": "Лянпинь гоудун цзутан",
    "address": null,
    "props": {
        "offline_time": "22:00",
        "online_time": "8:00",
        "operator": "неизвестен"
    },
    "createTime": "2022-07-06T12:41:56.000+0800",
    "updateTime": "2022-07-06T12:41:56.000+0800"
}

Поддержка аннотаций Excel

С версии 3.10, sql2java предоставляет возможность экспорта данных записей в поток или файл Excel-формата, реализованное на основе apache/poi. Подробнее см. sql2java-excel/README.md.

Функционал sql2java-excel позволяет конфигурировать каждое поле таблицы через аннотации для экспорта в Excel. Генератор sql2java-generator поддерживает создание аннотаций @ExcelSheet и @ExcelColumn в Java Bean классах на основании зарезервированных меток в SQL-таблицах и полях.

Включение Excel-аннотаций

Для включения генерации аннотаций Excel требуется выполнить следующие два шага:> Для активации этой функции необходима поддержка библиотеки sql2java-excel.

  • Изменение файла sql2java.properties Установите значение excel.annotation.bean равным true. Пример конфигурации:
# Генерация аннотаций @ExcelSheet и @ExcelColumn при значении true
excel.annotation.bean = true
  • Изменение DDL-запроса В комментариях столбцов таблицы базы данных следует использовать специальные метки EXCEL, как показано ниже. Пример создания таблицы SQL с использованием меток X@...@X:sql CREATE TABLE IF NOT EXISTS dc_device ( `id` INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'X@NAME:Уникальный идентификатор устройства@X', `group_id` INT(11) DEFAULT 1 COMMENT 'X@NAME:Идентификатор группы устройств@X', `features` INT(11) DEFAULT 0 COMMENT 'X@NAME:Флаги характеристик группы устройств@X, определяются уровнем приложения', `name` VARCHAR(32) DEFAULT NULL COMMENT 'X@NAME:Название устройства@X, указанное пользователем', `physical_address` VARCHAR(32) NOT NULL UNIQUE COMMENT 'Устройство X@NAME:Физический адрес@X, MAC-адрес, IMEI или другой уникальный идентификатор устройства', `address_type`VARCHAR(16) NOT NULL DEFAULT 'MAC' COMMENT 'Устройство физический X@NAME:Тип адреса@X (MAC, IMEI и т. д.), по умолчанию шестизначный MAC-адрес (HEX)', `iot_card` VARCHAR(32) DEFAULT NULL UNIQUE COMMENT 'Устройство X@NAME:Номер SIM-карты IoT@X, например ICCID для China Unicom', `status` VARCHAR(32) NOT NULL DEFAULT 'ENABLE' COMMENT 'X@NAME:Статус устройства@X, X@VALUES:ENABLE: нормальный, DISABLE: отключен, MAINTAIN: обслуживание, PENDING: подтвержден (ожидает проверки)@X', `private_time` BIGINT DEFAULT 0 COMMENT 'Устройство X@NAME:Временная метка создания токена@X, обновляется каждый раз при создании нового токена устройства', `screen_info` VARCHAR(32) DEFAULT NULL COMMENT 'X@NAME:Информация о экране устройства@X, пример формата: 15H1080x960 -- 15 (дюймов) горизонтальное разрешение 1080x960, 21V960x1080 -- 21 (дюймов) вертикальное разрешение 960x1080', `fixed_mode` VARCHAR(8) DEFAULT 'FLOOR' COMMENT 'Устройство X@NAME:Режим установки@X, X@VALUES:HANG: подвесной, FLOOR: напольный@X' ); os_arch varchar(64) DEFAULT NULL COMMENT 'X@NAME:Операционная система и архитектура@X: название ОС и версия, а также архитектура оборудования, например Windows-x86_64, Linux-x86_64, Android-arm и т. д.', network varchar(32) DEFAULT NULL COMMENT 'X@NAME:Тип соединения сети@X: 4G, WIFI, ETHERNET' )
  `version_info` varchar(32) DEFAULT NULL COMMENT 'версия приложения на устройстве, формат определяется уровнем приложений',
   `model`       varchar(32) DEFAULT NULL COMMENT 'модель устройства',
   `vendor`      varchar(32) DEFAULT NULL COMMENT 'поставщик устройства',
   `device_detail` varchar(512) DEFAULT NULL COMMENT '[JSON_STR,obj] детали продукта устройства в формате JSON, JSON поля: X@NAMES:device_name: название продукта, manufacturer: производитель, made_date: дата производства@X, уровень приложений может расширяться по необходимости',
   `props`       text DEFAULT NULL COMMENT '[JSON_STR,obj] расширенные поля в формате JSON (максимальный размер 64КБ), используемые для определения дополнительной информации, X@NAMES:last_active_time: последнее время активности, disk_capacity: объём жесткого диска, status_comment: комментарий изменения состояния@X',
   `plan_id`     varchar(64) DEFAULT NULL COMMENT 'текущий ID программы',
   `target_id`   varchar(64) DEFAULT NULL COMMENT 'целевой ID программы',
   `remark`      varchar(256) DEFAULT NULL COMMENT 'замечание',
   `create_time` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT 'время создания записи',
   `update_time` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'время обновления записи'
 ) COMMENT 'запись оборудования переднего плана, основная информация об оборудовании переднего плана, X@SHEET:titleFillColor=YELLOW,hideColumns=private_time|props|device_detail@X' DEFAULT CHARSET=utf8;
 ```С этими метками, sql2java-generator сгенерирует следующий Java Bean код с специальными аннотациями `@ExcelSheet`, `@ExcelColumn`:```java
/**
* DeviceBean представляет собой отображение таблицы dc_device.
* <br>Метаданные (в процессе):
* <ul>
*    <li>описание: запись оборудования переднего плана, основная информация об оборудовании переднего плана,</li>
* </ul>
* @author guyadong
*/
@ExcelSheet(sheetName="dc_device",title="запись оборудования переднего плана",titleFillColor="YELLOW",hideColumns={"private_time","props","device_detail"})
public final class DeviceBean extends BaseRow
   implements Serializable, Constant
{
   private static final long serialVersionUID = -3495281739409382636L;

   /** описание: идентификатор устройства */
   @ExcelColumn(sort=1,name="идентификатор устройства")
   private Integer id;

   /** описание: идентификатор группы устройства */
   @ExcelColumn(sort=2,name="идентификатор группы устройства")
   private Integer groupId;

   /** описание: характеристики группы устройств, определенные уровнем приложений */
   @ExcelColumn(sort=3,name="характеристики группы устройств")
   private Integer features;

   /** описание: имя устройства, указанное пользователем */
   @ExcelColumn(sort=4,name="имя устройства")
   private String name;

   /** комментарий: физический адрес устройства, MAC адрес, IMEI или другой идентификатор устройства */
   @ExcelColumn(sort=5,name="физический адрес")
   private String physicalAddress;

   /** комментарий: тип физического адреса устройства (MAC, IMEI и т. д.), по умолчанию шестизначный MAC адрес (HEX) */
   @ExcelColumn(sort=6,name="тип адреса")
   private String addressType;

   /** комментарий: номер SIM-карты IoT устройства, например, для China Unicom это ICCID */
   @ExcelColumn(sort=7,name="номер SIM-карты IoT")
   private String iotCard;
}
```    /** комментарий: состояние устройства, ENABLE: нормальное, DISABLE: отключено, MAINTAIN: обслуживание, PENDING: приостановлено (ожидает проверки) */
    @ExcelColumn(sort = 8, name = "Состояние устройства", readConverterExp = "ENABLE=нормальное, DISABLE=отключено, MAINTAIN=обслуживание, PENDING=приостановлено (ожидает проверки)")
    private String status;
    /** комментарий: время создания токена устройства в миллисекундах, каждое время создания токена устройства это поле обновляется */
    @ExcelColumn(sort = 9)
    private Long privateTime;
    /** комментарий: информация о экране устройства, пример формата: 15H1080x960 -- 15 (дюймов) горизонтальный экран с разрешением 1080x960, 21V960x1080 -- 21 (дюймов) вертикальный экран с разрешением 960x1080 */
    @ExcelColumn(sort = 10, name = "Информация о экране устройства")
    private String screenInfo;
    /** комментарий: метод установки, HANG: подвесной, FLOOR: напольный */
    @ExcelColumn(sort = 11, name = "Метод установки", readConverterExp = "HANG=подвесной, FLOOR=напольный")
    private String fixedMode;
    /** комментарий: платформа операционной системы, название и версия ОС и архитектура оборудования, например: Windows-x86_64, Linux-x86_64, Android-arm и т. д.  */
    @ExcelColumn(sort = 12, name = "Платформа операционной системы")
    private String osArch;
    /** комментарий: тип соединения сети: 4G, WIFI, ETHERNET */
    @ExcelColumn(sort = 13, name = "Тип соединения сети")
    private String network;
    /** комментарий: версия программного обеспечения на устройстве, формат определяется уровнем приложения */
    @ExcelColumn(sort = 14, name = "Версия")
    private String versionInfo;
    /** комментарий: модель устройства */```java
   @ExcelColumn(sort=15,name="Device Model")
    private String model;
    /** comment: device provider */
    @ExcelColumn(sort=16,name="Device Vendor")
    private String vendor;
    /** comment: detailed information about the device product defined in JSON format, JSON fields: device_name: product name, manufacturer: producer, made_date: production date, application level can be extended as needed */
    @ExcelColumns({
        @ExcelColumn(sort=17,name="Detailed Information About Device Product"),
```
```markdown
### EXCEL метки
Этот раздел объясняет, как определяются метки EXCEL `X@...@X`.
```#### MARKER NAME
`X@NAME:xxxx@X` — это метка определения имени таблицы/поля, которая используется для определения названий столбцов или заголовков в экспортированном Excel-файле. Когда она встречается в комментариях к таблице (COMMENT), то соответствует полю `title` аннотации `@ExcelSheet`. В случае комментариев к полям (COMMENT) она соответствует полю `name` аннотации `@ExcelColumn`.

#### MARKER NAMES
```
`X@NAMES:a=b,c=d@X` является маркером многосимвольной определенной метки, который определяет таблицу или поле в выходных данных EXCEL как имя столбца для членов или подчленов. Когда он встречается в комментариях к таблице (COMMENT), он соответствует аннотации `@ExcelColumn`, которая определяет имя столбца для членов или подчленов таблицы.

В приведенном выше примере поле `device_detail` определено как JSON объектное поле, а в комментариях указан тэг NAMES: `X@NAMES:device_name: продукт, manufacturer: производитель, made_date: дата производства @X`. Это определяет подчлены поля JSON `device_name`, `manufacturer`, `made_date` и соответствующие им названия колонок при экспорте в EXCEL.

> Если фактическое JSON поле содержит больше трёх полей, таких как поле `location`, которое не было определено, то как будет называться колонка этого поля? По умолчанию это будет `location`.
```#### ТЭГ VALUES
`X@VALUES:a=b,c=d@X` является маркером многозначного преобразования, используемым для определения содержимого значений полей при экспорте в Excel. Соответствует параметру `readConverterExp` аннотации `@ExcelColumn`.Как показано в примере, поле `dc_device.status` определяет тэг VALUES: `X@VALUES:ENABLE: нормальный, CLOSED: закрытый, MAINTAIN: обслуживание, PENDING: ожидающий (ожидание проверки) @X`. То есть, когда значение поля `status` равно `ENABLE`, значение в Excel будет `нормальный`, и так далее.

#### ТЭГ COLUMN
`X@COLUMN:name=a,b=c,d=e@X` является маркером полного определения аннотации `@ExcelColumn`, где аннотация `@ExcelColumn` имеет десятки конфигурируемых параметров. Параметры `name, readConverterExp` являются наиболее распространенными, поэтому используются специальные тэги NAME и VALUES. Для других параметров можно использовать тэг COLUMN.

#### ТЭГ SHEET
`X@SHEET:name=a,b=c,d=e@X` является маркером полного определения аннотации `@ExcelSheet`, где аннотация `@ExcelSheet` также имеет десятки конфигурируемых параметров. Параметр `name` является наиболее распространенным, поэтому используется специальный тэг NAME. Для других параметров можно использовать тэг SHEET.

Пример использования тэга SHEET в комментариях к таблице `dc_device`: `X@SHEET:titleFillColor=YELLOW, hideColumns=private_time|props|device_detail@X`

> Обратите внимание, что тип параметра `hideColumns` аннотации `@ExcelSheet` — это массив строк, поэтому при использовании тэга SHEET для определения нескольких элементов массива разделите их символом `|`.#### Принципы специальных маркеров
Специальные маркеры имеют приоритет над общими маркерами COLUMN и SHEET. Если для поля используется COLUMN тег, где указано `name`, а также используется NAME тег для указания имени столбца, в этом случае приоритет имеет значение, указанное с помощью NAME тега. Для SHEET тега логика такая же.## Поддержка полей типа Geometry

```sql
CREATE TABLE dc_spot (
   `id` INT(11) PRIMARY KEY AUTO_INCREMENT,
   `name` VARCHAR(255) DEFAULT NULL COMMENT 'Название места',
   `spot` POINT DEFAULT NULL COMMENT 'Точка координат'
) ENGINE = MyISAM DEFAULT CHARSET = utf8;
```

С версии 3.18.0 поддерживаются все пространственные типы данных MySQL (выше 5.7) ([Пространственные типы данных](https://dev.mysql.com/doc/refman/5.7/en/spatial-type-overview.html)), то есть поля типа Geometry автоматически генерируют члены типа `com.vividsolutions.jts.geom.Geometry`.

Далее представлено соответствие между названиями пространственных типов данных MySQL и объектами геометрии JTS:

| Название пространственного типа данных MySQL | Класс JTS |
|-------------------|----------------------------------------------|
| GEOMETRY          | com.vividsolutions.jts.geom.Geometry         |
| POINT             | com.vividsolutions.jts.geom.Point            |
| LINESTRING        | com.vividsolutions.jts.geom.LineString       |
| POLYGON           | com.vividsolutions.jts.geom.Polygon          |
| MULTIPOINT        | com.vividsolutions.jts.geom.GeometryCollection |
| MULTILINESTRING   | com.vividsolutions.jts.geom.GeometryCollection |
| MULTIPOLYGON      | com.vividsolutions.jts.geom.GeometryCollection |
| GEOMETRYCOLLECTION | com.vividsolutions.jts.geom.GeometryCollection |

### Настройки параметров

Чтобы контролировать типы getter/setter методов для полей типа Geometry в сгенерированном коде, был добавлен параметр `codewrite.bean.geometry.serial.type`.

Описание параметра `codewrite.bean.geometry.serial.type`:- STRING
 **[Значение по умолчанию]** Когда `codewrite.bean.geometry.serial.type=STRING`, типы getter/setter методов для полей типа Geometry являются String, то есть геометрические объекты представляются как WKT строки.
 
 Поскольку String является простым типом, этот способ хорошо читаемый и универсальный, что соответствует обычному подходу к работе с типом Geometry.
 
 Пример сгенерированного кода:
 
 ```java
 private com.vividsolutions.jts.geom.Point spot;
 /** Преобразование spot в WKT строку */
 public String getSpot() {
     return null == spot ? null : spot.toText();
 }
 /** Преобразование WKT строки в Point и сохранение его в spot */
 public void setSpot(String newVal) {
     spot = (null == newVal || newVal.isEmpty()) ? null : GeometryDataCodec.DEFAULT_INSTANCE.fromWKTUnchecked(newVal, Point.class);
 }
 /** Возвращает оригинальный объект spot */
 public com.vividsolutions.jts.geom.Point readSpot() {
     return spot;
 }
 ```

 Внимание: Оставшаяся часть примера кода была прервана и не завершена.```java
   public void setSpot(String newVal){
       spot =  (null == newVal || newVal.isEmpty()) ? null : GeometryDataCodec.DEFAULT_INSTANCE.fromWKTUnchecked(newVal, Point.class);
   }
   
   /** Возвращает оригинальный объект spot */
   public com.vividsolutions.jts.geom.Point readSpot(){
       return spot;
   }```markdown
- JTS
Когда `codewrite.bean.geometry.serial.type=JTS`, используется JTS Geomertry тип непосредственно в методах getter/setter для полей типа Geometry.
Пример сгенерированного кода:
```java
   @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = gu.sql2java.geometry.jackson.GeometryDeserializer.class)
   @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = gu.sql2java.geometry.jackson.GeometrySerializer.class) 
   @com.alibaba.fastjson.annotation.JSONField(serializeUsing=gu.sql2java.geometry.fastjson.PointCodec.class,deserializeUsing=gu.sql2java.geometry.fastjson.PointCodec.class) 
   private com.vividsolutions.jts.geom.Point spot;

   /** Возвращает оригинальный объект sport */
   public com.vividsolutions.jts.geom.Point getSpot(){
       return spot;
   }

   /** Изменяет оригинальный объект sport */
   public void writeSport(com.vividsolutions.jts.geom.Point newVal){
       spot = newVal;
   }
```
```    /**
    * Изменяет оригинальный объект sport
    */
   public void setSport(com.vividsolutions.jts.geom.Point newVal){
       sport = newVal;
   }
```
Независимо от того, какой параметр `codewrite.bean.geometry.serial.type` был выбран, тип поля Geometry всегда будет JTS Geometry типом.
### Поддержка Jackson
JTS Geometry объект не является стандартным Java Bean и поэтому не может автоматически сериализоваться и десериализоваться Jackson. Поэтому требуется реализовать пользовательские сериализаторы и десериализаторы для Geometry объекта.
Сериализатор для JTS Geometry класса реализован [gu.sql2java.geometry.jackson.GeometryDeserializer](sql2java-base/src/main/java/gu/sql2java/geometry/jackson/GeometryDeserializer.java)
Десериализатор для JTS Geometry класса реализован [gu.sql2java.geometry.jackson.GeometrySerializer](sql2java-base/src/main/java/gu/sql2java/geometry/jackson/GeometrySerializer.java)
Это позволяет использовать аннотации `@JsonDeserialize` и `@JsonSerialize` для определения пользовательских сериализаторов и десериализаторов для членов класса:
```java
   @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = gu.sql2java.geometry.jackson.GeometryDeserializer.class)
   @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = gu.sql2java.geometry.jackson.GeometrySerializer.class)
```
``````java
@JsonSerialize(using = gu.sql2java.geometry.jackson.GeometrySerializer.class)
private com.vividsolutions.jts.geom.Point sport;
```
Пример прямого использования пользовательского сериализатора и десериализатора можно найти в тесте: [GeometryJacksonTest](sql2java-base/src/test/java/gu/sql2java/GeometryJacksonTest.java)### Поддержка Fastjson

Объекты JTS Geometry не являются стандартными Java Beans и поэтому автоматически не могут быть сериализованы и десериализованы с помощью Fastjson. Поэтому требуется реализовать пользовательских сериализаторов и десериализаторов для объектов Geometry.

Базовый класс для пользовательской сериализации и десериализации типов JTS Geometry с использованием Fastjson  это [gu.sql2java.geometry.fastjson.GeometryCodec](sql2java-base/src/main/java/gu/sql2java/geometry/fastjson/GeometryCodec.java).

Ниже представлен подробный список соответствия между классами JTS Geometry и пользовательскими классами сериализации и десериализации:

| Класс JTS Geometry                                      | Классы пользовательской сериализации и десериализации |
| ------------------------------------------------------- | ------------------------------------------------------ |
| `com.vividsolutions.jts.geom.Geometry`                  | [gu.sql2java.geometry.fastjson.GeometryCodec](sql2java-base/src/main/java/gu/sql2java/geometry/fastjson/GeometryCodec.java) |
| `com.vividsolutions.jts.geom.Point`                     | [gu.sql2java.geometry.fastjson.PointCodec](sql2java-base/src/main/java/gu/sql2java/geometry/fastjson/PointCodec.java) |
| `com.vividsolutions.jts.geom.LineString`                | [gu.sql2java.geometry.fastjson.LineStringCodec](sql2java-base/src/main/java/gu/sql2java/geometry/fastjson/LineStringCodec.java) |
| `com.vividsolutions.jts.geom.Polygon`                   | [gu.sql2java.geometry.fastjson.PolygonCodec](sql2java-base/src/main/java/gu/sql2java/geometry/fastjson/PolygonCodec.java) |
| `com.vividsolutions.jts.geom.GeometryCollection`        | [gu.sql2java.geometry.fastjson.GeometryCollectionCodec](sql2java-base/src/main/java/gu/sql2java/geometry/fastjson/GeometryCollectionCodec.java) |#### Пример использования аннотаций

Ниже представлен пример использования аннотации `@JSONField`, чтобы определить пользовательскую сериализацию и десериализацию полей класса:

```java
@com.alibaba.fastjson.annotation.JSONField(
serializeUsing = gu.sql2java.geometry.fastjson.PointCodec.class,
deserializeUsing = gu.sql2java.geometry.fastjson.PointCodec.class)
private com.vividsolutions.jts.geom.Point spot;
```

Пример прямого цитирования с использованием пользовательских сериализаторов и десериализаторов:

Для примера использования см.: [gu.sql2java.GeometryFastjsonTest](sql2java-base/src/test/java/gu/sql2java/GeometryFastjsonTest.java)

#### GeometryInit

[gu.sql2java.geometry.fastjson.GeometryInit](sql2java-base/src/main/java/gu/sql2java/geometry/fastjson/GeometryInit.java) используется для глобальной настройки сериализатора и десериализатора JTS Geometry для FastJson. Это позволяет установить все пользовательские сериализаторы и десериализаторы JTS Geometry в качестве глобальных для FastJson.

Когда требуется отдельная сериализация и десериализация объектов JTS Geometry, можно использовать метод `GeometryInit.init()` для выполнения глобальной инициализации, чтобы гарантировать правильную работу FastJson с объектами JTS Geometry.

Пример:

```java
@Test
public void test2Fastjson() {
   try {
       GeometryInit.init();
       String wkt = "POINT (1 -1)";
       Point point = GeometryDataCodec.DEFAULT_INSTANCE.fromWKT(wkt, Point.class);
       log("point {}", JSON.toJSONString(point));
       assertTrue(wkt.equals(point.toText()));
   } catch (ParseException e) {
       e.printStackTrace();
       assertTrue(false);
   }
}
```

## Фильтрация статических полейНезависимо от того, используются ли Thrift RPC или Spring Web сервисы, входные и выходные параметры методов службы должны передаваться через сеть между сервером и клиентом. Для реализации передачи данных объекты данных отправителя сериализуются (в виде JSON или двоичного потока данных), а получатель затем десерилизует эти данные обратно в исходные объекты данных.

С версии 3.32.0 sql2java добавил возможность фильтрации статических полей, что позволяет указывать видимость полей при генерации классов объектов базы данных.

**Видимость** поля относится к тому, видимым является это поле для получателя данных или нет. Управление этим осуществляется за счет игнорирования невидимых полей при сериализации/десериализации объектов таблицы базы данных.

Реализация заключается в том, что sql2java-generator использует аннотации Jackson, Fastjson и Thrift для указания игнорирования этих полей при сериализации/десериализации объектов таблицы. Примеры см. в разделе **«SCOPE@@EPOSC»**

### Определение видимости полей

В sql2java видимость полей определяется с помощью перечисления `gu.sql2java.ColumnVisibility`.| Перечисляемое значение   | Видимость в JSON | Видимость в Thrift | Описание                                                                 |
|--------------------------|------------------|--------------------|---------------------------------------------------------------------------|
| PUBLIC                   | true             | true               | Поле всегда видимо                                                       |
| PRIVATE                  | false            | false              | Поле всегда скрыто                                                       |
| READ_ONLY                | true             | false              | Поле доступно только для чтения                                          |
| WRITE_ONLY               | false            | true               | Поле доступно только для записи                                          |Таким образом, можно контролировать видимость полей в зависимости от требований к сериализации и десериализации объектов таблицы базы данных.

| ----------- | ------------ | -------------- | ------------------------------------------------------------ |
| **DEFAULT** | true         | true           | По умолчанию все поля видимы                               |
| **LOCAL**   | false        | false          | Только локально видимо, при взаимодействии с удаленной стороной (Spring WEB, Thrift RPC) невидимо      |
| **THRIFT**  | false        | true           | Видимо при передаче данных через Thrift RPC, клиент и сервер Thrift RPC видят данные                  |
| **JSON**    | true         | false          | Видимо при сериализации в JSON, при взаимодействии клиента и сервера Spring WEB (Spring WEB использует Jackson для сериализации и десериализации), также применимо при использовании FastJson для сериализации и десериализации объектов базы данных |

### Определение видимости
Определяется способ установки видимости полей двумя методами: первый  путём указания метки `SCOPE@@EPOSC` в комментариях к столбцам таблицы в SQL-запросах, см. раздел **«SCOPE@@EPOSC»**, второй  путём конфигурации в файле параметров sql2java (`sql2java.properties`), см. раздел **«Параметры конфигурации»** `(6/8)`.

---

Таким образом, можно контролировать видимость полей в зависимости от требований к сериализации и десериализации объектов таблицы базы данных.

| ----------- | ------------ | -------------- | ------------------------------------------------------------ |
| **DEFAULT** | true         | true           | По умолчанию все поля видимы                               |
| **LOCAL**   | false        | false          | Только локально видимо, при взаимодействии с удаленной стороной (Spring WEB, Thrift RPC) невидимо      |
| **THRIFT**  | false        | true           | Видимо при передаче данных через Thrift RPC, клиент и сервер Thrift RPC видят данные                  |
| **JSON**    | true         | false          | Видимо при сериализации в JSON, при взаимодействии клиента и сервера Spring WEB (Spring WEB использует Jackson для сериализации и десериализации), также применимо при использовании FastJson для сериализации и десериализации объектов базы данных |

### Определение видимости
Определяется способ установки видимости полей двумя методами: первый  путём указания метки `SCOPE@@EPOSC` в комментариях к столбцам таблицы в SQL-запросах, см. раздел **«SCOPE@@EPOSC»**, второй  путём конфигурации в файле параметров sql2java (`sql2java.properties`), см. раздел **«Параметры конфигурации»** `(6/8)`.## Аннотация
### @Sql2javaLocalConfig
С версии 3.32.6 добавлена аннотация `@Sql2javaLocalConfig`, которая используется для определения конфигураций времени выполнения Sql2java в сервисных методах или классах. В настоящее время единственным свойством является `resetModifiedIfEqual`. При определении типа Java Bean в этом поле после успешной десериализации JSON в объект Java Bean вызывается метод `BaseBean.resetModifiedIfEqual`, который нормализует объект, гарантируя, что метка modified будет установлена только для полей, значения которых отличаются от значений записей в базе данных.#### RuntimeConfigInterceptor
Для активации аннотации `@Sql2javaLocalConfig` в среде Spring требуется использовать `RuntimeConfigInterceptor`. Этот интерцептор устанавливает объект конфигурации времени выполнения Sql2java (`gu.sql2java.config.RuntimeConfig`) перед тем как HTTP-запрос будет обработан, а затем удаляет его после завершения метода. Конфигурация, созданная аннотацией `@Sql2javaLocalConfig`, хранится в объекте `RuntimeConfig`.

#### Запуск RuntimeConfig интерцептора
Для запуска интерцептора RuntimeConfig достаточно указать пакет, содержащий конфигурацию `RuntimeConfigInterceptor` (`FilterInterceptorConfig`) в аннотации запуска Spring (`@SpringBootApplication`). Это активирует фильтры beanfilter, определённые в сервисных методах.
```java
import org.springframework.boot.autoconfigure.SpringBootApplication;
import gu.sql2java.config.spring.*;
```

```java
/**
* Конфигурация запуска приложения
*/
@SpringBootApplication(scanBasePackageClasses = {RuntimeConfigInterceptor.class})
public class ApplicationBoot {
   //////. . . . /////
}
```

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Генератор кода для доступа к облегчённой базе данных (SQL) на Java. Развернуть Свернуть
BSD-2-Clause
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/l0km-sql2java.git
git@api.gitlife.ru:oschina-mirror/l0km-sql2java.git
oschina-mirror
l0km-sql2java
l0km-sql2java
master