A lot of annoying things can happen when using Hibernate ORM.

  • ID logic, usually we don’t care how the ID is generated, just use the primary key.
  • A lot ofgetter,setterMethods benefit from the anaemic model, but in use we just use these methods to get or set properties.
  • The early Java EE pattern suggests that we willEntity,DAOCarry on the division, but in use, actuallyDAOThey are often empty, and this redundant hierarchy is not delivering value.
  • Hibernate provides powerful generic methods, but most of them are not used, which is a waste.
  • In practice, Hibernate is more complex for most trivial queries.

The introduction of

<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>
Copy the code

The configuration file

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# log quarkus. Hibernate - orm. Enter the SQL =trueQuarkus.hibernate-orm. Sql-load-script =importCreate table quarkus.hibernate-orm.database.generation=drop-and-createCopy the code

Defining database entities

By inheriting PanacheEntity or PanacheEntityBase, the following describes the basic encoding operations. Panache can support chain calls or return a Stream.

The default ID

@Entity
public class Person extends PanacheEntity {
    public String name;
    public LocalDate birth;
    public Status status;
}
Copy the code

The custom ID

@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;
}
Copy the code

Getters and setters are used to access fields that are public, so we can write getters and setters to do special processing.

Basic operation

new

@Transactional
public Person create(a) {
    Person person = new Person();
    person.name = "Stef";
    person.birth = LocalDate.of(1910, Month.FEBRUARY, 1);
    person.status = Status.Alive;
    // Persist
    person.persist();
    return person;
}
Copy the code

A single query

Query entity

Person person = Person.findById(personId);
Copy the code

Query entity Optional

Optional<Person> optional = Person.findByIdOptional(personId);
Person person = optional.orElseThrow(() -> new NotFoundException());
Copy the code

Query list

Query all

List<Person> allPersons = Person.listAll();
long countAll = Person.count();
Copy the code

Conditions of the query

List<Person> livingPersons = Person.list("status", Status.Alive);
long countAlive = Person.count("status", Status.Alive);
Copy the code

Paging query

PanacheQuery<Person> livingPersons = Person.find("status", Status.Alive);
// Return to page 5 with 10 entries per page
List<Person> page5 = livingPersons.page(Page.of(5.10)).list();
/ / the total number of article
long count = livingPersons.count();
Copy the code

The sorting

1 / / way
List<Person> persons = Person.list("order by name,birth");

2 / / way
List<Person> persons = Person.list(Sort.by("name").and("birth"));

3 / / way
List<Person> persons = Person.list("status", Sort.by("name").and("birth"), Status.Alive);
Copy the code

update

A single updating

Optional<Person> optional = Person.findByIdOptional(personId);
Person person = optional.orElseThrow(() -> new NotFoundException());
person.name = "Change the name";
Copy the code

Batch update

Person.update("name = 'Moral' where status = ? 1", Status.Alive);
Copy the code

delete

A single delete

Optional<Person> optional = Person.findByIdOptional(personId);
Person person = optional.orElseThrow(() -> new NotFoundException());
person.delete();
Copy the code

Delete all

Person.deleteAll();
Copy the code

Conditional deletion

Person.delete("status", Status.Alive);
Copy the code

The use of HQL

Native statements

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);
Copy the code

The query

Person.find("name = ? 1 and status = ? 2. ""."stef", Status.Alive);
Copy the code

Use Map as the parameter

Map<String, Object> params = new HashMap<>();
params.put("name"."stef");
params.put("status", Status.Alive);
Person.find("name = :name and status = :status", params);
Copy the code

Use Parameters to define Parameters

/ / using the map
Person.find("name = :name and status = :status",
         Parameters.with("name"."stef").and("status", Status.Alive).map());

/ / don't have a map
Person.find("name = :name and status = :status",
         Parameters.with("name"."stef").and("status", Status.Alive));
Copy the code

Using database locks

1 / / way
Person p = Person.findById(id, LockModeType.PESSIMISTIC_WRITE);

2 / / way
Person p = Person.find("name", name).withLock(LockModeType.PESSIMISTIC_WRITE).findOne();
Copy the code

Another way to use Repository

@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> {}Copy the code

This approach is similar to Spring Data JPA, so I won’t cover it.

@GET
@operation (summary = "query record list ")
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);
}
Copy the code