Самостоятельное присоединение к спящему режиму
Вопрос
Фон
У меня есть таблица со столбцами идентификатор, идентификатор изображения, идентификатор свойства.
С одним свойством может быть связано множество изображений, а с одним изображением может быть связано множество свойств.
imageId - many-to-many - propertyId
У меня есть список идентификаторов свойств, и я хочу найти все изображения, связанные со всеми идентификаторами свойств. использование спящего режима.
Проблема.
Сейчас я выбираю одно свойство за раз и с помощью Criteria API нахожу все идентификаторы изображений, связанные с этим идентификатором свойства, и получаю список идентификаторов изображений.Я использую этот список идентификаторов изображений в следующем запросе и говорю:
select imageIds where imageId in (imageIds obtained in previous step) where propertyId = x
Таким образом, количество запросов, обращающихся к БД, будет равняться количеству идентификаторов свойств.Я не думаю, что это хорошее решение: мне пришлось обращаться к базе данных n раз, я пробовал использовать отдельный запрос, но безуспешно.Есть ли лучшее решение?
Кроме того, когда я наконец получу список imageIds, стоит ли (не будем учитывать количество результатов) сохранить его в пользовательском сеансе и разбить на страницы ИЛИ стоит ли повторить весь процесс ИЛИ следует Я рассматриваю возможность хранения его в БД только для нумерации страниц?
Решение
Вот проблема со схемой вашей базы данных:
Вы пытаетесь втиснуть 3 отдельные ассоциации (изображение-коллекция, изображение-свойство, коллекция-свойство) в одну Коллекция изображений стол.Это не хорошая вещь.Хотя вам, вероятно, удастся избежать этого, используя простой SQL (за счет большого количества строк с нулевыми столбцами в этой таблице), вы не сможете правильно отобразить это в Hibernate.Кстати, этой таблице не нужен суррогатный первичный ключ.
Что вам нужно сделать, это разделить его на 3 отдельные таблицы и сопоставить вашу модель как правильную «многие ко многим» в Hibernate.Например:
@Entity
public class Image {
@ManyToMany
@JoinTable(
name="IMAGE_PROPERTIES",
joinColumns=@JoinColumn(name="IMAGE_ID"),
inverseJoinColumns=@JoinColumn(name="PROPERTY_ID")
)
private Collection<Property> properties;
...
}
IMAGE_PROPERTIES
в таблице будет только IMAGE_ID
и PROPERTY_ID
колонны;у тебя будет COLLECTION_IMAGES
и COLLECTION_PROPERTIES
столы тоже нравятся.
После этого вы сможете запрашивать изображения по именам свойств, например:
from Image img
left join img.properties as prop
with prop.name in ('Tag1', 'Tag2', 'Tag3')
Если ваши свойства действительно похожи на теги, взгляните на Эта статья для примеров запросов AND/OR/UNION.
Если ваши свойства на самом деле являются свойствами (то есть имеют жизненный цикл сущности-владельца и не могут принадлежать более чем одной сущности одновременно), рассмотрите возможность разделения их на две таблицы (одну для изображений и одну для коллекций) и используйте одну: ко-многим ассоциациям.Таким образом, вам не понадобится IMAGE_PROPERTIES
и COLLECTION_PROPERTIES
таблицы сверху.
Другие советы
Итак, у вас есть такой класс (Примечание:Я это писал не с помощью ide, поэтому код может быть не синтаксически корректным):
public class Property {
@ManyToMany
private List<Image> images;
}
public class Image {
@ManyToMany
private List<Property> properties;
}
Итак, запрос типа select property from Property property
должен предоставить вам список свойств, к которым вы можете получить доступ через обычные свойства Java.
Это то, что вы ищете, или я неправильно понял вопрос?