В чем преимущество load () перед get () в Hibernate? - PullRequest
52 голосов
/ 20 марта 2011

Может кто-нибудь сказать мне, в чем преимущество load () по сравнению с get () в Hibernate?

Ответы [ 10 ]

64 голосов
/ 20 марта 2011

Объяснение семантики этих методов не объясняет практическую разницу между ними.Практическое правило следующее:

  • Используйте 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);
    }
    
39 голосов
/ 06 октября 2015

В чем преимущество load () по сравнению с get () в Hibernate?

enter image description here
источник

Прокси означает, что hibernate подготовит некоторый поддельный объект с данным значением идентификатора в памяти, не обращаясь к базе данных. enter image description here

Например:
Если мы позвоним session.load(Student.class,new Integer(107));

hibernate создаст в памяти один поддельный объект Student [row] с идентификатором 107, но остальные свойства класса Student даже не будут инициализированы.

Источник

31 голосов
/ 20 октября 2011

Из книги "Сохранение Java в спящем режиме", стр. 405:

Единственное различие между get () и load () состоит в том, как они указывают, что экземпляр не может быть найден. Если нет строки с данным идентификатором значение существует в базе данных, get () возвращает ноль . Метод load () выдает исключение ObjectNotFoundException . Это ваш выбор, что обработка ошибок вы предпочитаете.

Более важно, t Метод load () может вернуть прокси , заполнитель без попадания в базу данных . Следствием этого является то, что вы можете получить исключение ObjectNotFoundException позже, как только вы попытаетесь получить доступ к возвращенному заполнителю и принудительно его инициализация (это также называется отложенной загрузкой; мы обсуждаем загрузку оптимизация в следующих главах.) Метод load () всегда пытается вернуть прокси-сервер и возвращает инициализированный экземпляр объекта, только если это уже управляется текущим контекстом постоянства. в В примере, показанном ранее, попадание в базу данных не происходит вообще! Метод get () с другой стороны, никогда не возвращает прокси, он всегда обращается к базе данных .

Вы можете спросить, почему эта опция полезна - в конце концов, вы получаете объект для доступа к нему. Обычно получают постоянный экземпляр назначить его как ссылку на другой экземпляр. Например, представьте что вам нужен элемент только для одной цели: установить ассоциация с комментарием: aComment.setForAuction (элемент). Если это все, что вы планируете делать с предметом, прокси подойдет; здесь нет нужно поразить базу данных. Другими словами, когда комментарий сохраняется, вам нужно значение внешнего ключа элемента, вставленного в КОММЕНТАРИЙ Таблица. Прокси-объект Item предоставляет только это: значение идентификатора завернутый в заполнитель, который выглядит как настоящая вещь.

5 голосов
/ 20 марта 2011

load вернет объект прокси.

get вернет реальный объект и вернет ноль, если не найдет объект.

4 голосов
/ 01 января 2014
  • Используйте 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

Если вы используете load в hibernate на шаге 1, вы не будете запускать любой запрос select для извлечения записи сотрудника из БД в данный момент. На этом пинте hibernate дает фиктивный объект (Proxy). Этот фиктивный объект не содержит ничего. это новый сотрудник (20). Вы можете проверить это в шаге 2 будет напечатано 20. Но на шаге 3 мы пытаемся найти информацию о сотрудниках. поэтому в это время hibernate запускает SQL-запрос для получения Empoyee-объекта. Если он не найден в DB.throws ObjectNotFoundException.

Employee employee2 = session.get(Employee.class,20);  //Step-4

for session.get () hibernate запускает SQL-запрос для извлечения данных из базы данных. поэтому в нашем случае id = 20 не существует в БД. поэтому он вернет ноль.

4 голосов
/ 20 марта 2011

A: Это объясняется в ссылке на спящий режим. Одно из различий было в производительности, а другое в том, что загрузка выдает неисправимое исключение, когда не найден объект для идентификатора.

Подробнее здесь

2 голосов
/ 13 декабря 2016

Проблемы с производительностью также являются существенным отличием между методами get и load.

Метод get () извлекает данные, как только он выполняется, в то время как метод load () возвращает прокси-объект и извлекает только данные, когда требуются свойства объекта. Так что метод load () получает лучшую производительность, потому что он поддерживает отложенную загрузку. Whe должен использовать метод load () только тогда, когда мы знаем, что данные существуют, потому что он выдает исключение, когда данные не найдены. Если мы хотим убедиться, что данные существуют, мы должны использовать метод get ().

Короче говоря, вы должны понимать разницу между ними и решать, какой метод лучше всего исправить в вашем приложении.

Я нашел эти различия в учебнике Разница между методами get и load в Hibernate

2 голосов
/ 07 февраля 2012

Когда вызывается 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 будет нулевым.

sw  Software  (id=17)   
id  Integer  (id=20)    
prop1   "prodjlt1" (id=23)  
softwareprop    "softwrjlt1" (id=27)    

Как всегда, используйте load только в том случае, если вы уверены, что запись существует в БД. В этом случае работа с прокси безвредна, и будет полезно откладывать запрос к БД до тех пор, пока действительно не потребуется сопоставленное свойство.

1 голос
/ 09 июня 2018

session.load () : он всегда возвращает прокси-объект с заданным значением идентификатора, даже если значение идентификатора не существует в базе данных.Однако, когда вы пытаетесь инициализировать прокси-сервер, извлекая его свойства из базы данных, он попадает в базу данных с помощью оператора select.Если строка не найдена, возникнет исключение ObjectNotFoundException.

session.get () : всегда будет возвращаться ноль, если значение идентификатора не найдено в базе данных.

0 голосов
/ 16 июля 2018

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

С помощью load () мы можем напечатать идентификатор, но как только мы пытаемся получить доступ к другим полям, он запускает запрос к базе данных и генерирует исключение org.hibernate.ObjectNotFoundException, если не найдено записи с данным идентификатором. Это специфичное для спящего режима исключение времени выполнения, поэтому нам не нужно явно его отлавливать.

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