[JAVA] Premiers pas avec Doma-Using Projection avec l'API Criteira

introduction

La récupération en spécifiant uniquement une colonne spécifique dans la clause SELECT est appelée projection, mais lorsqu'il n'est pas pratique de récupérer toutes les colonnes (il y a trop de colonnes, il y a de grandes colonnes telles que les LOB). C'est une méthode pratique.

Cette fois, je vais expliquer comment exprimer la projection avec l'API Criteria de Doma.

Il existe deux façons de réaliser une projection avec l'API Criteria.

La version de Doma utilisée ici est la 2.43.0.

Pour un aperçu de Doma et de l'API Criteria, lisez les autres articles dans Introduction à Doma.

Exemple de code utilisé dans cet article

Je vais l'expliquer avec un code simplifié. Voir le projet ci-dessous pour l'exemple de code complet.

La base de données contient une table d'employés qui représente les employés.

schema.sql


create table employee (
    id integer not null primary key,
    name varchar(255) not null,
    age integer not null,
    salary integer,
    job_type varchar(20),
    hiredate timestamp, 
    department_id integer, 
    version integer not null, 
    insertTimestamp timestamp, 
    updateTimestamp timestamp);

Préparez la classe Employé correspondant à la table Employé.

Employee.java


@Entity(metamodel = @Metamodel)
public class Employee {
  @Id
  Integer id;
  String name;
  Age age;
  Salary salary;
  @Column(name = "JOB_TYPE")
  JobType jobType;
  LocalDate hiredate;
  @Column(name = "DEPARTMENT_ID")
  Integer departmentId;
  @Version
  @Column(name = "VERSION")
  Integer version;
  LocalDateTime insertTimestamp;
  LocalDateTime updateTimestamp;

  // getter, setter
}

Préparez un DTO (ValueObject) qui contient le résultat projeté.

NameAndSalaryDto.java


public class NameAndSalaryDto {

  private final String name;
  private final Salary salary;

  public NameAndSalaryDto(String name, Salary salary) {
    this.name = name;
    this.salary = salary;
  }

  // getter
}

Nous préparerons ʻEmployeeRepository` et ajouterons quelques méthodes à cette classe pour montrer un exemple.

EmployeeRepository.java


public class EmployeeRepository {

  private final Entityql entityql;
  private final NativeSql nativeSql;

  public EmployeeRepository(Config config) {
    this.entityql = new Entityql(config);
    this.nativeSql = new NativeSql(config);
  }
}

Obtenir à l'aide de la classe d'entité

C'est une méthode très pratique dans le sens où vous pouvez réutiliser des structures de données existantes.

Vous pouvez utiliser la méthode selectTo pour définir la valeur projetée sur une propriété spécifique de l'entité (les autres propriétés sont définies sur des valeurs nulles ou initiales).

  public List<Employee> selectNameAndSalaryAsEntityList() {
    Employee_ e = new Employee_();
    return entityql.from(e).selectTo(e, e.name, e.salary).fetch();
  }

Le SQL émis est le suivant.

select t0_.id, t0_.name, t0_.salary from Employee t0_

Les deux colonnes, nom et salaire, sont le SQL spécifié dans la clause SELECT. Il contient une clé primaire non spécifiée, qui est par conception et est utilisée pour garantir l'unicité de l'entité dans l'ensemble de résultats.

Utiliser la classe tuple

Doma fournit des classes dans le package ʻorg.seasar.doma.jdbc.criteria.tuple qui représentent des combinaisons de valeurs telles que Tuple2, Tuple3, ..., Tuple9`. Le nombre à la fin du nom de la classe indique le nombre de valeurs que la classe peut gérer.

Voici un exemple de projection de deux colonnes à l'aide de la classe Tuple2.

  public List<Tuple2<String, Salary>> selectNameAndSalary() {
    Employee_ e = new Employee_();
    return nativeSql.from(e).select(e.name, e.salary).fetch();
  }

