Может кто-нибудь сказать мне, в чем преимущество load()
перед get()
в Hibernate?
Какое преимущество load() vs get() в Hibernate?
Ответ 1
В чем преимущество load() по сравнению с get() в Hibernate?
Прокси-сервер означает, что hibernate подготовит некоторый поддельный объект с заданным значением идентификатора в памяти без попадания в базу данных.
Например:
Если мы позвоним session.load(Student.class,new Integer(107));
hibernate создаст в памяти один поддельный объект Student [row] с идентификатором 107, но остальные свойства класса Student даже не будут инициализированы.
Ответ 2
Объяснение семантики этих методов не объясняет практической разницы между ними. Практическое правило следующее:
-
Используйте
get()
, когда вы хотите загрузить объект -
Используйте
load()
, когда вам нужно получить ссылку на объект без выдачи дополнительных SQL-запросов, например, для создания отношения с другим объектом:public void savePost(long authorId, String text) { Post p = new Post(); p.setText(text); // No SELECT query here. // Existence of Author is ensured by foreign key constraint on Post. p.setAuthor(s.load(Author.class, authorId)); s.save(p); }
Ответ 3
Из книги "Сохранение Java с гибернацией" на стр. 405:
Единственное различие между get() и load() заключается в том, как они указывают, что экземпляр не найден. Если строка с указанным идентификаторомзначение существует в базе данных, get() возвращает null. Метод load() выбрасывает ObjectNotFoundException. Его выбор, какой которую вы предпочитаете.
Более важно, t метод load() может верните прокси, местозаполнитель, без попадания в базу данных. следствием этого является то, что вы можете получить ObjectNotFoundException позже, как только вы попытаетесь получить доступ к возвращенному заполнителю и силу его инициализация (это также называется ленивой загрузкой, мы обсуждаем нагрузку оптимизация в последующих главах.) Метод load() всегда пытается возвращает прокси-сервер и возвращает только экземпляр инициализированного объекта, если его уже управляет текущий контекст постоянства. в пример, показанный ранее, никакого попадания в базу данных не происходит вообще! Метод get() с другой стороны, никогда не возвращает прокси, он всегда попадает в базу данных.
Вы можете спросить, почему этот параметр полезен. В конце концов, вы получаете объект для доступа к нему. Его общий для получения постоянного экземпляра назначьте его как ссылку на другой экземпляр. Например, представьте себе что вам нужен элемент только для одной цели: установить связь с комментарием: aComment.setForAuction(item). Если это все, что вы планируете делать с элементом, прокси-сервер будет делать все; здесь нет нужно попасть в базу данных. Другими словами, когда комментарий сохраняется, вам нужно значение внешнего ключа элемента, вставленного в КОММЕНТАРИЙ Таблица. Прокси-элемент элемента предоставляет только это: значение идентификатора завернутый в заполнитель, который выглядит как настоящая вещь.
Ответ 4
load вернет прокси-объект.
get вернет фактический объект и вернет null, если он не найдет какой-либо объект.
Ответ 5
A: Это объясняется в справочной системе спящего режима. Одно из отличий - это производительность, а другая - то, что load выдает неисправимое исключение, если для ID не найден объект.
Подробнее здесь
Ответ 6
- Используйте get(), когда вы хотите загрузить объект
- Используйте load(), когда вам нужно получить ссылку на объект без выдача дополнительных SQL-запросов, например, для создания отношений с другой объект:
Пример: если вы пытаетесь загрузить/получить объект Empoyee, где empid = 20. Но предположим, что запись недоступна в БД.
Employee employee1 = session.load(Employee.class,20); //Step-1
system.out.println(employee1.getEmployeeId(); //Step-2 --o/p=20
system.out.println(employee1.getEmployeeName(); //Step-3 -->O/P:ObjectNotFoundException
Если вы используете загрузку в спящем режиме с шагом 1, не запускайте любой запрос выбора для извлечения записи сотрудника из базы данных в этот момент. В этом спящем режиме пинты появляется фиктивный объект (прокси). Этот фиктивный объект не содержит ничего. это новый сотрудник (20). вы можете проверить это на шаге 2 он будет печатать 20. но на шаге 3 мы пытаемся найти информацию о сотрудниках. поэтому в это время hibernate запускает sql-запрос для извлечения Empoyee objct. Если он не найден в DB.throws ObjectNotFoundException.
Employee employee2 = session.get(Employee.class,20); //Step-4
для session.get() hibernate запускает sql-запрос для извлечения данных из db. поэтому в нашем случае id = 20 не существует в БД. поэтому он возвращает null.
Ответ 7
Проблемы с производительностью также являются существенной разницей между методом get и load.
Метод get() извлекает данные, как только он выполняется, когда метод load() возвращает прокси-объект и извлекает только данные, когда требуются свойства объекта. Так что метод load() получает лучшую производительность, так как поддерживает ленивую загрузку. Whe должен использовать метод load() только тогда, когда мы знаем, что данные существуют, потому что он выдает исключение, когда данные не найдены. Если мы хотим убедиться, что данные существуют, мы должны использовать метод get().
Короче говоря, вы должны понимать разницу между ними и решить, какой метод лучше всего исправить в вашем приложении.
Я нашел эти различия в учебнике Разница между методом get и load в Hibernate
Ответ 8
Когда вызывается Load, возвращается объект Proxy. Фактический запрос выбора еще не запущен. Когда мы используем какое-либо из отображаемого свойства, первый запрос запускается. Если строка не существует в БД, она будет генерировать исключение. например.
Software sw = ( Software )session.load(Software.class, 12);
Здесь sw - тип прокси. И выбор запроса еще не вызван. в отладчике Eclipse вы можете увидеть его как
sw Software$$EnhancerByCGLIB$$baf24ae0 (id=17)
CGLIB$BOUND true
CGLIB$CALLBACK_0 CGLIBLazyInitializer (id=23)
CGLIB$CALLBACK_1 null
CGLIB$CONSTRUCTED true
id null
prop1 null
softwareprop null
когда я использую
sw.getProp1()
выполняется запрос выбора. И теперь прокси теперь знает значения для всех отображаемых свойств.
Где, как при вызове get, немедленно вызывается запрос. Возвращаемый объект не является прокси, а действительным классом. например.
Software sw = ( Software )session.get(Software.class, 12);
Здесь sw является типом программного обеспечения. Если строка существует, то все отображаемые свойства заполняются значениями в БД. Если строка не существует, то sw будет null.
sw Software (id=17)
id Integer (id=20)
prop1 "prodjlt1" (id=23)
softwareprop "softwrjlt1" (id=27)
Как всегда, используйте нагрузку, только если вы уверены, что запись существует в БД. В этом случае безопасно работать с прокси-сервером и будет полезно отложить запрос БД до тех пор, пока на самом деле не будет выполнено сопоставленное свойство.
Ответ 9
Session.load(): Он всегда будет возвращать прокси-объект с заданным значением идентификатора, даже если значение идентификатора не существует в базе данных. Однако, когда вы пытаетесь инициализировать прокси-сервер, извлекая его свойства из базы данных, он попадает в базу данных с помощью оператора select. Если строка не найдена, возникнет исключение ObjectNotFoundException.
session.get(): Он всегда будет возвращать ноль, если значение идентичности не найдено в базе данных.
Ответ 10
Get() возвращает объект, извлекая его из базы данных или из кэша гибернации, тогда как load() просто возвращает ссылку на объект, который может фактически не существовать, он загружает данные из базы данных или кэша только при доступе к другим свойствам объекта.
С помощью load() мы можем напечатать идентификатор, но как только мы пытаемся получить доступ к другим полям, он запускает запрос к базе данных и генерирует исключение org.hibernate.ObjectNotFoundException, если запись с указанным идентификатором не найдена. Это специфичное для спящего режима исключение времени выполнения, поэтому нам не нужно явно его отлавливать.