hibernate
Настройка производительности
Поиск…
Не используйте тип выборки EAGER
Спящий режим может использовать два типа извлечения при сопоставлении отношений между двумя объектами: EAGER
и LAZY
.
В общем EAGER
тип EAGER
выборки не является хорошей идеей, потому что он сообщает JPA, чтобы всегда извлекать данные, даже если эти данные не нужны.
Например, если у вас есть объект Person
и отношения с Address
например:
@Entity
public class Person {
@OneToMany(mappedBy="address", fetch=FetchType.EAGER)
private List<Address> addresses;
}
В любое время, когда вы запрашиваете Person
, будет возвращен и список Address
этого Person
.
Таким образом, вместо того, чтобы сопоставлять вашу сущность с:
@ManyToMany(mappedBy="address", fetch=FetchType.EAGER)
Использование:
@ManyToMany(mappedBy="address", fetch=FetchType.LAZY)
Еще одна вещь, на которую нужно обратить внимание, - отношения @OneToOne
и @ManyToOne
. По умолчанию оба они EAGER. Итак, если вас беспокоит производительность вашего приложения, вам нужно установить выборку для этого типа отношений:
@ManyToOne(fetch=FetchType.LAZY)
А также:
@OneToOne(fetch=FetchType.LAZY)
Использовать композицию вместо наследования
Hibernate имеет несколько стратегий наследования. JOINED
наследования JOINED
выполняет JOIN между дочерним объектом и родительским объектом.
Проблема с этим подходом заключается в том, что Hibernate всегда выводит данные всех вовлеченных таблиц в наследование.
Например, если у вас есть объекты Bicycle
и MountainBike
используя JOINED
наследования JOINED
:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Bicycle {
}
А также:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class MountainBike extends Bicycle {
}
Любой запрос JPQL, который попадает в MountainBike
приведет к данным Bicycle
, создав SQL-запрос, например:
select mb.*, b.* from MountainBike mb JOIN Bicycle b ON b.id = mb.id WHERE ...
Если у вас есть другой родительский элемент для Bicycle
(например, Transport
, например), этот вышеприведенный запрос также приведет данные от этого родителя, делая дополнительный JOIN.
Как вы можете видеть, это своего рода сопоставление EAGER
. У вас нет выбора приносить только данные таблицы MountainBike
используя эту стратегию наследования.
Лучшим для исполнения является использование композиции вместо наследования.
Для этого вы можете сопоставить объект MountainBike
с полевым bicycle
:
@Entity
public class MountainBike {
@OneToOne(fetchType = FetchType.LAZY)
private Bicycle bicycle;
}
И Bicycle
:
@Entity
public class Bicycle {
}
В каждом запросе теперь будут отображаться только данные MountainBike
по умолчанию.