[JAVA] Compréhension étape par étape de la cartographie O / R

introduction

Qu'est-ce que le mappage O / R?

Le mappage O / R est, en un mot, un moyen de manipuler les enregistrements de base de données relationnelle en tant qu'objets normaux dans un langage de programmation orienté objet. Il est plus facile de voir le code réel que de donner une définition plus détaillée. Voici des exemples d'utilisation de l'API JDBC de bas niveau et de JPA, qui est un représentant du cadre de mappage O / R de haut niveau.

public List<Issue> findByProjectId(long projectId) {
  String query = "select id, title, description from issue where project_id = ?";
  try (PreparedStatement ps = connection.prepareStatement(query)) {
    ps.setLong(1, projectId);
    List<Issue> issues = new ArrayList<>();
    try (ResultSet rs = ps.executeQuery()) {
      while (rs.next()) {
        Issue issue = new Issue();
        issue.setId(rs.getLong("id"));
        issue.setTitle(rs.getString("title"));
        issue.setDescription(rs.getString("description"));
        issues.add(issue);
      }
    }
    return issues;
  } catch (SQLException e) {
    throw new RuntimeException(e);
  }
}
public List<Issue> findByProjectId(long projectId) {
  String query = "select i from Issue i where i.project.id = ?1";
  List<Issue> issues = entityManager.createQuery(query, Issue.class)
      .setParameter(1, projectId).getResultList();
  return issues;
}

La différence est claire lorsque l'on compare les deux. Ce dernier, qui utilise un mappage O / R de haut niveau, élimine le besoin de descriptions de routine et exprime l'intention plus clairement.

Cartographie O / R mal comprise

Le mappage O / R semble bon dans l'exemple ci-dessus, mais il y a beaucoup de plaintes dans le monde. Certains sont radicaux, comme le refus de tous les mappages O / R, tandis que d'autres refusent les cadres de mappage O / R de haut niveau et préfèrent l'utilisation d'alternatives plus simples. Dans une telle situation, la position de promouvoir activement l'utilisation d'un cadre de cartographie O / R de haut niveau semble être plutôt minoritaire.

Il y a deux raisons principales pour lesquelles le mappage O / R n'est pas apprécié. La première raison peut être que les cadres de mappage O / R de haut niveau ne semblent pas écouter les programmeurs. De nombreuses personnes ont de l'expérience dans l'utilisation du framework de mappage O / R, qui ont eu des difficultés à gérer les problèmes de performances car SQL n'a pas été exécuté comme prévu sous le capot. Sous-jacent, cela semble être un malentendu sur le mécanisme de base de la cartographie O / R. La deuxième raison peut être que la cartographie O / R de haut niveau est souvent utilisée dans des projets qui ne lui conviennent pas. Comme nous le verrons plus en détail plus tard, l'utilisation d'un cadre de cartographie O / R de haut niveau dans des situations où des conditions préalables telles que la discrétion du schéma ne sont pas remplies est proche du suicide. Sous-jacent, cela semble être un malentendu sur les critères pour une utilisation appropriée de la cartographie O / R.

Résumé de cet article

Dans cet article, afin de résoudre le malentendu ci-dessus, je vais montrer qu'il existe plusieurs niveaux de mappage O / R. En examinant pas à pas les moyens de bas niveau à haut niveau, quel genre de problème le mécanisme de base de chaque niveau est apparu comme une solution et quels critères devraient être utilisés pour chaque niveau de moyens. Vous devez savoir quoi faire.

5 niveaux

Dans cet article, j'expliquerai le mappage O / R en cinq niveaux:

--Niveau 1: API de bas niveau --Niveau 2: abstraction du prétraitement et du post-traitement --Niveau 3: Requête et mappage d'objets simples --Niveau 4: Mappage des requêtes et des objets navigables associés --Niveau 5: mappage table-objet

Ces réglages de niveau ne sont fournis qu'à titre explicatif. Les fonctionnalités de divers frameworks de mappage Java O / R se chevauchent en fait à plusieurs niveaux. De plus, par souci de concision, le type de traitement cible est réduit au système de référence et le système de mise à jour est omis.

Étant donné que le sujet traite de divers frameworks Java réels, il doit être lu comme une brève introduction à ceux-ci. Cependant, il ne vise pas à être une explication exhaustive de la fonction, donc si vous voulez en savoir plus, veuillez vous référer au document officiel lié à.

