Mysql使用Key/Value方式存储动态扩展字段、对象与HashMap的相互转化

1、背景

在项目刚刚进入开发阶段设计表时,后期表的字段很可能会增加,我们可以设计出预留字段来应对。但是假如你的数据数据非常庞大且没有预留字段,那么执行修改表语句时会长时间锁表。而且假如一张表支持许多个客户,每个客户的需求不相同且多变时,使用一张表也无法满足需求。这时可以使用Mysql存储key/value数据满足不同客户需求。

2、Key/Value表设计

以Key/Value存储数据肯定不是Mysql的存储常态,但是可以应对一些灵活多变的场景。以下就是使用Key/Value的例子,先创建要给order订单表,再创建订单表的扩展字段。创建好Key/Value表之后可以为不同的客户配置不同的扩展字段属性和值。

CREATE TABLE `order` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) DEFAULT NULL,
  `description` text,
  `quantity` bigint(20) unsigned DEFAULT NULL COMMENT '数量',
  `amount` decimal(22,2) DEFAULT NULL COMMENT '金额',
   PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=337411 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;


CREATE TABLE `order_extend` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `order_id` bigint unsigned NOT NULL COMMENT '订单id',
  `extendfield_code` varchar(255) NOT NULL COMMENT '扩展字段属性',
  `extendfield_value` text COMMENT '扩展字段值',
   PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

3、对象和HashMap相互转化

在设计了Key/Value扩展字段表之后,在某些业务场景为了方便处理扩展字段,可以将对象转化为Map进行操作,一个Map的所有key就是对象的所有字段,value就是对象字段所对应的值。以下是操作Key/Value数据案例操作:

    public void example(Long id) {
    	//查到id对应的订单
        Order order = orderMapper.selectByPrimaryKey(id);
        //将对象属性转化为map集合
        Map<String, Object> map = JSON.parseObject(JSONObject.toJSONString(order), HashMap.class);
        //查到对应的扩展字段list
        List<OrderExtend> orderExtends = orderExtendMapper.select(id);
        for (OrderExtend orderExtend : orderExtends) {
        	//将扩展字段放入map中
            map.put(orderExtend.getExtendFieldCode(),orderExtend.getExtendFieldValue());
        }
		 
		 //......
    	 //对map一顿操作
    	 //......

		//将map集合中的数据转化为指定对象的同名属性中
        Order updateOrder = JSON.parseObject(JSONObject.toJSONString(map), EventOrder.class);
		//更新订单信息
        eventOrderMapper.updateByPrimaryKey(updateOrder);
		//遍历出map中的扩展字段进行更新
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (entry.getKey().startsWith("extendField_")) {
                OrderExtend  orderExtend  = new OrderExtend ();
                orderExtend.setOrderId(updateOrder.getId());
                orderExtend.setExtendFieldCode(entry.getKey());
                orderExtend.setExtendFieldValue(entry.getValue());
                update(orderExtend);
            }
        }
    }
  • HashMap和对象之间的转化还可以通过使用org.springframework.cglib.beans.BeanMap类中的方法,转化效率高。使用BeanMap进行对象和HashMap的转化:

    //将map集合中的数据转化为指定对象的同名属性中
    public static <T> Map<String, Object> beanToMap(T bean) {
        Map<String, Object> map = new HashMap<>();
        if (bean != null) {
            BeanMap beanMap = BeanMap.create(bean);
            for (Object key : beanMap.keySet()) {
                map.put(key+"", beanMap.get(key));
            }
        }
        return map;
    }
    
    //将对象属性转化为map集合
    public static <T> T mapToBean(Map map,Class<T> clazz) throws Exception {
        T bean = clazz.newInstance();
        BeanMap beanMap = BeanMap.create(bean);
        beanMap.putAll(map);
        return bean;
    }
发布了36 篇原创文章 · 获赞 28 · 访问量 1505

猜你喜欢

转载自blog.csdn.net/tc979907461/article/details/105435163
今日推荐