Статьи

Hibernate: генерация схемы DDL

Не так давно мне приходилось работать с базой данных в памяти. Эта деятельность была связана с интеграционным тестированием. Как вы знаете, обычная практика — использовать базы данных в памяти для тестирования интеграции. Для этого есть несколько причин: мобильность, хорошо структурированная инфраструктура среды, высокая производительность, согласованность исходной базы данных.

Проблема заключается в копировании производственных DDL-схем в тестовую базу данных в памяти. Первый — MySQL , второй — HSQLDB . Синтаксис MySQL отличается от синтаксиса HSQL. Поэтому импорт схем таблиц MySQL в HSQLDB становится невозможным без соответствующей конвертации.

Честно говоря, я потратил много времени на поиск решения, которое поможет мне импортировать схемы MySQL DDL в HSQL . Результаты были не так хороши, как я хотел. Все решения были либо коммерческими, либо не автоматическими, например, замена всего специфического для MySQL кода на HSQL.

К счастью, мой проект использует Hibernate в качестве реализации JPA. Все объекты украшены соответствующими аннотациями Hibernate. Как вы увидите далее, это будет очень полезно при переводе схем MySQL. Hibernate предоставляет механизмы для создания сущностей на основе DDL и наоборот. Следовательно, любая сущность, украшенная аннотациями Hibernate, может быть представлена ​​в виде схемы таблицы с использованием того диалекта DB, который поддерживает Hibernate.

Вот класс, который решает мою проблему:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
public class SchemaTranslator {
    private Configuration config = null;
 
    public SchemaTranslator() {
        config = new Configuration();
    }
 
    public SchemaTranslator setDialect(String dialect) {
        config.setProperty(AvailableSettings.DIALECT, dialect);
        return this;
    }
 
    /**
     * Method determines classes which will be used for DDL generation.
     * @param annotatedClasses - entities annotated with Hibernate annotations.
     */
    public SchemaTranslator addAnnotatedClasses(Class[] annotatedClasses) {
        for (Class clazz : annotatedClasses)
            config.addAnnotatedClass(clazz);
        return this;
    }
 
    /**
     * Method performs translation of entities in table schemas.
     * It generates 'CREATE' and 'DELETE' scripts for the Hibernate entities.
     * Current implementation involves usage of {@link #write(FileOutputStream, String[], Formatter)} method.
     * @param outputStream - stream will be used for *.sql file creation.
     * @throws IOException
     */
    public SchemaTranslator translate(FileOutputStream outputStream) throws IOException {
        Dialect requiredDialect = Dialect.getDialect(config.getProperties());
        String[] query = null;
 
        query = config.generateDropSchemaScript(requiredDialect);
        write(outputStream, query, FormatStyle.DDL.getFormatter());
 
        query = config.generateSchemaCreationScript(requiredDialect);
        write(outputStream, query, FormatStyle.DDL.getFormatter());
 
        return this;
    }
 
    /**
     * Method writes line by line DDL scripts in the output stream.
     * Also each line logs in the console.
     * @throws IOException
     */
    private void write(FileOutputStream outputStream, String[] lines, Formatter formatter)
            throws IOException {
        String tempStr = null;
 
        for (String line : lines) {
            tempStr = formatter.format(line)+";";
            System.out.println(tempStr);
            outputStream.write(tempStr.getBytes());
        }
    }
 
    public static void main(String[] args) throws IOException {
        SchemaTranslator translator = new SchemaTranslator();
        Class[] entityClasses = {Smartphone.class};
 
        translator.setDialect("org.hibernate.dialect.HSQLDialect")
            .addAnnotatedClasses(entityClasses)
            .translate(new FileOutputStream(new File("db-schema.sql")));
 
    }
 
}

Приведенный выше код довольно многословен, но я прокомментировал его. Поэтому я надеюсь, что это будет более или менее легко для понимания. Код всего приложения можно найти на GitHub . Класс SchemaTranslator имеет следующее расположение в структуре проекта:

  • / SRC / тест / Java / COM / mobapp / тест / Util /

С помощью этого класса вы можете перенести свои объекты в любые необходимые базы данных, поддерживаемые Hibernate.

Удачи!

Ссылка: Hibernate: Генерация схемы DDL от нашего партнера по JCG Алексея Зволинского в блоге заметок Фрузенштейна .