Notez que nous utilisons nativeSql au lieu de ʻentityql. Si vous n'avez pas besoin de gérer des entités avec des identifiants individuels (comme obtenir des résultats sans clé primaire ou utiliser des fonctions d'agrégation), nativeSql` est un bon choix.

Le SQL émis est le suivant.

select t0_.name, t0_.salary from Employee t0_

Seules deux colonnes, nom et salaire, sont le SQL spécifié dans la clause SELECT.

C'est à vous comment utiliser la classe Tuple2-9 dans quelle couche, mais c'est une belle conception de l'utiliser comme structure de données temporaire jusqu'à ce qu'elle soit convertie en DTO (ou ValueObject) de l'application comme indiqué ci-dessous. pense.

  public List<NameAndSalaryDto> selectNameAndSalaryAsNameAndSalaryDtoList() {
    Employee_ e = new Employee_();
    return nativeSql.from(e).select(e.name, e.salary).stream()
        .map(tuple -> new NameAndSalaryDto(tuple.getItem1(), tuple.getItem2()))
        .collect(Collectors.toList());
  }

Si vous spécifiez 10 colonnes ou plus et que vous les recevez, vous pouvez l'exprimer avec l'interface ʻorg.seasar.doma.jdbc.criteria.tuple.Row`, mais si vous avez un grand nombre de colonnes, utilisez une classe d'entité en lecture seule. Ce sera plus facile à comprendre si vous le créez.

en conclusion

J'ai expliqué comment représenter une projection avec l'API Criteria.

S'il y a quelque chose comme la classe Tuple dans la norme Java, j'aimerais l'utiliser, mais c'est ennuyeux qu'elle n'existe pas réellement.

De plus, la classe Tuple2-9 de Doma est également consciente qu'elle sera utilisée dans Kotlin, elle correspond donc à la déclaration de déstructuration. Par conséquent, Kotlin peut le gérer comme suit.

val (number, string) = Tuple2(1, "a")

Recommended Posts

Premiers pas avec Doma-Using Projection avec l'API Criteira
Premiers pas avec Doma-Using Joins avec l'API Criteira
Premiers pas avec les sous-requêtes utilisant Doma avec l'API Criteria
Premiers pas avec Doma - Introduction à l'API Criteria
Premiers pas avec Doma-Dynamic Construction de clauses WHERE avec l'API Criteria
Premiers pas avec Reactive Streams et l'API JDK 9 Flow
Premiers pas avec Doma-Criteria API Cheet Sheet
Démarrez avec le fonctionnement de JVM GC
Premiers pas avec DBUnit
Premiers pas avec Ruby
Premiers pas avec Swift
Premiers pas avec Doma-Transactions
Prise en main des opérateurs logiques utilisant Doma tels que AND et OR dans la clause WHERE de l'API Criteria
Premiers pas avec le traitement Doma-Annotation
Premiers pas avec JSP et servlet
Premiers pas avec les bases de Java
Premiers pas avec Spring Boot
Premiers pas avec les modules Ruby
Il est maintenant temps de commencer avec l'API Stream
Premiers pas avec Java_Chapitre 5_Exercices pratiques 5_4
[Google Cloud] Premiers pas avec Docker
Premiers pas avec Docker avec VS Code
Revenir au début, démarrer avec Java ② Instructions de contrôle, instructions de boucle
Résumer les principaux points de démarrage avec JPA appris avec Hibernate
Premiers pas avec Ruby pour les ingénieurs Java
Premiers pas avec Docker pour Mac (installation)
Introduction au test de paramétrage dans JUnit
Introduction à Java à partir de 0 Partie 1
Premiers pas avec Ratpack (4) - Routage et contenu statique
Premiers pas avec Language Server Protocol avec LSP4J
Premiers pas avec la création d'ensembles de ressources avec ListResoueceBundle
Premiers pas avec Java_Chapter 8_A propos des "Instances" et des "Classes"
Liens et mémos pour démarrer avec Java (pour moi-même)
Premiers pas avec Java 1 Assembler des éléments similaires
Premiers pas avec Kotlin à envoyer aux développeurs Java
J'ai essayé de démarrer avec Gradle sur Heroku
Revenir au début et démarrer avec Java ① Types de données et modificateurs d'accès
Prise en main des programmes Java à l'aide de Visual Studio Code
Premiers pas avec les anciens ingénieurs Java (Stream + Lambda)
Commencez avec Java sans serveur avec le framework léger Micronaut!