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

Аннотация @WhereJoinTable спячки

Hibernate позволяет запрашивать в соответствии с столбцами в таблице отношений во многих отношениях. Это достигается с помощью аннотации WhereJoinTable.

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

1. Обзор

Использование инструмента Object Relational Mapping, как Hibernate, упрощает чтение наших данных в объекты, но может затрудняет формирование наших запросов со сложными моделями данных.

Отношения между многими и многими всегда сложны, но они могут быть более сложными, когда мы хотим приобретать связанные организации на основе некоторого имущества самого отношения.

В этом учебнике мы посмотрим, как решить эту проблему с помощью программного @WhereJoinTable аннотация.

2. Основные @ManyToMany отношения

Начнем с простого @ManyToMany . Нам нужны сущности модели домена, сущность отношения и некоторые данные выборочных тестов.

2.1. Модель домена

Давайте представим, что у нас есть две простые сущности, Пользователь и Групповой , которые связаны как @ManyToMany:

@Entity
public class User {

    @Id
    @GeneratedValue
    private Long id;
    private String name;

    @ManyToMany
    private List groups = new ArrayList<>();

    // standard getters and setters

}
@Entity
public class Group {

    @Id
    @GeneratedValue
    private Long id;
    private String name;

    @ManyToMany(mappedBy = "groups")
    private List users = new ArrayList<>();

    // standard getters and setters

}

Как мы видим, наши Пользователь сущность может быть членом более чем одного Групповой сущность. Аналогичным образом, Групповой сущность может содержать более одного Пользователь сущность.

2.2. Отношение entity

Для @ManyToMany ассоциаций, нам нужна отдельная таблица баз данных, называемая таблицей отношений. Таблица отношений должна содержать по крайней мере два столбца: основные клавиши связанного Пользователь и Групповой Объекты.

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

Однако, если нам нужно поместить дополнительные данные в таблицу отношений, мы должны также определить сущность отношения для многих к многим отношения себя.

Давайте создадим ПользовательGroupRelation класс, чтобы сделать это:

@Entity(name = "r_user_group")
public class UserGroupRelation implements Serializable {

    @Id
    @Column(name = "user_id", insertable = false, updatable = false)
    private Long userId;

    @Id
    @Column(name = "group_id", insertable = false, updatable = false)
    private Long groupId;

}

Здесь мы назвали сущность r_user_group так что мы можем ссылаться на него позже.

Для наших дополнительных данных, скажем, мы хотим хранить каждый Пользователь ‘S роль для каждого Групповой . Итак, мы создадим ПользовательGroupRole перечисление:

public enum UserGroupRole {
    MEMBER, MODERATOR
}

Далее мы добавим ролевые имущество для UserGroupRelation:

@Enumerated(EnumType.STRING)
private UserGroupRole role;

Наконец, чтобы настроить его должным образом, мы должны добавить @JoinTable аннотация на Пользователь ‘ы группы коллекция. Здесь мы указать имя таблицы присоединения, используя r_user_group, название сущности UserGroupRelation:

@ManyToMany
@JoinTable(
    name = "r_user_group",
    joinColumns = @JoinColumn(name = "user_id"),
    inverseJoinColumns = @JoinColumn(name = "group_id")
)
private List groups = new ArrayList<>();

2.3. Выборочных данных

Для наших интеграционных тестов давайте определим некоторые выборочных данных:

public void setUp() {
    session = sessionFactory.openSession();
    session.beginTransaction();
    
    user1 = new User("user1");
    user2 = new User("user2");
    user3 = new User("user3");

    group1 = new Group("group1");
    group2 = new Group("group2");

    session.save(group1);
    session.save(group2);

    session.save(user1);
    session.save(user2);
    session.save(user3);

    saveRelation(user1, group1, UserGroupRole.MODERATOR);
    saveRelation(user2, group1, UserGroupRole.MODERATOR);
    saveRelation(user3, group1, UserGroupRole.MEMBER);

    saveRelation(user1, group2, UserGroupRole.MEMBER);
    saveRelation(user2, group2, UserGroupRole.MODERATOR);
}

private void saveRelation(User user, Group group, UserGroupRole role) {

    UserGroupRelation relation = new UserGroupRelation(user.getId(), group.getId(), role);
    
    session.save(relation);
    session.flush();
    session.refresh(user);
    session.refresh(group);
}

Как мы видим, user1 и user2 в двух группах. Кроме того, мы должны заметить, что в то время как user1 это МОДЕРАТОР на группа 1 , в то же время он имеет ЧЛЕН роль в группа 2 .

3. Получение @ManyToMany отношений

Теперь мы правильно настроили наши сущности, давайте забираем группы Пользователь сущность.

3.1. Простое извлечение

Для того, чтобы получить группы, мы можем просто вызвать getGroups () метод Пользователь внутри активного сеанса Hibernate:

List groups = user1.getGroups();

Наша продукция для группы будет:

[Group [name=group1], Group [name=group2]]    

Но как мы можем получить группы пользователей, роль группы которых только посредник?

3.2. Пользовательские фильтры на сущности отношения

Мы можем использовать @WhereJoinTable аннотация непосредственно приобретать только фильтрованные группы.

Давайте определим новое свойство как модераторГруппы и положить @WhereJoinTable аннотация на нем. Когда мы будем иметь доступ к связанным сущностям через это свойство, оно будет содержать только группы, из которых наш пользователь посредник.

Нам нужно будет добавить пункт О’8, где пункт для фильтрации групп по МОДЕРАТОР роль:

@WhereJoinTable(clause = "role='MODERATOR'")
@ManyToMany
@JoinTable(
    name = "r_user_group",
    joinColumns = @JoinColumn(name = "user_id"),
    inverseJoinColumns = @JoinColumn(name = "group_id")
)
private List moderatorGroups = new ArrayList<>();

Таким образом, мы можем легко получить группы с указанным S’L, где применяется оговорка:

List groups = user1.getModeratorGroups();

Нашим выходом будут группы, на которых пользователь имеет только роль посредник:

[Group [name=group1]]

4. Заключение

В этом учебнике мы научились фильтр @ManyToMany коллекции, основанные на свойстве таблицы отношений с использованием @WhereJoinTable аннотация .

Как всегда, все образцы кода, данные в этом учебнике, доступны более на GitHub .