• SpringBoot、MyBatis、PostgreSQL储存JSON、对象等自定义TypeHandler


            由于MyBatis没有提供直接处理JSON的方法,因此需要自己实现处理JSON的类,并继承BaseTypeHandler来处理储存JSON字段。

           一、JSON转换

            首先引入pom文件:

    1. <dependency>
    2. <groupId>org.postgresqlgroupId>
    3. <artifactId>postgresqlartifactId>
    4. dependency>

            实体类接收定义为Object:

    1. import lombok.Data;
    2. @Data
    3. public class TestJson {
    4. private Long id;
    5. private Object value;
    6. }

            创建Handler:

    1. import org.apache.ibatis.type.BaseTypeHandler;
    2. import org.apache.ibatis.type.JdbcType;
    3. import org.apache.ibatis.type.MappedTypes;
    4. import org.postgresql.util.PGobject;
    5. import java.sql.CallableStatement;
    6. import java.sql.PreparedStatement;
    7. import java.sql.ResultSet;
    8. import java.sql.SQLException;
    9. @MappedTypes({Object.class})
    10. public class JsonTypeHandler extends BaseTypeHandler {
    11. //引入PGSQL提供的工具类PGobject
    12. private static final PGobject jsonObject = new PGobject();
    13. @Override
    14. public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
    15. jsonObject.setType("json");
    16. jsonObject.setValue(parameter.toString());
    17. ps.setObject(i, jsonObject);
    18. }
    19. @Override
    20. public Object getNullableResult(ResultSet rs, String s) throws SQLException {
    21. return rs.getString(s);
    22. }
    23. @Override
    24. public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    25. return rs.getString(columnIndex);
    26. }
    27. @Override
    28. public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    29. return cs.getString(columnIndex);
    30. }
    31. }
    32.         需要在Mapper.xml文件中加入:

      1. <result column="classify_value" jdbcType="OTHER"
      2. property="classifyValue" typeHandler="xx.xx.xx.JsonTypeHandler"/>

              typeHandler指的是自定义的JsonTypeHandler 的全类限定名。

              二、List转换

              存储对象实际上存储的也是JSON,只是需要对接收的参数进行一定的处理,比如传入的List,这里的Object指自定义的java对象,其余的处理都跟传入Object一致,只需要进行Handler的编写:

              定义一个Java对象:

      1. import lombok.Data;
      2. import java.util.List;
      3. @Data
      4. public class ListObjectTest{
      5. private String name;
      6. private Stirng address;
      7. }

              编写自定义的Handler: 

      1. @MappedJdbcTypes({JdbcType.VARCHAR})
      2. @MappedTypes(value = {List.class})
      3. public class ListObjectHandler extends BaseTypeHandler> {
      4. @SneakyThrows
      5. @Override
      6. public void setNonNullParameter(PreparedStatement ps, int i, List parameter, JdbcType jdbcType) throws SQLException {
      7. ps.setString(i, JSONUtil.toJsonStr(parameter));
      8. }
      9. @SneakyThrows
      10. @Override
      11. public List getNullableResult(ResultSet rs, String columnName){
      12. String value = rs.getString(columnName);
      13. return JSONUtil.parseArray(value).toList(TestListObject.class);
      14. }
      15. @SneakyThrows
      16. @Override
      17. public List getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
      18. String value = rs.getString(columnIndex);
      19. return JSONUtil.parseArray(value).toList(TestListObject.class);
      20. }
      21. @SneakyThrows
      22. @Override
      23. public List getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
      24. String value = cs.getString(columnIndex);
      25. return JSONUtil.parseArray(value).toList(TestListObject.class);
      26. }
      27. }

              三、List转换

              handler编写:

      1. import lombok.SneakyThrows;
      2. import org.apache.ibatis.type.BaseTypeHandler;
      3. import org.apache.ibatis.type.JdbcType;
      4. import org.apache.ibatis.type.MappedJdbcTypes;
      5. import org.apache.ibatis.type.MappedTypes;
      6. import java.sql.CallableStatement;
      7. import java.sql.PreparedStatement;
      8. import java.sql.ResultSet;
      9. import java.sql.SQLException;
      10. import java.util.ArrayList;
      11. import java.util.Arrays;
      12. import java.util.List;
      13. @MappedJdbcTypes({JdbcType.VARCHAR})
      14. @MappedTypes(value = {List.class})
      15. public class HeadersTypeHandler extends BaseTypeHandler> {
      16. @SneakyThrows
      17. @Override
      18. public void setNonNullParameter(PreparedStatement ps, int i, List parameter, JdbcType jdbcType) throws SQLException {
      19. ps.setString(i, String.join(",", parameter));
      20. }
      21. @SneakyThrows
      22. @Override
      23. public List getNullableResult(ResultSet rs, String columnName) {
      24. String value = rs.getString(columnName);
      25. if (value == null) {
      26. return new ArrayList<>();
      27. }
      28. return Arrays.asList(value.split(","));
      29. }
      30. @SneakyThrows
      31. @Override
      32. public List getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
      33. String value = rs.getString(columnIndex);
      34. if (value == null) {
      35. return new ArrayList();
      36. }
      37. return Arrays.asList(value.split(","));
      38. }
      39. @SneakyThrows
      40. @Override
      41. public List getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
      42. String value = cs.getString(columnIndex);
      43. if (value == null) {
      44. return new ArrayList<>();
      45. }
      46. return Arrays.asList(value.split(","));
      47. }
      48. }

              四、List转换

              handler:

      1. import cn.hutool.json.JSONUtil;
      2. import com.pearadmin.system.domain.ProductStrategyDetail;
      3. import lombok.extern.slf4j.Slf4j;
      4. import org.apache.commons.lang.StringEscapeUtils;
      5. import org.apache.ibatis.type.BaseTypeHandler;
      6. import org.apache.ibatis.type.JdbcType;
      7. import org.apache.ibatis.type.MappedJdbcTypes;
      8. import org.apache.ibatis.type.MappedTypes;
      9. import java.sql.CallableStatement;
      10. import java.sql.PreparedStatement;
      11. import java.sql.ResultSet;
      12. import java.sql.SQLException;
      13. import java.util.List;
      14. @MappedJdbcTypes({JdbcType.OTHER})
      15. @MappedTypes(value = {List.class})
      16. @Slf4j
      17. public class DetailHandler extends BaseTypeHandler {
      18. @Override
      19. public void setNonNullParameter(PreparedStatement preparedStatement, int i, List list, JdbcType jdbcType) throws SQLException {
      20. preparedStatement.setString(i, JSONUtil.toJsonStr(list));
      21. }
      22. @Override
      23. public List getNullableResult(ResultSet resultSet, String s) throws SQLException {
      24. String value = resultSet.getString(s);
      25. if (value == null) {
      26. return null;
      27. }
      28. return JSONUtil.toList(value, ProductStrategyDetail.class);
      29. }
      30. @Override
      31. public List getNullableResult(ResultSet resultSet, int i) throws SQLException {
      32. String value = resultSet.getString(i);
      33. if (value == null) {
      34. return null;
      35. }
      36. return JSONUtil.toList(value, ProductStrategyDetail.class);
      37. }
      38. @Override
      39. public List getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
      40. String value = callableStatement.getString(i);
      41. if (value == null) {
      42. return null;
      43. }
      44. return JSONUtil.toList(value, ProductStrategyDetail.class);
      45. }
      46. }

              五、Map转换

              handler:

      1. import cn.hutool.json.JSONUtil;
      2. import com.fasterxml.jackson.databind.ObjectMapper;
      3. import lombok.SneakyThrows;
      4. import lombok.extern.slf4j.Slf4j;
      5. import org.apache.ibatis.type.BaseTypeHandler;
      6. import org.apache.ibatis.type.JdbcType;
      7. import org.apache.ibatis.type.MappedJdbcTypes;
      8. import org.apache.ibatis.type.MappedTypes;
      9. import java.io.IOException;
      10. import java.lang.reflect.InvocationTargetException;
      11. import java.math.BigDecimal;
      12. import java.nio.charset.StandardCharsets;
      13. import java.sql.CallableStatement;
      14. import java.sql.PreparedStatement;
      15. import java.sql.ResultSet;
      16. import java.sql.SQLException;
      17. import java.util.HashMap;
      18. import java.util.Map;
      19. @MappedJdbcTypes({JdbcType.VARCHAR})
      20. @MappedTypes(value = {Map.class})
      21. @Slf4j
      22. public class JsonTypeHandler extends BaseTypeHandler {
      23. private ObjectMapper objectMapper = new ObjectMapper();
      24. @SneakyThrows
      25. @Override
      26. public void setNonNullParameter(PreparedStatement ps, int i, Map parameter, JdbcType jdbcType) throws SQLException {
      27. ps.setString(i, objectMapper.writeValueAsString(parameter));
      28. }
      29. @SneakyThrows
      30. @Override
      31. public Map getNullableResult(ResultSet rs, String columnName) {
      32. String value = rs.getString(columnName);
      33. if (value == null) {
      34. return new HashMap();
      35. }
      36. Map map = objectMapper.readValue(value.getBytes(), Map.class);
      37. return toStructureElementObjectMap(map);
      38. }
      39. @SneakyThrows
      40. @Override
      41. public Map getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
      42. String value = rs.getString(columnIndex);
      43. if (value == null) {
      44. return new HashMap();
      45. }
      46. Map map = objectMapper.readValue(value.getBytes(), Map.class);
      47. return toStructureElementObjectMap(map);
      48. }
      49. @SneakyThrows
      50. @Override
      51. public Map getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
      52. String value = cs.getString(columnIndex);
      53. if (value == null) {
      54. return new HashMap();
      55. }
      56. Map map = objectMapper.readValue(value.getBytes(), Map.class);
      57. return toStructureElementObjectMap(map);
      58. }
      59. }

    33. 相关阅读:
      基于java+springboot+mybatis+vue+elementui的人职匹配推荐系统
      古代汉语 郭锡良版本 复习要点
      不断迭代的收银系统,工厂_策略_装饰器_反射
      STM32H743 RTC精密数字校准 深度剖析
      公司只有功能测试,如何进一步提升自己?
      ATFX汇市:欧央行利率决议来袭,能够逆转欧元跌势吗?
      微信小程序 生成跳转体验版url,可直接跳转到体验版小程序(可通过此方法测试模板消息)
      Nomad 系列-Nomad+Traefik+Tailscale 集成实现零信任安全
      i7 11800h和i7 12800hx选哪个好
      MySQL8实现主从备份
    34. 原文地址:https://blog.csdn.net/qq_41061437/article/details/126951993