Рубрики
Без рубрики

Руководство для начинающих по репозиторию GitHub с высокой производительностью и сохраняемостью java

Репозиторий GitHub с высокой производительностью и сохраняемостью java представляет собой набор интеграционных тестов и утилит, позволяющих с максимальной легкостью тестировать функции JDBC, JPA, Hibernate и jOOQ.

Автор оригинала: Vlad Mihalcea.

Когда я начал писать Высокопроизводительное сохранение Java , я понял, что мне нужен репозиторий GitHub для размещения всех тестовых примеров, которые мне нужны для фрагментов кода в моей книге, и именно так родился высокопроизводительный репозиторий GitHub с сохранением java .

Репозиторий GitHub с высокой производительностью и сохраняемостью java представляет собой набор интеграционных тестов и утилит, позволяющих с максимальной легкостью тестировать функции JDBC, JPA, Hibernate и jOOQ.

Коллекция интеграционных тестов и утилит, позволяющих тестировать функции JDBC, JPA, Hibernate и jOOQ – @vlad_mihalcea https://t.co/FOCcW98MAs https://t.co/FOCcW98MAs

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

Это видео-лишь один из многих потрясающих видеоуроков, которые вы можете найти в моем высокопроизводительном видеокурсе сохранения Java .

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

Именно так мы тестируем проект Hibernate ORM That’s also how we are testing the Hibernate ORM project

Теперь в репозитории GitHub с высокой производительностью и сохраняемостью java вы найдете множество интеграционных тестов. На момент написания этой статьи существует более 440 интеграционных тестов, охватывающих наиболее распространенные сценарии, с которыми вы можете столкнуться при использовании JDBC, JPA или Hibernate.

В то время как для производственной системы вы действительно хотите использовать Flyway для управления схемой базы данных, когда ваша цель состоит в создании автономных интеграционных тестов, инструмент Hibernate hbm2ddl – отличный выбор.

Таким образом, вам не нужно писать какие-либо сценарии DDL для вашей базы данных для интеграционных тестов, и это дает вам большое преимущество при переключении с одной реляционной базы данных на другую.

До тех пор, пока вы продолжаете As long as you extend AbstractTest , all you need to do is to override the entities base class method: Абстрактный тест

@Override
protected Class[] entities() {
    return new Class[] {
        Post.class,
        PostDetails.class,
    };
}

И сущности могут быть инкапсулированы в интеграционные тесты, чтобы каждый тест работал по своей собственной уникальной модели без влияния изменений, происходящих за пределами исходного кода рассматриваемого интеграционного теста:

@Entity(name = "Post")
@Table(name = "post")
public static class Post {

    @Id
    @GeneratedValue
    private Long id;

    private String title;

    //Getters and setters omitted for brevity
}

@Entity(name = "PostDetails")
@Table(name = "post_details")
public static class PostDetails {

    @Id
    private Long id;

    @Column(name = "created_on")
    private Date createdOn;

    @Column(name = "created_by")
    private String createdBy;

    @OneToOne
    @MapsId
    private Post post;

    //Getters and setters omitted for brevity
}

Удивительность этого метода проявляется, когда вы начинаете переопределять метод базы данных базового класса.

Если вы заявляете, что хотите использовать MySQL:

@Override
protected Database database() {
    return Database.MYSQL;
}

В вашем тесте будет использоваться следующая схема базы данных MySQL:

create table post (
    id bigint not null, 
    title varchar(255), 
    primary key (id)
) engine=InnoDB

create table post_details (
    created_by varchar(255), 
    created_on datetime(6), 
    post_id bigint not null, 
    primary key (post_id)
)

alter table post_details 
add constraint FKmcgdm1k7iriyxsq4kukebj4ei 
foreign key (post_id) references post (id)

Если вы хотите, чтобы этот тест выполнялся на PostgreSQL, просто измените метод database следующим образом:

@Override
protected Database database() {
    return Database.POSTGRESQL;
}

И Hibernate hbm2ddl сделает свое дело:

create sequence hibernate_sequence 
start 1 increment 1

create table post (
    id int8 not null, 
    title varchar(255), 
    primary key (id)
)

create table post_details (
    created_by varchar(255), 
    created_on timestamp, 
    post_id int8 not null, 
    primary key (post_id)
)

alter table if exists post_details 
add constraint FKmcgdm1k7iriyxsq4kukebj4ei 
foreign key (post_id) references post

Круто, правда?

Просто потому, что вам нужно протестировать код JDBC, это не значит, что ваш код должен быть подробным. Благодаря методу do В JDBC , который вы автоматически наследуете от Абстрактный тест , ваша логика интеграционного теста выглядит следующим образом:

doInJDBC(connection -> {
    try (Statement statement = connection.createStatement()) {
        statement.addBatch(
            "insert into post (title, version, id) " +
            "values ('Post no. 1', 0, 1)"
        );

        statement.addBatch(
            "insert into post_comment (post_id, review, version, id) " +
            "values (1, 'Post comment 1.1', 0, 1)"
        );
        
        statement.addBatch(
            "insert into post_comment (post_id, review, version, id) " +
            "values (1, 'Post comment 1.2', 0, 2)"
        );

        int[] updateCounts = statement.executeBatch();
        assertEquals(3, updateCounts.length);
    }
});

За кулисами метод doInJDBC выполняет все необходимые действия для запуска этого кода:

  • получено соединение с базой данных,
  • транзакция запускается автоматически,
  • выполняется лямбда-код Java 8,
  • в случае успеха транзакция будет совершена,
  • в случае сбоя транзакция откатывается,
  • соединение закрывается независимо от того, что происходит выше.

В том же духе именно так вы выполняете логику доступа к данным JPA и гибернации:

Post _post = doInJPA(entityManager -> {
    Post post = new Post("First post");
    entityManager.persist(post);

    return post;
});

doInJPA(entityManager -> {
    Post post = entityManager.getReference(
        Post.class, _post.getId()
    );

    PostDetails details = new PostDetails("John Doe");
    details.setPost(post);

    entityManager.persist(details);
});

doInJPA(entityManager -> {
    PostDetails details = entityManager.find(
        PostDetails.class, 
        _post.getId()
    );
    assertNotNull(details);

    entityManager.flush();
    details.setPost(null);
});

Метод doInJPA заботится о:

  • создание JPA EntityManager ,
  • запуск JPA EntityTransaction ,
  • выполняется лямбда-код Java 8,
  • при успешном выполнении EntityTransaction выполняется,
  • в случае сбоя/| entityтранзакция откатывается,
  • EntityManager закрывается независимо от того, что происходит выше.

Если вы хотите протестировать код доступа к данным, просто разветвите мой высокопроизводительный репозиторий GitHub с сохранением java и сосредоточьтесь на логике тестирования, вместо загрузки JDBC, JPA или гибернации или управления схемой базы данных или базовыми ресурсами, задействованными во время выполнения тестов.