обратный = «истинный» пример и объяснение
Always put inverse=”true” in your collection variable ?
Есть много статей о Hibernate, в которых пытаются объяснить «обратное» с помощью многих «официальных» жаргонов Hibernate, которые очень трудно понять (по крайней мере, для меня). В нескольких статьях они даже предлагали просто забыть об «инверсии» и всегда помещатьinverse=”true” в переменную коллекции.
Это утверждение всегда верно - «положить переменную = true в переменную коллекции», но не закрывайте на это глаза, постарайтесь понять причину, по которой это необходимо для оптимальной производительности Hibernate.
Что такое «обратный»?
Это самое запутанное ключевое слово в Hibernate, по крайней мере, я потратил довольно много времени, чтобы понять его. Ключевое слово «inverse» всегда объявляется в соотношенииone-to-many иmany-to-many (многие-к-одному не имеют обратного ключевого слова), это означает, что какая сторона несет ответственность за отношения.
«Обратный», должен измениться на «владелец отношений»?
В Hibernate только «владелец отношения» должен поддерживать отношения, и создается ключевое слово «инверсия», чтобы определить, какая сторона является владельцем для поддержания отношений. Однако само ключевое слово «inverse» недостаточно подробное, я бы предложил изменить ключевое слово на «relationship_owner».
Короче говоря, обратный = «истина» означает, что это владелец отношения, а обратный = «ложь» (по умолчанию) означает, что это не так.
1. Отношение один ко многим
Это дизайн таблицы отношенийone-to-many, таблица STOCK имеет много вхождений в таблице STOCK_DAILY_RECORD.
2. Реализация гибернации
См. Реализацию Hibernate в файлах сопоставления XML.
Файл: Stock.java
public class Stock implements java.io.Serializable { ... private SetstockDailyRecords = new HashSet (0); ...
Файл: StockDailyRecord.java
public class StockDailyRecord implements java.io.Serializable { ... private Stock stock; ...
Файл: Stock.hbm.xml
... ...
Файл: StockDailyRecord.hbm.xml
... ...
3. обратный = правда / ложь
Обратное ключевое слово применяется в отношении один ко многим. Вот вопрос, если операция сохранения или обновления выполняется в объекте «Stock», следует ли обновить отношение «stockDailyRecords»?
Файл: Stock.hbm.xml
... ...
1. инверсия = "истина"
Если значение inverse = «true» в переменной set, это означает, что «stock_daily_record» является владельцем отношения, поэтому Stock НЕ ОБНОВЛЯЕТ отношение.
...
2. инверсия = "ложь"
Если значение inverse = «false» (по умолчанию) в переменной set, это означает, что «stock» является владельцем отношения, и Stock обновит отношение.
...
Смотрите больше примеров ниже:
4. пример = "ложь"
Если ключевое слово «обратный» не определено, будет использовано обратное = «ложное», что
...
Это означает, что «сток» является владельцем отношений, и он будет поддерживать отношения.
Вставить пример…
При сохранении объекта «Stock» Hibernate сгенерирует три оператора SQL, две вставки и одно обновление.
session.beginTransaction(); Stock stock = new Stock(); stock.setStockCode("7052"); stock.setStockName("PADINI"); StockDailyRecord stockDailyRecords = new StockDailyRecord(); stockDailyRecords.setPriceOpen(new Float("1.2")); stockDailyRecords.setPriceClose(new Float("1.1")); stockDailyRecords.setPriceChange(new Float("10.0")); stockDailyRecords.setVolume(3000000L); stockDailyRecords.setDate(new Date()); stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stock); session.save(stockDailyRecords); session.getTransaction().commit();
Выход…
Hibernate: insert into exampledb.stock (STOCK_CODE, STOCK_NAME) values (?, ?) Hibernate: insert into exampledb.stock_daily_record (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?) Hibernate: update exampledb.stock_daily_record set STOCK_ID=? where RECORD_ID=?
Stock обновит «stock_daily_record.STOCK_ID» с помощью переменной Set (stockDailyRecords), потому что Stock является владельцем отношения.
Note
Третий оператор действительно НЕ нужен.
Пример обновления…
Когда объект «Stock» обновляется, Hibernate сгенерирует два оператора SQL, один для вставки и один для обновления.
session.beginTransaction(); Stock stock = (Stock)session.get(Stock.class, 57); StockDailyRecord stockDailyRecords = new StockDailyRecord(); stockDailyRecords.setPriceOpen(new Float("1.2")); stockDailyRecords.setPriceClose(new Float("1.1")); stockDailyRecords.setPriceChange(new Float("10.0")); stockDailyRecords.setVolume(3000000L); stockDailyRecords.setDate(new Date()); stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stockDailyRecords); session.update(stock); session.getTransaction().commit();
Выход…
Hibernate: insert into exampledb.stock_daily_record (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?) Hibernate: update exampledb.stock_daily_record set STOCK_ID=? where RECORD_ID=?
Note
Опять же, третий оператор НЕ нужен.
5. пример = "истина"
Если ключевое слово «inverse = true» определено:
...
Теперь это означает, что «stockDailyRecords» является владельцем отношения, а «акции» не будут поддерживать отношения.
Вставить пример…
При сохранении объекта «Stock» Hibernate сгенерирует два оператора вставки SQL.
session.beginTransaction(); Stock stock = new Stock(); stock.setStockCode("7052"); stock.setStockName("PADINI"); StockDailyRecord stockDailyRecords = new StockDailyRecord(); stockDailyRecords.setPriceOpen(new Float("1.2")); stockDailyRecords.setPriceClose(new Float("1.1")); stockDailyRecords.setPriceChange(new Float("10.0")); stockDailyRecords.setVolume(3000000L); stockDailyRecords.setDate(new Date()); stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stock); session.save(stockDailyRecords); session.getTransaction().commit();
Вывод …
Hibernate: insert into exampledb.stock (STOCK_CODE, STOCK_NAME) values (?, ?) Hibernate: insert into exampledb.stock_daily_record (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?)
Пример обновления…
При обновлении объекта «Stock» Hibernate сгенерирует одну инструкцию SQL.
session.beginTransaction(); Stock stock = (Stock)session.get(Stock.class, 57); StockDailyRecord stockDailyRecords = new StockDailyRecord(); stockDailyRecords.setPriceOpen(new Float("1.2")); stockDailyRecords.setPriceClose(new Float("1.1")); stockDailyRecords.setPriceChange(new Float("10.0")); stockDailyRecords.setVolume(3000000L); stockDailyRecords.setDate(new Date()); stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stockDailyRecords); session.update(stock); session.getTransaction().commit();
Выход…
Hibernate: insert into exampledb.stock_daily_record (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?)
inverse vs cascade
Многие люди любят сравнивать инверсию и каскад, но это совершенно разные понятия, см.differential here.
Заключение
Понимание «обратного» необходимо для оптимизации кода Hibernate, оно помогает избежать многих ненужных операторов обновления, таких как «пример вставки и обновления для обратного = ложного» выше. Наконец, постарайтесь запомнить обратное = «true», означающее, что это владелец отношения, который будет управлять отношениями.