• mysql json类型映射查询


    业务场景

    在mysql中在有些业务场景下可能会有 json 格式的使用,而 json 数据格式比较灵活多变,而 mybatisjson 类型的映射是通过 object 进行映射关系,在查询出来进行获取时使用会很麻烦, 在这里我们可以通过 json + jackson 框架的多态序列化方式实现将 json 格式映射成接口数据

    实战

    1. json结构

    有以下两种数据结构需要存储到数据库中,数据库中设计了一个 value 字段为 json 类型

    {
        "type": 1,
        "rule": "aaaaaaaa"
    }
    
    • 1
    • 2
    • 3
    • 4
    {
        "cron": "0 0 0/1 * * ? *",
        "type": 0
    }
    
    • 1
    • 2
    • 3
    • 4

    2. 接口

    JsonTypeInfo 的使用方法可以参考我的这篇博客 https://blog.csdn.net/weixin_43915643/article/details/127313547?spm=1001.2014.3001.5501

    @JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type"
    )
    @JsonSubTypes(
        {
            @JsonSubTypes.Type(value = DeviceValue0DTO.class, name = "0"),
            @JsonSubTypes.Type(value = DeviceValue0DT1.class, name = "1")
        }
    )
    //忽略掉json中没有的set方法
    @JsonIgnoreProperties(ignoreUnknown = true)
    public interface ITriggerConditionValue {
    
        //type类型
        Integer getType();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3. 实现类

    @Data
    public class DeviceValue1DTO implements ITriggerConditionValue, Serializable {
    
        /** serialVersionUID */
        private static final long serialVersionUID = 3491976287068028239L;
        /** Rule sql */
        private String rule;
    
        @Override
        public Integer getType() {
            return ConditionType.DEVICE.getValue();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    @Data
    public class DeviceValue0DTO implements ITriggerConditionValue, Serializable {
    
        /** serialVersionUID */
        private static final long serialVersionUID = 3491976287068028239L;
        /** Cron */
        private String cron;
    
        @Override
        public Integer getType() {
            return ConditionType.DEVICE.getValue();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4. 实体类

    下面使用的是 mybatis-plus 提供的注解相当于在 xml 文件中的 resultMap 里面映射字段后面加上 typeHandler 类型处理器

    public class TriggerCondition {
    
    	private String name;
    	
        @TableField(typeHandler = JacksonTypeHandler.class, value = "value")
        private ITriggerConditionValue value;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5. typeHandler

    自定义实现的 TypeHandler,通过使用 jackson 框架的多态实现,这里是使用的 mybatis-plus 实现的类型处理器,如果是 mybatis 可以复制下面代码

    public abstract class AbstractJsonTypeHandler<T> extends BaseTypeHandler<T> {
        public AbstractJsonTypeHandler() {
        }
    
        public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
            ps.setString(i, this.toJson(parameter));
        }
    
        public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
            String json = rs.getString(columnName);
            return StringUtils.isBlank(json) ? null : this.parse(json);
        }
    
        public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
            String json = rs.getString(columnIndex);
            return StringUtils.isBlank(json) ? null : this.parse(json);
        }
    
        public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
            String json = cs.getString(columnIndex);
            return StringUtils.isBlank(json) ? null : this.parse(json);
        }
    
        protected abstract T parse(String json);
    
        protected abstract String toJson(T obj);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    public class JacksonTypeHandler extends AbstractJsonTypeHandler<Object> {
        private static final Logger log = LoggerFactory.getLogger(JacksonTypeHandler.class);
        private static ObjectMapper objectMapper = new ObjectMapper();
        private final Class<?> type;
    
        public JacksonTypeHandler(Class<?> type) {
            if (log.isTraceEnabled()) {
                log.trace("JacksonTypeHandler(" + type + ")");
            }
    
            Assert.notNull(type, "Type argument cannot be null", new Object[0]);
            this.type = type;
        }
    
        protected Object parse(String json) {
            try {
                return objectMapper.readValue(json, this.type);
            } catch (IOException var3) {
                throw new RuntimeException(var3);
            }
        }
    
        protected String toJson(Object obj) {
            try {
                return objectMapper.writeValueAsString(obj);
            } catch (JsonProcessingException var3) {
                throw new RuntimeException(var3);
            }
        }
    
        public static void setObjectMapper(ObjectMapper objectMapper) {
            Assert.notNull(objectMapper, "ObjectMapper should not be null", new Object[0]);
            JacksonTypeHandler.objectMapper = objectMapper;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
  • 相关阅读:
    Android 对于状态栏和导航栏的操作
    取Dataset子集(pytorch)
    3.1 C/C++ 使用字符与指针
    图像处理及深度学习开源数据集大全(四万字呕心沥血整理)
    Android事件分发机制
    二分查找以及扩展
    Unregistering JMX-exposed beans on shutdown
    【WIFI】【WPS】基础介绍(主要根据sniffer log角度和kernel log去介绍)
    微服务项目:尚融宝(52)(核心业务流程:充值服务(2))
    【数字图像处理】直方图均衡化与规定化
  • 原文地址:https://blog.csdn.net/weixin_43915643/article/details/127539366