Спящая карта * списка * строк (с указанием строки) - PullRequest
0 голосов
/ 05 января 2020

Я немного прочитал об этой теме c и нашел решение, но мне интересно, есть ли более точное или более оптимальное решение.

Мое основное требование c - создать объект, который имеет карту списков типа string, ie:

private Map<String, List<String>> mapOfStringLists;

Важно, что мы можем эффективно запрашивать сущности, которые содержат определенную c пару имя-значение, ie. где mapOfStringLists.get(K).contains(V);

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

Java код:

@Entity
@Table(name = "T_USER_PROFILE")
public class UserProfile {
    @OneToMany(targetEntity = UserProfileAttributeMultiValued.class, mappedBy = "userProfile")
    @MapKeyColumn(name = "ATTRIBUTE_NAME")
    private Map<String, UserProfileAttributeMultiValued> attributesMultiValued = new HashMap<>();
}

@Entity(name = "T_USER_PROFILE_ATTRIBUTE_MV")
public class UserProfileAttributeMultiValued {
    @EmbeddedId
    private MultiValuedUserProfileAttributeKey key;

    @ElementCollection
    @CollectionTable(name = "T_USER_PROFILE_ATTRIBUTE_MV_VALUES", joinColumns = {
            @JoinColumn(name = "USER_PROFILE_GUID_FK"),
            @JoinColumn(name = "ATTRIBUTE_NAME")
    })
    public List<String> values;

    @ManyToOne
    @JoinColumn(name = "USER_PROFILE_GUID_FK", nullable = false, insertable = false, updatable = false)
    private UserProfile userProfile;
}

@Embeddable
public class MultiValuedUserProfileAttributeKey implements Serializable {
    @Column(name = "USER_PROFILE_GUID_FK", length = 36)
    private String guid;

    @Column(name = "ATTRIBUTE_NAME")
    private String attributeName;
}

Сгенерированная схема:

    create table T_USER_PROFILE (
        GUID varchar(36) not null,
        primary key (GUID)
    );

    create table T_USER_PROFILE_ATTRIBUTE_MV (
        USER_PROFILE_GUID_FK varchar(36) not null,
        ATTRIBUTE_NAME varchar(255) not null,
        primary key (ATTRIBUTE_NAME, USER_PROFILE_GUID_FK)
    );

    create table T_USER_PROFILE_ATTRIBUTE_MV_VALUES (
        USER_PROFILE_GUID_FK varchar(255) not null,
        ATTRIBUTE_NAME varchar(36) not null,
        values varchar(255)
    );

Это является достаточно аккуратным и логичным, и я могу понять, что промежуточная таблица может быть необходима для того, чтобы иметь четкий (составной) первичный ключ для набора элементов, но, возможно, есть лучший способ скрыться?

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...