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);

    }
GitHub 加速计划 / js / json
18
5
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:3 个月前 )
f06604fc * :page_facing_up: bump the copyright years Signed-off-by: Niels Lohmann <mail@nlohmann.me> * :page_facing_up: bump the copyright years Signed-off-by: Niels Lohmann <mail@nlohmann.me> * :page_facing_up: bump the copyright years Signed-off-by: Niels Lohmann <niels.lohmann@gmail.com> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me> Signed-off-by: Niels Lohmann <niels.lohmann@gmail.com> 2 天前
d23291ba * add a ci step for Json_Diagnostic_Positions Signed-off-by: Harinath Nampally <harinath922@gmail.com> * Update ci.cmake to address review comments Signed-off-by: Harinath Nampally <harinath922@gmail.com> * address review comment Signed-off-by: Harinath Nampally <harinath922@gmail.com> * fix typo in the comment Signed-off-by: Harinath Nampally <harinath922@gmail.com> * fix typos in ci.cmake Signed-off-by: Harinath Nampally <harinath922@gmail.com> * invoke the new ci step from ubuntu.yml Signed-off-by: Harinath Nampally <harinath922@gmail.com> * issue4561 - use diagnostic positions for exceptions Signed-off-by: Harinath Nampally <harinath922@gmail.com> * fix ci_test_documentation check Signed-off-by: Harinath Nampally <harinath922@gmail.com> * address review comments Signed-off-by: Harinath Nampally <harinath922@gmail.com> * fix ci check failures for unit-diagnostic-postions.cpp Signed-off-by: Harinath Nampally <harinath922@gmail.com> * improvements based on review comments Signed-off-by: Harinath Nampally <harinath922@gmail.com> * fix const correctness string Signed-off-by: Harinath Nampally <harinath922@gmail.com> * further refinements based on reviews Signed-off-by: Harinath Nampally <harinath922@gmail.com> * add one more test case for full coverage Signed-off-by: Harinath Nampally <harinath922@gmail.com> * ci check fix - add const Signed-off-by: Harinath Nampally <harinath922@gmail.com> * add unit tests for json_diagnostic_postions only Signed-off-by: Harinath Nampally <harinath922@gmail.com> * fix ci_test_diagnostics Signed-off-by: Harinath Nampally <harinath922@gmail.com> * fix ci_test_build_documentation check Signed-off-by: Harinath Nampally <harinath922@gmail.com> --------- Signed-off-by: Harinath Nampally <harinath922@gmail.com> 2 天前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