Niveau 1: API de bas niveau

Tout d'abord, examinons l'accès aux données à l'aide de l'API JDBC intégrée à JDK telle quelle. A titre d'exemple, je vais réimprimer le code donné au début de cet article.

public List<Issue> findByProjectId(long projectId) {
  String query = "select id, title, description from issue where project_id = ?";
  try (PreparedStatement ps = connection.prepareStatement(query)) {
    ps.setLong(1, projectId);
    List<Issue> issues = new ArrayList<>();
    try (ResultSet rs = ps.executeQuery()) {
      while (rs.next()) {
        Issue issue = new Issue();
        issue.setId(rs.getLong("id"));
        issue.setTitle(rs.getString("title"));
        issue.setDescription(rs.getString("description"));
        issues.add(issue);
      }
    }
    return issues;
  } catch (SQLException e) {
    throw new RuntimeException(e);
  }
}

Le sujet est une simple application de gestion des tâches. Le contenu de traitement du code ci-dessus est une extraction par l'ID de projet du problème.

La définition de la table ʻissue` ressemble à ceci:

create table issue
(
   id bigint primary key,
   project_id bigint,
   title varchar (100),
   description text
);

Comment utiliser

Ce que vous devez faire pour utiliser ce niveau d'approche est:

--Spécifier une chaîne de requête --Spécifier les paramètres de requête --Exécuter la requête

Tâche

La complexité de la description de routine est un problème. Pour les rédacteurs de code, c'est trop à écrire pour du code qui exécute simplement des requêtes et récupère les résultats. Même du côté de la lecture du code, l'intention est enfouie dans le code supplémentaire et il est difficile à comprendre.

De plus, les risques liés à la gestion des ressources ne peuvent être négligés. Si vous oubliez le processus de fermeture pris en charge à l'aide de try-with-resources dans l'exemple ci-dessus, une fuite de ressources se produira.

Les critères de sélection

À partir de 2019, il y a peu d'occasions dans le code de production où ce niveau d'approche devrait être adopté. Vous pouvez avoir la possibilité d'utiliser ce niveau d'approche uniquement si vous êtes extrêmement conscient des performances ou si, pour une raison quelconque, votre utilisation du framework est restreinte. Cependant, même dans ces cas, il est facile de réaliser soi-même la méthode équivalente au niveau 2 décrite plus loin.

Niveau 2: abstraction pré-traitement et post-traitement

Parmi les descriptions standard de niveau 1, celles liées au prétraitement et au post-traitement peuvent être résumées relativement facilement. Voici un exemple utilisant Jdbi.

public List<Issue> findByProjectId(long projectId) {
  String query = "select id, title, description from issue where project_id = ?";
  List<Issue> issues = handle.createQuery(query).bind(0, projectId)
      .map((rs, ctx) -> {
        Issue issue = new Issue();
        issue.setId(rs.getLong("id"));
        issue.setTitle(rs.getString("title"));
        issue.setDescription(rs.getString("description"));
        return issue;
      }).list();
  return issues;
}

Comment utiliser

Ce que vous devez faire pour utiliser ce niveau d'approche est: Il est clairement réduit par rapport au niveau 1.

--Spécifier une chaîne de requête --Spécifier les paramètres de requête --Exécuter la requête --Remplir les enregistrements en objets

Tâche

Bien que le prétraitement et le post-traitement aient été résumés, le réenregistrement des enregistrements en objets est toujours fastidieux. Étant donné que le code ci-dessus n'est qu'un exemple, le nombre de colonnes est limité, mais dans un projet réel, une description standard sera requise pour de nombreuses colonnes.

Framework Java typique

Il n'y a pas de framework dédié à ce niveau, mais Jdbi et Spring JdbcTemplate Les frameworks avec des fonctionnalités de niveau 3, telles que /spring-framework-reference/data-access.html#jdbc-JdbcTemplate), ont également des fonctionnalités de niveau 2.

De plus, comme mentionné au niveau 1 «Critères de sélection», il est facile de créer vous-même un cadre de ce niveau. Ce devrait être une bonne plateforme de pratique pour vous familiariser avec Lambda.

Les critères de sélection

Il n'y a pas beaucoup de situations où ce niveau de méthode devrait être adopté. Comme pour le niveau 1, c'est une option si les performances sont extrêmement importantes ou si, pour une raison quelconque, l'utilisation du framework est restreinte.

De plus, si la structure des enregistrements et des objets est très différente et que vous devez écrire manuellement des processus de mappage flexibles, vous pouvez oser rester à ce niveau au lieu du niveau 3.

Niveau 3: Requête et mappage d'objets simples

Le niveau 3 automatise le remplissage des enregistrements vers des objets pris en charge manuellement au niveau 2. Voici un exemple utilisant une autre API de Jdbi qui est identique au niveau 2.

public List<Issue> findByProjectId(long projectId) {
  handle.registerRowMapper(BeanMapper.factory(Issue.class));
  String query = "select id, title, description from issue where project_id = ?";
  List<Issue> issues = handle.createQuery(query).bind(0, projectId)
      .mapTo(Issue.class).list();
  return issues;
}

Comment utiliser

Ce que vous devez faire pour utiliser ce niveau d'approche est:

--Spécifier une chaîne de requête --Spécifier les paramètres de requête --Exécuter la requête

Tâche

À première vue, ce niveau d'approche peut paraître polyvalent, mais l'absence de navigation associée des objets est un défaut sérieux. L'application réelle se compose de plusieurs tables. Par exemple, dans le cas de l'application de gestion des problèmes simple qui fait l'objet de cet article, en plus de la table «issue», il devrait y avoir une table «projet» liée plusieurs-à-un et une table «commentaire» liée un-à-plusieurs. Pour les idées orientées objet, il est naturel que de telles données soient accessibles en tant qu'objets liés par des méthodes telles que ʻIssue # getProject () et ʻIssue # getComments (). Cependant, une telle navigation associée ne peut pas être réalisée avec ce niveau d'approche.

À ce niveau de technique, vous ne pouvez obtenir qu'un seul objet ou une liste d'objets (structure de table bidimensionnelle). Si vous souhaitez obtenir un accès aux données équivalent à la navigation associée, vous pouvez soit écrire la logique pour l'obtenir dans des requêtes distinctes et la fusionner vous-même, soit la forcer en tant qu'objet JOIN.

Sous ces contraintes, la réalisation d'une architecture qui suppose un modèle de domaine riche tel que la conception pilotée par domaine est sans espoir. En conséquence, les modèles individuels entraînés par la commodité d'afficher chaque écran prolifèrent, ce qui donne une application centrée sur l'écran plutôt qu'une application centrée sur le domaine. Il n'y a pas d'option pour recharger les objets acquis par cette méthode de niveau dans un modèle de domaine riche par vous-même, mais il est souvent moins cher d'apprendre la méthode de niveau 4-5 docilement que de faire une chose aussi gênante. Tu devrais avoir fini.

De plus, dans une interface utilisateur telle que OOUI qui offre une interaction gratuite aux utilisateurs, la navigation associée est presque une fonction essentielle. Les modèles sans navigation associée peuvent éventuellement entraver la réalisation d'une interface utilisateur facile à utiliser.

Framework Java typique

Les frameworks typiques à ce niveau sont Jdbi et [Spring JdbcTemplate](https://docs.spring.io/spring-framework/docs/current/spring- framework-reference / data-access.html # jdbc-JdbcTemplate). À proprement parler, les deux peuvent gérer un accès aux données équivalent au niveau 4 si vous faites de votre mieux (bien que Exemple Comme vous pouvez le voir dans la relation à plusieurs avec jdbi-sql-object-api), c'est compliqué). Il existe également de nombreuses autres options, telles que sql2o et le nostalgique Commons DbUtils.

De plus, Doma, qui a gagné un certain support en tant que simple cadre de mappage O / R, ne prend en charge que le niveau 3 pour les systèmes de référence. Ne pas. C'est obstinément [Ne pas prendre en charge la navigation associée en tant que concept de conception](https://doma.readthedocs.io/en/stable/faq/#does-doma-map-database-relationships-such-as-one -to-one-and-one-to-many-to-java-objects) est indiqué.

Les critères de sélection

Il devrait y avoir des situations où ce niveau d'approche est suffisant, comme une application avec une interface utilisateur standard ou un lot avec un accès simple aux données. Espérons que ce ne sera pas un développement commun si les exigences réelles n'étaient ni standard ni simples, contrairement à l'hypothèse initiale.

Niveau 4: Mappage des requêtes et des objets navigables associés

Jetons un coup d'oeil à un exemple de réalisation utilisant MyBatis pour la navigation associée qui n'a pas pu être réalisée au niveau 3.

Tout d'abord, la définition de la table «project» comment »associée à la table« issue »est la suivante.

create table project
(
   id bigint primary key,
   name varchar (100)
);
create table comment
(
   id bigint primary key,
   issue_id bigint,
   description text
);

Ensuite, la classe Java à mapper est indiquée ci-dessous.

@Data
public class Issue {
	private long id;
	private Project project;
	private List<Comment> comments;
	private String title;
	private String description;
}
@Data
public class Project {
	private long id;
	private String name;
}
@Data
public class Comment {
	private long id;
	private String description;
}

En outre, écrivez des paramètres pour les mapper. Ici, la méthode basée sur XML est utilisée (notez que MyBatis a également la méthode basée sur les annotations //mybatis.org/mybatis-3/ja/java-api.html#Mapper_.E3.82.A2.E3.83.8E.E3.83.86.E3.83.BC.E3.82.B7.E3. Il existe également 83.A7.E3.83.B3)).

<resultMap id="issueResult" type="Issue" autoMapping="true">
  <id property="id" column="id" />
  <association property="project" column="project_id"
    select="Project.find" />
  <collection property="comments" column="id"
    select="Comment.findByIssueId" />
</resultMap>
<select id="findByProjectId" parameterType="long"
  resultMap="issueResult">
  <![CDATA[
    select
      id,
      project_id,
      title,
      description
    from
      issue
    where
      project_id = #{projectId}
  ]]>
</select>
<resultMap id="projectResult" type="Project"
  autoMapping="true">
  <id property="id" column="id" />
</resultMap>
<select id="find" parameterType="long"
  resultMap="projectResult">
  <![CDATA[
    select
      id,
      name
    from
      project
    where
      id = #{id}
  ]]>
</select>
<resultMap id="commentResult" type="Comment"
  autoMapping="true">
  <id property="id" column="id" />
</resultMap>
<select id="findByIssueId" parameterType="long"
  resultMap="commentResult">
  <![CDATA[
    select
      id,
      description
    from
      comment
    where
      issue_id = #{issueId}
  ]]>
</select>

Enfin, l'accès aux données est effectué en fonction des paramètres ci-dessus.

public List<Issue> findByProjectId(long projectId) {
  return sqlSession.selectList("Issue.findByProjectId", projectId);
}

Comment utiliser

Ce que vous devez faire pour utiliser ce niveau d'approche est:

--Spécifier une chaîne de requête --Dans l'exemple ci-dessus, il est spécifié dans les paramètres XML. --Définir le résultat de la requête et le mappage d'objets --Dans l'exemple ci-dessus, il est spécifié dans les paramètres XML. --Spécifier les paramètres de requête --Exécuter la requête

Tâche

Maintenant que la navigation associée est possible, ce n'est pas facile à configurer, comme vous pouvez le voir dans l'exemple. En outre, lorsque les types de requêtes de référence augmentent ou lorsqu'un traitement d'insertion / mise à jour / suppression de mise à jour est nécessaire, il est nécessaire d'écrire manuellement SQL à chaque fois. Comme cela sera décrit plus loin, il existe des contre-mesures par génération automatique, mais l'effet est limité.

Il existe également une faiblesse dans l'abstraction du traitement de routine. Ce niveau est destiné au traitement de routine qui peut être facilement extrait par des méthodes de niveau 5, telles que la saisie automatique des colonnes d'audit (date et heure d'enregistrement, date et heure de mise à jour, utilisateur enregistré, utilisateur de mise à jour, ...) et verrouillage optimiste par numéro de version. Avec cette méthode, vous devez à chaque fois écrire manuellement SQL.

De plus, en tant que problème commun à tous les niveaux jusqu'à présent, tant que SQL est écrit manuellement, il existe une dépendance à un SGBD spécifique. Il est difficile de répondre à toutes les exigences avec un SQL conforme aux normes qui prend en compte la portabilité. Il y a peu d'occasions de prendre conscience de ce problème dans le développement quotidien, mais quand l'histoire de la rénovation à grande échelle comme le remplacement du système se présente, la gravité de la situation devient immédiatement apparente.

Notez que le problème N + 1 qui saccage au niveau 5 peut également se produire à ce niveau. Cependant, ce niveau d'approche ne fonctionne que lorsque vous avez écrit le SQL, vous en êtes donc responsable, pas le cadre, et vous savez comment le gérer. Par exemple, dans l'exemple ci-dessus, le problème N + 1 se produit réellement, mais le problème peut être résolu en remplaçant SQL par celui utilisant JOIN comme indiqué ci-dessous.

<resultMap id="issueResultWithProjectAndComments"
  type="Issue" autoMapping="true">
  <id property="id" column="id" />
  <association property="project" columnPrefix="p_"
    resultMap="Project.projectResult" />
  <collection property="comments" columnPrefix="c_"
    resultMap="Comment.commentResult" />
</resultMap>
<select id="findByProjectIdWithProjectAndComments"
  parameterType="long" resultMap="issueResultWithProjectAndComments">
  <![CDATA[
    select
      i.id as id,
      i.project_id as project_id,
      i.title as title,
      i.description as description,
      p.id as p_id,
      p.name as p_name,
      c.id as c_id,
      c.description as c_description
    from
      issue i
      inner join project p on i.project_id = p.id
      left outer join comment c on i.id = c.issue_id
    where
      project_id = #{projectId}
  ]]>
</select>

Mécanisme auxiliaire

Ce niveau d'approche s'accompagne des mécanismes suivants:

Framework Java typique

Un framework typique à ce niveau est MyBatis mentionné dans l'exemple. En raison de sa longue histoire, il dispose d'un ensemble complet de fonctions répertoriées dans "Mécanismes attachés".

De plus, à propos de JPA qui apparaît au niveau 5, il fait partie de Native Query. /5.4/userguide/html_single/Hibernate_User_Guide.html#sql) peut être considérée comme une technique de niveau 4. Cependant, par rapport à MyBatis, il existe une différence dans la facilité d'utilisation des fonctions de base et la prise en charge des fonctions répertoriées dans "Mécanisme attaché".

Les critères de sélection

Les chaînes de base de données peuvent être une raison de choisir une approche de niveau 4. Les «grands-pères» sont, par exemple, des schémas hérités qui ne peuvent pas être modifiés, des structures de données incompatibles avec les exigences d'interface utilisateur et les exigences de déviation SQL existantes.

De plus, étant donné un modèle de domaine riche avec une conception axée sur le domaine, une approche de niveau 4, qui est supérieure au niveau 5 en termes de flexibilité de configuration de mappage, est une option viable.

En outre, compte tenu des exigences de performance et des compétences des membres de l'équipe, vous pouvez choisir l'approche de niveau 4 comme alternative à faible risque et à faible rendement aux risques de performance de niveau 5.

Niveau 5: mappage table-objet

Au niveau 4, j'ai écrit SQL manuellement à chaque fois, mais en premier lieu, la structure des tables et des objets est similaire à bien des égards dans les applications générales, donc si vous pouvez bien les mapper, vous devriez pouvoir économiser du travail. Ci-dessous, regardons un exemple utilisant Hibernate ORM conforme à la norme JPA. ..

Le schéma de la base de données est le même que jusqu'au niveau 4. La classe Java à mapper est la même que le niveau 4, mais l'annotation pour le paramètre de mappage est ajoutée.

@Data
@Entity
public class Issue {
	@Id
	private long id;
	@ManyToOne
	@JoinColumn(name = "project_id")
	private Project project;
	@OneToMany
	@JoinColumn(name = "issue_id")
	private List<Comment> comments;
	private String title;
	private String description;
}
@Data
@Entity
public class Project {
	@Id
	private long id;
	private String name;
}
@Data
@Entity
public class Comment {
	@Id
	private long id;
	private String description;
}

Accédez aux données en fonction de ce qui précède.

public List<Issue> findByProjectId(long projectId) {
  String query = "select i from Issue i where i.project.id = ?1";
  List<Issue> issues = entityManager.createQuery(query, Issue.class)
      .setParameter(1, projectId).getResultList();
  return issues;
}

Comment utiliser

L'utilisation de cette méthode de niveau est la suivante.

--Définir le mappage table-objet --Dans l'exemple ci-dessus, il est spécifié par une annotation.

Tâche

Un défi majeur pour ce niveau d'approche est la dégradation des performances due à l'émission involontaire de SQL, dont le plus typique est le problème N + 1. Le problème N + 1 est que pour N enregistrements renvoyés dans une seule requête à la table principale, la table associée est interrogée N fois. Basé sur l'application de gestion des problèmes qui fait l'objet de cet article, dans l'accès aux données de l'écran de la liste des problèmes, après qu'une seule requête à la table ʻissue soit exécutée, ʻIssue # getComments () dans une boucle. Quand ʻest appelé à chaque fois, la table comment est interrogée N fois, ce qui équivaut au nombre d'enregistrements ʻissue obtenus dans la requête précédente.

L'une des principales solutions au problème N + 1 dans JPA est FETCH JOIN Est. Par exemple, dans l'exemple ci-dessus, le problème N + 1 se produit réellement, mais le problème peut être supprimé en remplaçant la requête par celle utilisant FETCH JOIN comme indiqué ci-dessous.

public List<Issue> findByProjectIdWithProjectAndComments(long projectId) {
  String query = "select distinct i from Issue i join fetch i.project"
      + " left join fetch i.comments where i.project.id = ?1";
  List<Issue> issues = entityManager.createQuery(query, Issue.class)
      .setParameter(1, projectId).getResultList();
  return issues;
}

La requête SQL qui est réellement générée ressemble à ceci:

select
    distinct issue0_.id as id1_1_0_,
    project1_.id as id1_2_1_,
    comments2_.id as id1_0_2_,
    issue0_.description as descript2_1_0_,
    issue0_.project_id as project_4_1_0_,
    issue0_.title as title3_1_0_,
    project1_.name as name2_2_1_,
    comments2_.description as descript2_0_2_,
    comments2_.issue_id as issue_id3_0_0__,
    comments2_.id as id1_0_0__
from
    issue issue0_
inner join
    project project1_
        on issue0_.project_id=project1_.id
left outer join
    comment comments2_
        on issue0_.id=comments2_.issue_id
where
    issue0_.project_id=?

En plus de FETCH JOIN, comment utiliser @Fetch (FetchMode.SUBSELECT) Ou vous pouvez utiliser Entity Graph .. Aussi, @Where et @Filter Dans certains cas, un contrôle affiné, tel que /hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#pc-filter) est requis.

Il existe diverses mesures de la performance comme décrit ci-dessus, mais c'est l'un des principaux problèmes liés à l'introduction du niveau 5 que le coût d'apprentissage initial n'est pas minime pour les apprendre. Peut-être que dans de nombreux contextes, ces coûts ne sont pas consciemment payés à l'avance, et les problèmes de performance qui en résultent sont vaguement imputés au cadre. Si des outils d'analyse tels que Hypersistence Optimizer peuvent être utilisés, le coût d'apprentissage initial devrait être réduit dans une certaine mesure.

Il y a aussi le problème des lacunes de la norme JPA. Par exemple, implémenté dans le comportement de Entity Graph ci-dessus. Il existe une partie de dépendance, ainsi que @Where et [@Filter](https: // docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#pc-filter) est une fonctionnalité dépendant de l'implémentation Hibernate non standardisée.

En outre, à titre de limitation en premier lieu, il y a un point que l'effet ne peut pas être attendu dans un projet dans lequel la similitude structurelle entre la table et l'objet, qui est la prémisse du niveau 5, est faible en termes d'exigences. Dans de tels cas, la méthode de niveau 3-4, qui vous permet d'écrire librement des requêtes, est plus appropriée.

Mécanisme auxiliaire

Ce niveau d'approche s'accompagne des mécanismes suivants:

--La gestion du cycle de vie

Framework Java typique

Un framework typique à ce niveau est le standard JPA. En plus de l 'Hibernate ORM abordé dans cet article, le système d'implémentation JPA est EclipseLink. Il existe également eclipselink /). L'implémentation que vous choisissez dépendra de celle par défaut pour votre serveur d'applications et votre infrastructure de niveau supérieur.

De plus, EBean et jOOQ mentionnés dans "Attached Mechanism" et [Reladomo](https: // github) Il existe des alternatives comme .com / goldmansachs / reladomo). Étant donné qu'ils sont tous non standard et qu'ils créent une dépendance, en particulier avec jOOQ et Reladomo, vous devez être prudent lorsque vous faites vos choix.

Les critères de sélection

Comme mentionné dans la tâche, il existe des conditions préalables strictes pour les coûts et les schémas d'apprentissage initial lors de l'utilisation de ce niveau d'approche. On peut s'attendre à des rendements de productivité élevés si les conditions préalables sont remplies, mais sinon, cela peut être un gaspillage de main-d'œuvre.

De plus, si certaines restrictions imposent la conformité aux normes, vous pouvez ignorer le niveau 3-4 et n'avoir que le niveau 5 JPA (comme mentionné ci-dessus, vous pouvez utiliser la fonction de requête native équivalente au niveau 4).

Comment choisir le meilleur niveau de méthode pour votre projet

Maintenant, quel niveau de méthode doit être sélectionné dans quelle situation est quelque peu dupliqué avec la description des "critères de sélection" de chaque niveau, mais revenons rapidement en arrière.

Premièrement, il est rare de commencer au niveau 1-2. La première décision est souvent de savoir si le niveau 3 est suffisant ou le niveau 4-5.

Les techniques de niveau 3 peuvent suffire si la complexité du projet est faible. Cependant, il n'y a pas d'indice unique et facile à comprendre concernant la complexité, et il est nécessaire de porter un jugement complet en fonction des caractéristiques de l'interface utilisateur, des caractéristiques d'accès aux données, de l'échelle du projet, de la composition du personnel de l'équipe, etc.

Si votre projet est très complexe, choisissez parmi les niveaux 4-5. La méthode de niveau 4 est probablement appropriée si le schéma est hérité ou nécessite une certaine ingéniosité dans la cartographie et que vous souhaitez vous concentrer sur une faible incertitude, sinon la méthode de niveau 5 est probablement appropriée.

Il convient de noter que le fait que la méthode actuelle de niveau 5 ne soit pas achevée complique le problème. S'il y a des améliorations telles que rendre facultative la gestion du cycle de vie avec un coût d'apprentissage initial élevé, simplifier les spécifications de contrôle de navigation associées et les incorporer dans la norme, et leur permettre d'être combinées avec des techniques riches de niveau 4 si nécessaire. , Il devrait y avoir plus d'occasions de choisir une méthode plus de niveau 5.

(A part) A partir de quel niveau se trouve le "mapping O / R"?

Il n'est pas évident à partir de quel niveau il devrait être appelé "Mappage O / R". Il n'y aurait aucune objection à appeler la cartographie O / R d'approche de niveau 5. En outre, peut-être que la méthode de niveau 4, avec le préfixe «largement défini», semble avoir peu d'objection à l'appeler mappage O / R. Cependant, pour les méthodes de niveau 3, il existe des cas comme JDBC appelé quelque chose qui est différent du mappage O / R, et comme Doma dans le passé. Dans certains cas, proclamé être un mappeur O / R. En outre, même pour les méthodes qui appartiennent à l'origine au niveau 1-2, l'interface du composant d'accès aux données est techniquement la même que celle du niveau 3-5 (référentiel qui ressemble au mappage O / R vu d'en haut). Peut être fourni.

Il peut y avoir plusieurs positions concernant le niveau de "Mappage O / R" comme suit. Je ne pense pas que ce sera un débat très productif sur la position qui convient, alors je n'entrerai pas dans le vif du sujet.

--Position à considérer comme une méthode de conception

en conclusion

Comme mentionné ci-dessus, concernant la cartographie O / R, les niveaux sont divisés en 5 niveaux, et il est montré que chacun a ses propres critères d'inévitabilité et d'utilisation appropriée. Nous espérons que cet article réduira les malentendus sur la cartographie O / R et les inadéquations malheureuses dans la sélection des technologies élémentaires sur le site de développement.

Recommended Posts

Compréhension étape par étape de la cartographie O / R
Compréhension étape par étape de la gestion des exceptions Java
Prise en compte du SIG et du Mappeur O / R
Mécanisme de conversion de type de données flexible de la bibliothèque de mappage O / R Lightsleep pour Java 8
Je l'ai utilisé sans connaître la cartographie O / R des rails, donc je l'ai vérifié.
[Java] Compréhension débutante de Servlet-②
[Java] Compréhension débutante de Servlet-①
Mémorandum sur LOD.