использовать
Hibernate ORM
В процессе будет происходить много неприятных вещей.
- Логика ID, обычно нас не волнует, как генерируется ID, он просто используется как первичный ключ.
- Много
getter
,setter
методы, которые выигрывают от анемичной модели, но при использовании мы просто используем эти методы для получения или установки свойств. - Ранние шаблоны Java EE предполагают, что мы поместили
Entity
,DAO
Разделенный, но в употреблении, по сути,DAO
Часто пустая, эта избыточная иерархия не приносит той ценности, которой она заслуживает. - Hibernate предоставляет мощные универсальные методы, но большинство из них не используются, что является пустой тратой времени.
- На практике Hibernate более сложен для большинства тривиальных запросов.
вводить
<dependencies>
<!-- Hibernate ORM specific dependencies -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-panache</artifactId>
</dependency>
<!-- JDBC driver dependencies -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-mysql</artifactId>
</dependency>
</dependencies>
конфигурационный файл
quarkus.datasource.db-kind=mysql
quarkus.datasource.username=root
quarkus.datasource.password=123456
quarkus.datasource.jdbc.url=jdbc:mysql://127.0.0.1:3306/demo?characterEncoding=utf8&useSSL=false
quarkus.datasource.jdbc.max-size=8
quarkus.datasource.jdbc.min-size=1
# 日志
quarkus.hibernate-orm.log.sql=true
# 初始化脚本
quarkus.hibernate-orm.sql-load-script=import.sql
# 自动创建表
quarkus.hibernate-orm.database.generation=drop-and-create
Определение объектов базы данных
по наследствуPanacheEntity
илиPanacheEntityBase
, ниже кратко представлены основные операции кодирования,Panache
Может поддерживать связанные вызовы, а также может возвращатьStream
.
Идентификатор по умолчанию
@Entity
public class Person extends PanacheEntity {
public String name;
public LocalDate birth;
public Status status;
}
пользовательский идентификатор
@Entity
public class Person extends PanacheEntityBase {
@Id
@SequenceGenerator(
name = "personSequence",
sequenceName = "person_id_seq",
allocationSize = 1,
initialValue = 4)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "personSequence")
public Integer id;
public String name;
public LocalDate birth;
public Status status;
}
Определяется полямиpublic
Да на самом деле нижний слой все же проходитgetter
,setter
для доступа, поэтому мы можем написатьgetter
,setter
для специального лечения.
Основная операция
новый
@Transactional
public Person create() {
Person person = new Person();
person.name = "Stef";
person.birth = LocalDate.of(1910, Month.FEBRUARY, 1);
person.status = Status.Alive;
// 进行持久化
person.persist();
return person;
}
Один запрос
объект запроса
Person person = Person.findById(personId);
Сущность запроса Необязательно
Optional<Person> optional = Person.findByIdOptional(personId);
Person person = optional.orElseThrow(() -> new NotFoundException());
список запросов
запросить все
List<Person> allPersons = Person.listAll();
long countAll = Person.count();
Условный запрос
List<Person> livingPersons = Person.list("status", Status.Alive);
long countAlive = Person.count("status", Status.Alive);
Пейджинговый запрос
PanacheQuery<Person> livingPersons = Person.find("status", Status.Alive);
// 每页 10 条,返回第 5 页
List<Person> page5 = livingPersons.page(Page.of(5, 10)).list();
// 总条数
long count = livingPersons.count();
Сортировать
// 方式1
List<Person> persons = Person.list("order by name,birth");
// 方式2
List<Person> persons = Person.list(Sort.by("name").and("birth"));
// 方式3
List<Person> persons = Person.list("status", Sort.by("name").and("birth"), Status.Alive);
возобновить
одно обновление
Optional<Person> optional = Person.findByIdOptional(personId);
Person person = optional.orElseThrow(() -> new NotFoundException());
person.name = "更改name";
Массовое обновление
Person.update("name = 'Moral' where status = ?1", Status.Alive);
Удалить
одиночное удаление
Optional<Person> optional = Person.findByIdOptional(personId);
Person person = optional.orElseThrow(() -> new NotFoundException());
person.delete();
удалить все
Person.deleteAll();
Удалить по условиям
Person.delete("status", Status.Alive);
Использование HQL
родной оператор
Order.find("select distinct o from Order o left join fetch o.lineItems");
Order.update("update from Person set name = 'Moral' where status = ?", Status.Alive);
проверить предложение
Person.find("name = ?1 and status = ?2", "stef", Status.Alive);
Использовать карту в качестве параметра
Map<String, Object> params = new HashMap<>();
params.put("name", "stef");
params.put("status", Status.Alive);
Person.find("name = :name and status = :status", params);
Используйте параметры для определения параметров
// 使用map
Person.find("name = :name and status = :status",
Parameters.with("name", "stef").and("status", Status.Alive).map());
// 不用map
Person.find("name = :name and status = :status",
Parameters.with("name", "stef").and("status", Status.Alive));
Использовать блокировку базы данных
// 方式1
Person p = Person.findById(id, LockModeType.PESSIMISTIC_WRITE);
// 方式2
Person p = Person.find("name", name).withLock(LockModeType.PESSIMISTIC_WRITE).findOne();
Другой способ использования репозитория
@Entity
public class Person {
@Id @GeneratedValue private Long id;
private String name;
private LocalDate birth;
private Status status;
// getter and setter ...
}
@ApplicationScoped
public class PersonRepository implements PanacheRepository<Person> {
}
таким образом сSpring Data JPA
Он относительно похож и не будет представлен.
@GET
@Operation(summary = "查询记录列表")
public PageResponse<SysUserModel> list(
@QueryParam("key") String key,
@QueryParam("index") int index,
@QueryParam("size") int size
) {
StringBuilder sql = new StringBuilder("1 = 1 ");
Parameters parameters = new Parameters();
if (Objects.nonNull(key)) {
sql.append("and userName like :userName");
parameters.and("userName", "%" + key + "%");
}
PanacheQuery<SysUserModel> query = SysUserModel.find(sql.toString(), parameters);
query.page(Page.of(index, size == 0 ? 10 : size));
List<SysUserModel> list = query.list();
list.forEach(sysUserModel -> sysUserModel.password=null);
long count = query.count();
return PageResponse.page(count, list);
}