Mybatis自动映射Java对象 与 MySQL8后的JSON数据

Mybatis自动映射Java对象 与 MySQL8后的JSON数据

1.转化成为正常Json类型

自认为
优点:数据库存储为单纯的数据,不需要额外存储类型
缺点:不够通用 对于Map、Object、List<T>能用,但是对于List<List<T>>不太行
          需要写两个Typehander不够优雅

接下来,简单过一下流程(只有插入和查找)

1.1 JsonTypeHander

notice: 使用的转换JSON工具是hutool中的,如果自己有别的转换可以使用别的json转换工具

hutool工具包

<dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.11</version>
        </dependency>

JsonTypeHandler 这个负责非List,一般存储的都是Map,Object,和List

public class JsonTypeHandler<T> extends BaseTypeHandler<T>{
    private Class<T> clazz;
    //在Mybatis中将类型注入进来
    public JsonTypeHandler(Class<T> clazz) {
        this.clazz = clazz;
    }
        //写入数据
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, JSONUtil.toJsonStr(parameter));
    }

    /**
     * 一般是根据列名字获取下方就不再详述“(因为我也不知道,还没用到)
     * @param rs  结果
     * @param colName 列名
     */
    @SneakyThrows
    @Override
    public  T getNullableResult(ResultSet rs, String colName) {
        String data = rs.getString(colName);
        return StrUtil.isBlank(data) ? null : JSONUtil.toBean(data, clazz);
    }

    @SneakyThrows
    @Override
    public T getNullableResult(ResultSet rs, int colIndex) {
        String data = rs.getString(colIndex);
        return StrUtil.isBlank(data) ? null : JSONUtil.toBean(data, clazz);
    }

    @SneakyThrows
    @Override
    public T getNullableResult(CallableStatement cs, int i) {
        String data = cs.getString(i);
        return StrUtil.isBlank(data) ? null : JSONUtil.toBean(data, clazz);
    }
    
}

1.2 ListJsonTypeHandler 负责List 类型

public class ListJsonTypeHandler<T> extends BaseTypeHandler<List<T>> implements InitializingBean {
    private Class<T> clazz;

    public ListJsonTypeHandler(Class<T> clazz) {
        this.clazz = clazz;
    }
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, JSONUtil.toJsonStr(parameter));
    }
    @Override
    public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String data = rs.getString(columnName);
        return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
    }

    @SneakyThrows
    @Override
    public List<T> getNullableResult(ResultSet rs, int colIndex) {
        String data = rs.getString(colIndex);
        return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
    }

    @SneakyThrows
    @Override
    public List<T> getNullableResult(CallableStatement cs, int i) {
        String data = cs.getString(i);
        return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
    }

1.3 实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Json {
    /**
     * 唯一标识
     */
    private Integer id;

    /**
     * map
     */
    private Map<String,Object> mapJson;

    /**
     * 对象
     * 这个对象自定义的放在下面
     */
    private Object objJson;

    /**
     * list集合
     * <? extends Object>这个我也不知道怎么设置  但是用这个没错
     */
    private List<? extends Object> listJson;
}

//测试的对象
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class JsonObj {
    /**
     * 唯一id
     */
    private Integer id;

    /**
     * 测试所用
     */
    private String str;
}

1.4 mapper

//查找 不建议用 * 代替 我是为啦偷工减料
    @Select(" SELECT * from json ")
    @Results(value = {
            @Result(property = "id", column = "id"),
            @Result(property = "mapJson", column = "mapJson", typeHandler = JsonTypeHandler.class,javaType = HashMap.class),
            @Result(property = "objJson", column = "objJson", typeHandler = JsonTypeHandler.class,javaType = JsonObj.class),
            @Result(property = "listJson", column = "listJson", typeHandler = ListJsonTypeHandler.class,javaType = JsonObj.class)
    })
    List<Json> select1();
// 增加
    @Insert("insert into json( mapJson, objJson, listJson) values (#{mapJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler}," +
            "#{objJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler}," +
            "#{listJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler})")
    int insert1(Json vo);

1.5 测试类

@SpringBootTest
public class ProductTest {
//这个就是刚才放sql的mapper
    @Autowired
    JsonMapper jsonMapper;
    @Test
    void test11() throws JsonProcessingException {

        JsonObj js = JsonObj.builder().str("这真的是一个简单的测试对象").build();
        Map<String,Object> map =  new HashMap<>();
        map.put("gaga","乱杀");
        List<JsonObj> jsonObjs = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            JsonObj js0 = JsonObj.builder().id(i).str("这真的是一个简单的测试对象").build();
            jsonObjs.add(js0);
        }
        Json build = Json.builder().mapJson(map).listJson(jsonObjs).objJson(js).build();
        jsonMapper.insert1(build);

    }
    @Test
    void test12(){

        List<Json> select = jsonMapper.select1();
        System.out.println(select);
    }
    }

在这里插入图片描述

2. 存储为携带类型的Json

因为在java在编译的时候是泛型擦除的,所以对于,List里面的类型无法确定,于是便可以把数据类型存入数据库之中,并且不需要再指出java类型
在这里插入图片描述
实体类还和上面一样,只需调整mapper中,对应的typeHandler即可

 @Select(" SELECT * from json ")
    @Results(value = {
            @Result(property = "id", column = "id"),
            @Result(property = "mapJson", column = "mapJson", typeHandler = JsonTypeHandler2.class),
            @Result(property = "objJson", column = "objJson", typeHandler = JsonTypeHandler2.class),
            @Result(property = "listJson", column = "listJson", typeHandler = JsonTypeHandler2.class)
    })
    List<Json> select();



    @Insert("insert into json( mapJson, objJson, listJson) values (#{mapJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler2}," +
            "#{objJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler2}," +
            "#{listJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler2})")
    int insert(Json vo);

在这里插入图片描述
ListJsonTypehander2

public class ListJsonTypeHandler<T> extends BaseTypeHandler<List<T>>{
    private Class<T> clazz;

    public ListJsonTypeHandler(Class<T> clazz) {
        this.clazz = clazz;
    }


    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, JSONUtil.toJsonStr(parameter));
    }
    @Override
    public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String data = rs.getString(columnName);
        return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
    }

    @SneakyThrows
    @Override
    public List<T> getNullableResult(ResultSet rs, int colIndex) {
        String data = rs.getString(colIndex);
        return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
    }

    @SneakyThrows
    @Override
    public List<T> getNullableResult(CallableStatement cs, int i) {
        String data = cs.getString(i);
        return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
    }
}

测试类,和上面基本类似

  @Test
    void test() throws JsonProcessingException {

        JsonObj js = JsonObj.builder().str("这真的是一个简单的测试对象").build();
        Map<String,Object> map =  new HashMap<>();
        map.put("gaga","乱杀");
        List<JsonObj> jsonObjs = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            JsonObj js0 = JsonObj.builder().id(i).str("这真的是一个简单的测试对象").build();
            jsonObjs.add(js0);
        }
        Json build = Json.builder().mapJson(map).listJson(jsonObjs).objJson(js).build();
        jsonMapper.insert(build);

    }

    @Test
    void test1(){

        List<Json> select = jsonMapper.select();
        System.out.println(select);

    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值