MysqlはKey/Value方式で動的拡張フィールド、オブジェクトとHashMapの相互変換を格納

17719 ワード

1、背景
プロジェクトが開発段階に入ったばかりの設計テーブルでは、後期テーブルのフィールドが増加する可能性があり、予約フィールドを設計して対応することができます.しかし、データが膨大であれば、テーブル文の変更を実行するときにテーブルをロックします.また、1枚のテーブルが複数の顧客をサポートしている場合、各顧客のニーズが異なり、変化が多い場合、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に変換して操作することができます.1つの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;
        }