Je souhaite stocker l'objet en tant que type JSONB dans PostgreSQL lorsque Spring + Mybatis (l'instruction SQL est définie par Mapper XML)
Cette fois, j'en couvrirai deux.
Une fois du côté Java, créez-en une chaîne et transtypez-la en JSONB dans l'instruction SQL stockée. Utilisez com.fasterxml.jackson.databind.ObjectMapper
pour Object → String.
Appelant SQL
Object data = hoge(); //Données que vous souhaitez stocker
ObjectMapper mapper = new ObjectMapper();
String objectJSON = mapper.writeValueAsString(data)
sqlClient.insert(objectJSON)
MapperXML
<insert id="insert">
insert into hogetable (data) values (#{objectJSON}::jsonb);
</insert>
Si la chaîne est au format JSON, elle sera stockée.
En parlant de travailler avec cela, cela fonctionne, mais si possible, j'aimerais le garder en tant qu'objet en Java. Il est difficile pour l'appelant de se donner la peine de le formater pour qu'il soit facile à utiliser pour l'appelant.
Par conséquent, du côté Java, conservez l'objet tel quel et convertissez-le au format JSON en ** Mapper XML. ** Cela résoudra les problèmes mentionnés précédemment.
Commencez par concevoir l'interface Mapper comme suit. Le fait est que pour exécuter com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString
dans Mapper XML, ʻObjectMapper` est également entrepris.
Interface du mappeur
insert(@Param("objectMapper") ObjectMapper objectMapper, @Param("object") Object object);
L'appelant passe simplement ʻObjectMapper` et l'objet que vous voulez stocker.
Appelant SQL
Object data = hoge(); //Données que vous souhaitez stocker
ObjectMapper mapper = new ObjectMapper();
sqlClient.insert(mapper, data)
Mapper XML utilise également ** des expressions de liaison. ** **
MapperXML
<insert id="insert">
<bind name="objectJSON" value="objectMapper.writeValueAsString(object)" />
insert into hogetable (data) values ('${objectJSON}'::jsonb)
</insert>
Dans l'expression de liaison, la valeur écrite dans value est affectée à la variable spécifiée par nom. À ce stade, non seulement la valeur elle-même mais également l'expression ** peuvent être écrites dans la valeur. ** **
Les instructions sql suivantes peuvent être référencées avec $ {nom de variable}
. Cependant, $ {nom de la variable}
est juste un remplacement, vous devez donc le mettre entre guillemets simples pour en faire une chaîne (type de texte dans PostgreSQL). De plus, vous ne devriez pas vraiment utiliser $ {}
. C'est juste un remplacement qui le rend vulnérable à l'injection ** SQL. ** **
En fait, je devrais utiliser le # {}
qui résout ce problème, mais je ne pourrais pas bien y faire référence ...
Après tout, je l'ai atteint car le but de cet article est de déplacer le mappage Objet → Chaîne du côté Java vers le côté Mybatis.
Cependant, puisque l'appelant prépare le mappeur, je ne pense pas que l'on puisse dire que le traitement a été complètement transféré. Si le contenu de traitement du côté Mybatis est à nouveau modifié, le côté Java doit également être modifié. Lorsque je tente d'implémenter une architecture résistante au changement **, je ne veux pas compter sur des connexions externes. ** **
À cet égard, ce serait bien si Mybatis pouvait préparer un mappeur. Si l'appelant peut préparer le mappeur, l'appelant n'a qu'à transmettre les données lui-même. Si je trouve un moyen de le faire, je le mettrai à jour à nouveau.