例)jbooks というテーブルの列名=jdata が JSONB型だとする。
ObjectMapper の writeValueAsString に頼る方法
SQLMap XML で bindタグで、writeValueAsString が働くようにする。
<insert id="insertJbook"> <bind name="jdata" value="objectMapper.writeValueAsString(object)" /> INSERT INTO jbooks (id, title, jdata) VALUES(#{id}, #{title}, '${jdata}'::jsonb ) </insert>
'${jdata}'::jsonb のように文字列出力してマッピングする。
Mapper Interface はSQLMap XMLに合わせて以下のとおり、
第3引数に、ObhjectMapperインスタンス、第4引数にJSONとして格納するインスタンスを指定
public int insertJbook(@Param("id")int id, @Param("title")String title, @Param("objectMapper")ObjectMapper objectMapper, @Param("object")Object object );
JSON用のTypeHandleを用意してタイプハンドラを使用する方法
用意するタイプハンドラは、
こちらのように用意する。MySQL 使用する時に書いたものだが、PostgreSQL でも注意すれば使える。
(⇒注意すること。 ::jsonb によるJSON 文字列から JSONB型への変換を指定すれば良い)
MySQL JSON型をmybatis で読み書きするサンプル - Oboe吹きプログラマの黙示録
Mapper Interface は、JSONB型の列で用意したタイプハンドラを指定
@Insert("INSERT INTO jbooks (id, title, jdata)VALUES(#{id}, #{title}, #{jdata, typeHandler=org.sample.JsonTypeHandler}::jsonb )") public int insertJbook(@Param("id")int id, @Param("title")String title, @Param("jdata")ItemDto object);
用意したタイプハンドラ
package org.sample; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import org.yipuran.mybatis.types.AbstractJsonTypeHandler; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; public class JsonTypeHandler<T> extends AbstractJsonTypeHandler<T> { public JsonTypeHandler(Class<T> clazz){ super(clazz); } @Override public SimpleModule getModule(){ JavaTimeModule jtm = new JavaTimeModule(); jtm.addSerializer(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))) .addSerializer(new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))) .addSerializer(LocalTimeSerializer.INSTANCE) .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))) .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))) .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ISO_LOCAL_TIME)); return jtm; } }
import して継承している AbstractJsonTypeHandler は、
以下に書いている。
https://github.com/yipuran/yipuran-mybatis/blob/master/src/main/java/org/yipuran/mybatis/types/AbstractJsonTypeHandler.java
LocalDateTime など、細かい仕様を1つで引き受けて定義するなら、
カスタマイズした TypeHandller を用意した方が楽であろう。