åè¨
æ¥çä¸ä¸¤ç¯ï¼ãéç¨Serviceããéç¨æ ç»ææä½ãï¼éç¨æå¡çåè½ï¼æ们继ç»è¯´ä¸æ们ç第ä¸ç¯ï¼å ³äºéç¨çå±æ§æå¡ï¼å æ¥è¯´è¯´ä¸ºä»ä¹ä¼æ³çæ½ç¦»è¿ä¹ä¸ªæå¡ï¼æ³å¿ å·¥ä½æ¶é´ä¹ çå¼å人åè¯å®ä¼éå°è¿ç§é®é¢ï¼éçä¸å¡çå¢é¿ï¼ä¼å¯¹åæä¸å¡è¡¨ä¸å¢å åç§å段ï¼ä½æ¯æçå段并ä¸åºè¯¥å½å±äºä¸»è¡¨ä¸ï¼èæ¯åºè¯¥æ¾å¨å ¶æ©å±å±æ§è¡¨ä¸ï¼å 为æäºåæ®µä» ä» æ¯ä¸»ä¸å¡å ¶ä¸æä¸ç§ç¹å®ä¸å¡æå ·æçï¼æ¯å¦ï¼å¨order表ä¸ï¼æ»æ¯æä¸äºå¹¶ä¸æ¯ææ订åé½ä¼æçå±æ§ï¼è¿æ¶æ们å¯è½ä¼å°è¿äºå±æ§åå¨å¨ä¸ä¸ªå«extçå段ä¸ï¼æ ¼å¼å¯è½æ¯jsonæ ¼å¼çå符串ä¹å¯è½æ¯key:valueè¿ç§æ°æ®ç»æï¼ä½æ¯æ³æ³è¿ç§æ¹å¼çåå¨æ¯ä¸æ¯å¾ä¸å©äºç»æåæç´¢ï¼èä¸è¿è¦å¨ä¸»è¡¨ä¸ç»´æ¤æ©å±å±æ§çå¢å æ¹æ¥åè½ï¼æ½ç¦»ä¸å ¬å ±åè½çéå 表æ¯ä¸ªå¾å¥½çæ¹å¼ï¼ï¼é£å¦ææ们æè¿ç§key->valueç»æå ³ç³»åç¬æ½ç¦»ä¸ä¸ªåè½ï¼æ¥ç®åæ们对è¿ç§éå å±æ§ç使ç¨ï¼æ¯ä¸æ¯ä¼æ´å¥½å¢ï¼
å®ç°æè·¯
å®ç°æè·¯å¾ç®åï¼å°±æ¯åä¸ä¸ªéç¨çå±æ§æå¡mapperåserviceï¼è®©ä»»ä½ä¸»è¡¨çå±æ§æ©å±è¡¨ä» éè¦ç®åçé 置就å¯ä»¥å»ä½¿ç¨è¯¥åè½ï¼é£ä¹ç°å¨æ¥çä¸éç¨çæ©å±è¡¨ç»æåéè¦å®ä¹å ä¸ªæ ¸å¿ç±»ï¼
表ç»æ
DROP TABLE IF EXISTS `XXX_attr`;
CREATE TABLE `XXX_attr` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主é®',
`object_id` varchar(64) NOT NULL COMMENT '对象ID',-- 该å段类åéä¸ä¸»è¡¨ç主é®ä¸è´
`key` varchar(64) NOT NULL COMMENT 'é®',
`value` varchar(1024) DEFAULT NULL COMMENT 'å¼',
`type` varchar(32) NOT NULL COMMENT 'ç±»å',
`create_time` datetime NOT NULL COMMENT 'å建æ¶é´',
PRIMARY KEY (`id`),
UNIQUE INDEX uq_object_id_key(`object_id`, `key`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='XXXå±æ§è¡¨';
æ ¸å¿ç±»
Attributeï¼å±æ§POç±»
AttributeMapperï¼éç¨å±æ§MAPPERç±»
InsertAttributeServiceãUpdateAttributeServiceãDeleteAttributeServiceãSelectAttributeServiceï¼éç¨å±æ§APIæ¥å£
AttributeServiceImplï¼éç¨å±æ§å®ç°é»è¾
AttributesChangedEventï¼å±æ§åæ´äºä»¶
注æ
- keyå°±æ¯æ们çå±æ§å段åï¼valueå°±æ¯å±æ§å段çå¼ï¼å段typeç¨æ¥åå¨valueå段çç±»å
- XXX å°±ä»£è¡¨ä½ ç主表å½ï¼å ¶ä¸object_idåå¨ä½ ç主表ç主é®å ³è
- å¼å¾æ³¨æçæ¯object_idå段çç±»åæ¯æ ¹æ®ä¸»è¡¨ç主é®ç±»åä¸è´çï¼é²æ¢å ç±»åä¸ä¸è´å¯¼è´ç¨åºèµ°ä¸ä¸ç´¢å¼é®é¢
å ·ä½å®ç°
Attribute对象
package com.zm.zhuma.commons.attributes.model;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Attribute<OID> implements Serializable{
private static final long serialVersionUID = 1L;
private Long id;
private OID objectId;
private String key;
private String value;
private String type;
}
AttributeMapperç±»ï¼éç¨å±æ§æä½mapperï¼
package com.zm.zhuma.commons.attributes.mapper;
import java.util.List;
import com.zm.zhuma.commons.attributes.model.Attribute;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface AttributeMapper<OID> {
void addAttributes(@Param(value = "tableName") String tableName, @Param(value = "attributes") List<Attribute<OID>> attributes);
void deleteAttributes(@Param(value = "tableName") String tableName, @Param(value = "objectId") OID objectId, @Param(value = "keys") List<String> keys);
void updateAttributes(@Param(value = "tableName") String tableName, @Param("attr") Attribute<OID> attribute);
List<Attribute<OID>> getAttributeMapByKeys(@Param(value = "tableName") String tableName, @Param(value = "objectIds") List<OID> objectIds, @Param(value = "keys") List<String> keys);
List<Attribute<OID>> getAttributeMapByKeyAndValue(@Param(value = "tableName") String tableName, @Param(value = "objectIds") List<OID> objectIds, @Param(value = "key") String key, @Param(value = "value") Object value);
List<Attribute<OID>> getAttributeMapByKeyAndValues(@Param(value = "tableName") String tableName, @Param(value = "key") String key, @Param(value = "values") List<Object> values);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mapper.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zm.zhuma.commons.attributes.mapper.AttributeMapper">
<insert id="addAttributes" useGeneratedKeys="true">
insert into ${tableName} (`object_id`,`key`,`value`,`type`,`create_time`) values
<foreach collection="attributes" item="item" index="index" separator=",">
(#{item.objectId},#{item.key},#{item.value},#{item.type},now())
</foreach>
</insert>
<delete id="deleteAttributes">
delete from ${tableName} where `object_id`=#{objectId}
<if test="keys != null and keys.size() > 0">
and `key` in
<foreach collection="keys" item="key" open="(" separator="," close=")">
#{key}
</foreach>
</if>
</delete>
<update id="updateAttributes">
update ${tableName} set `value` = #{attr.value},type = #{attr.type}
<where>
<if test="attr.id != null">id = #{attr.id}</if>
<if test="attr.objectId != null and attr.objectId != ''"> and `object_id` = #{attr.objectId}</if>
<if test="attr.key != null and attr.key != '' "> and `key` = #{attr.key}</if>
</where>
</update>
<select id="getAttributeMapByKeys" resultType="com.zm.zhuma.commons.attributes.model.Attribute">
select * from ${tableName}
<where>
<if test="objectIds != null and objectIds.size() > 0">
`object_id` in
<foreach collection="objectIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
<if test="keys != null and keys.size() > 0">
and `key` in
<foreach collection="keys" item="key" open="(" separator="," close=")">
#{key}
</foreach>
</if>
</where>
</select>
<select id="getAttributeMapByKeyAndValue" resultType="com.zm.zhuma.commons.attributes.model.Attribute">
select * from ${tableName}
<where>
<if test="objectIds != null and objectIds.size() > 0">
`object_id` in
<foreach collection="objectIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
<if test="key != null and key != ''">
and `key` = #{key}
</if>
<if test="value != null and value != ''">
and `value` = #{value}
</if>
</where>
</select>
<select id="getAttributeMapByKeyAndValues" resultType="com.zm.zhuma.commons.attributes.model.Attribute">
select * from ${tableName}
<where>
<if test="key != null and key != ''">
`key` = #{key}
</if>
<if test="values != null and values.size() > 0">
and `value` in
<foreach collection="values" item="value" open="(" separator="," close=")">
#{value}
</foreach>
</if>
</where>
</select>
</mapper>
å¤æ³¨
- å¯ä»¥çå°æä»¬å ¶å®æ¯æ表ååï¼${tableName}ï¼ä½ä¸ºåæ°ä¼ éè¿æ¥ï¼ä»¥è¾¾å°éç¨å±æ§mapperçç®çï¼æ没æåå¦å°ä¸æçæè§å¢ï¼O(â©_â©)O
å¢å å±æ§æ¥å£å®ä¹
package com.zm.zhuma.commons.attributes.service;
import com.zm.zhuma.commons.attributes.model.AttributesChange;
import java.util.Map;
/**
* @desc æå
¥å±æ§æå¡
*
* @author zhuamer
* @since 7/9/2018 11:13
*/
public interface InsertAttributeService<OID> {
/**
* æ·»å 对象å±æ§
* 该æä½å°ä¿åattributesä¸çå±æ§ï¼ä¸åå¨äºattributesä¸çå±æ§ä¸åä»»ä½æä½
* @param objectId 对象id
* @param attributes å±æ§éå
*/
AttributesChange<OID> addAttributes(OID objectId, Map<String, Object> attributes);
}
ä¿®æ¹å±æ§æ¥å£å®ä¹
package com.zm.zhuma.commons.attributes.service;
import com.zm.zhuma.commons.attributes.model.AttributesChange;
import java.util.Map;
/**
* @desc æ´æ°å±æ§æå¡
*
* @author zhuamer
* @since 7/9/2018 11:13
*/
public interface UpdateAttributeService<OID> {
/**
* 设置对象å±æ§
* @param objectId 对象id
* @param key å±æ§key
* @param value å±æ§å¼
*/
AttributesChange<OID> setAttribute(OID objectId, String key, Object value);
/**
* 设置对象å±æ§
* 该æä½å°ä¿åattributesä¸çå±æ§ï¼ä¸åå¨äºattributesä¸çå±æ§å°å é¤
* @param objectId 对象id
* @param attributes å±æ§mapï¼keyï¼å±æ§keyï¼valueï¼å±æ§å¼
*/
AttributesChange<OID> setAttributes(OID objectId, Map<String, Object> attributes);
}
å é¤å±æ§æ¥å£å®ä¹
package com.zm.zhuma.commons.attributes.service;
import com.zm.zhuma.commons.attributes.model.AttributesChange;
import java.util.Map;
/**
* @desc å é¤å±æ§æå¡
*
* @author zhuamer
* @since 7/9/2018 11:13
*/
public interface DeleteAttributeService<OID> {
/**
* å é¤å个å±æ§
* @param objectId 对象id
* @param key å±æ§key
*/
AttributesChange<OID> deleteAttribute(OID objectId, String key);
/**
* å é¤å¯¹è±¡å±æ§
* @param objectId 对象id
*/
AttributesChange<OID> deleteAttributes(OID objectId);
/**
* å é¤å¯¹è±¡å±æ§
* @param objectId 对象id
* @param keys å±æ§keys
*/
AttributesChange<OID> deleteAttributes(OID objectId, Iterable<String> keys);
}
æ¥çå±æ§æ¥å£å®ä¹
package com.zm.zhuma.commons.attributes.service;
import java.util.Map;
/**
* @desc æ¥è¯¢å±æ§æå¡
*
* @author zhuamer
* @since 7/9/2018 11:13
*/
public interface SelectAttributeService<OID> {
/**
* è·å对象ææå±æ§
* @param objectId 对象id
* @return å±æ§mapï¼keyï¼å±æ§keyï¼valueï¼å±æ§å¼
*/
Map<String, Object> getAttributes(OID objectId);
/**
* è·å对象ææå±æ§
* @param objectId 对象id
* @param objectClass å±æ§å¯¹åºçç±»
* @return ææå±æ§å¯¹åºè½¬åç类对象
*/
<T> T getAttributes(OID objectId, Class<T> objectClass);
/**
* è·å对象æä¸ä¸ªå±æ§
* @param objectId 对象id
* @param key å±æ§key
* @return å±æ§å¼
*/
Object getAttribute(OID objectId, String key);
/**
* è·å对象æä¸ä¸ªå±æ§
* @param objectId 对象id
* @param key å±æ§key
* @param valueClass å±æ§valueç±»
* @return å±æ§å¼
*/
<V> V getAttribute(OID objectId, String key, Class<V> valueClass);
/**
* è·å对象æä¸æ¹å±æ§
* @param objectId 对象id
* @param keys å±æ§keys
* @return å±æ§mapï¼keyï¼å±æ§keyï¼valueï¼å±æ§å¼
*/
Map<String, Object> getAttributes(OID objectId, Iterable<String> keys);
/**
* æ¹éè·åå¤ä¸ªå¯¹è±¡çå±æ§
* @param objectIds 对象ids
* @param keys å±æ§keys
* @return mapï¼keyï¼å¯¹è±¡idï¼valueï¼å¯¹è±¡å±æ§mapï¼keyï¼å±æ§keyï¼valueï¼å±æ§å¼ï¼
*/
Map<OID, Map<String, Object>> getAttributes(Iterable<OID> objectIds, Iterable<String> keys);
/**
* æ¹éè·åå¤ä¸ªå¯¹è±¡çå±æ§
* @param objectIds 对象ids
* @return mapï¼keyï¼å¯¹è±¡idï¼valueï¼å¯¹è±¡å±æ§mapï¼keyï¼å±æ§keyï¼valueï¼å±æ§å¼ï¼
*/
Map<OID, Map<String, Object>> getAttributes(Iterable<OID> objectIds);
/**
* æ¹éè·åå¤ä¸ªå¯¹è±¡çå±æ§
* @param objectIds 对象ids
* @param key å±æ§key
* @return
*/
Map<OID, Object> getAttributes(Iterable<OID> objectIds, String key);
/**
* æ¹éè·åå¤ä¸ªå¯¹è±¡ID对åºå±æ§ä¿¡æ¯
* @param objectIds 对象ids
* @param key å±æ§key
* @return
*/
Map<OID, Object> getAttributes(Iterable<OID> objectIds, String key, Object value);
/**
* ä¸ä¸ªkeyï¼ä¸åvalueå¼
* @param key
* @param values
* @return
*/
Map<OID, Object> getAttributes(String key, Iterable<Object> values);
}
å¤æ³¨
- è·åå±æ§çæ¹æ³è¿æ¯æ¯è¾å¤çï¼æ以åºè¯¥åºæ¬è½æ»¡è¶³å¹³æ¶å¼åä¸çä¸å¡åºæ¯äº
AttributeServiceImplå®ç°é»è¾
package com.zm.zhuma.commons.attributes.service.impl;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.google.common.collect.Maps;
import com.zm.zhuma.commons.attributes.mapper.AttributeMapper;
import com.zm.zhuma.commons.attributes.event.publisher.AttributeEventPublisher;
import com.zm.zhuma.commons.attributes.model.Attribute;
import com.zm.zhuma.commons.attributes.model.AttributeChange;
import com.zm.zhuma.commons.attributes.model.AttributesChangedEvent;
import com.zm.zhuma.commons.attributes.model.AttributesChange;
import com.zm.zhuma.commons.attributes.service.AttributeService;
import com.google.common.collect.Lists;
import com.zm.zhuma.commons.util.BeanUtil;
import com.zm.zhuma.commons.util.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.springframework.util.Assert;
@Slf4j
public class AttributeServiceImpl<OID> implements AttributeService<OID> {
private String table = null;
private AttributeMapper<OID> attributeDao;
private AttributeEventPublisher<OID> eventPublisher;
public AttributeServiceImpl(String table, AttributeMapper<OID> attributeDao, AttributeEventPublisher<OID> eventPublisher) {
this.table = table;
this.attributeDao = attributeDao;
this.eventPublisher = eventPublisher;
}
@Override
public Map<String, Object> getAttributes(OID objectId) {
Assert.notNull(objectId, "objectId is not null");
List<Attribute<OID>> list = attributeDao.getAttributeMapByKeys(table, Lists.newArrayList(objectId), null);
return list.stream().collect(Collectors.toMap(Attribute::getKey, this::convertType,(key1, key2) -> key2));
}
@Override
public <T> T getAttributes(OID objectId, Class<T> objectClass) {
Map<String, Object> attrMap = getAttributes(objectId);
return BeanUtil.mapToObject(attrMap, objectClass);
}
@Override
public Object getAttribute(OID objectId, String key) {
Assert.notNull(objectId, "objectId is not null");
Assert.notNull(key, "key is not null");
List<Attribute<OID>> list = attributeDao.getAttributeMapByKeys(table, Lists.newArrayList(objectId), Lists.newArrayList(key));
if (list.size() == 0) {
return null;
} else if (list.size() == 1) {
return convertType(list.get(0));
} else {
throw new TooManyResultsException();
}
}
@Override
public <V> V getAttribute(OID objectId, String key, Class<V> valueClass) {
return (V) getAttribute(objectId, key);
}
@Override
public Map<String, Object> getAttributes(OID objectId, Iterable<String> keys) {
Assert.notNull(objectId, "objectId is not null");
Assert.notNull(keys, "keys is not null");
List<Attribute<OID>> list = attributeDao.getAttributeMapByKeys(table, Lists.newArrayList(objectId), Lists.newArrayList(keys));
return list.stream().collect(Collectors.toMap(Attribute::getKey, this::convertType,(key1, key2) -> key2));
}
@Override
public Map<OID, Map<String, Object>> getAttributes(Iterable<OID> objectIds, Iterable<String> keys) {
Assert.notNull(objectIds, "objectIds is not null");
Assert.notNull(keys, "objectId is not null");
Map<OID, Map<String, Object>> map = Maps.newHashMap();
objectIds.forEach(objectId -> {
Map<String, Object> partMap = getAttributes(objectId, keys);
map.put(objectId, partMap);
});
return map;
}
@Override
public Map<OID, Map<String, Object>> getAttributes(Iterable<OID> objectIds) {
Assert.notNull(objectIds, "objectIds is not null");
Map<OID, Map<String, Object>> map = Maps.newHashMap();
objectIds.forEach(objectId -> {
Map<String, Object> partMap = getAttributes(objectId);
map.put(objectId, partMap);
});
return map;
}
@Override
public Map<OID, Object> getAttributes(Iterable<OID> objectIds, String key) {
Assert.notNull(objectIds, "objectIds is not null");
Assert.notNull(key, "key is not null");
List<Attribute<OID>> list = attributeDao.getAttributeMapByKeys(table, Lists.newArrayList(objectIds), Lists.newArrayList(key));
return list.stream().collect(Collectors.toMap(Attribute::getObjectId, this::convertType,(key1, key2) -> key2));
}
@Override
public Map<OID, Object> getAttributes(Iterable<OID> objectIds, String key, Object value) {
Assert.notNull(objectIds, "objectIds is not null");
Assert.notNull(key, "key is not null");
List<Attribute<OID>> list = attributeDao.getAttributeMapByKeyAndValue(table, Lists.newArrayList(objectIds), key, value);
return list.stream().collect(Collectors.toMap(Attribute::getObjectId, this::convertType,(key1, key2) -> key2));
}
@Override
public Map<OID, Object> getAttributes(String key, Iterable<Object> values) {
Assert.notNull(key, "key is not null");
Assert.notNull(values, "values is not null");
List<Attribute<OID>> list = attributeDao.getAttributeMapByKeyAndValues(table, key, Lists.newArrayList(values));
Map<OID, Object> map = new HashMap<>();
for (Attribute<OID> attribute : list) {
map.put(attribute.getObjectId(), convertType(attribute));
}
return map;
}
@Override
public AttributesChange<OID> setAttribute(OID objectId, String key, Object value) {
Map<String, Object> attributes = Maps.newHashMap();
attributes.put(key, value);
return this.setAttributes(objectId, attributes);
}
@Override
public AttributesChange<OID> setAttributes(OID objectId, Map<String, Object> attributes) {
Assert.notNull(objectId, "objectId is not null");
Assert.notNull(attributes, "attributes is not null");
Map<String, AttributeChange> added = Maps.newHashMap();
Map<String, AttributeChange> updated = Maps.newHashMap();
Map<String, AttributeChange> removed = Maps.newHashMap();
Map<String, Object> previousMap = getAttributes(objectId);
List<String> previousKeyList = Lists.newArrayList(previousMap.keySet());
List<String> currentKeyList = Lists.newArrayList(attributes.keySet());
List<String> addKeyList = CollectionUtil.subtract(currentKeyList, previousKeyList);
List<String> updateKeyList = CollectionUtil.intersection(currentKeyList, previousKeyList);
List<String> removeKeyList = CollectionUtil.subtract(previousKeyList, currentKeyList);
List<Attribute<OID>> addAttrList = addKeyList.stream().map(c -> {
Attribute<OID> attribute = new Attribute<>();
attribute.setKey(c);
attribute.setObjectId(objectId);
convertType(attributes.get(c), attribute);
added.put(c, AttributeChange.builder().previous(null).current(attributes.get(c)).build());
return attribute;
}).collect(Collectors.toList());
if (!CollectionUtil.isEmpty(addAttrList)) {
attributeDao.addAttributes(table, addAttrList);
}
updateKeyList.forEach(c -> {
Attribute<OID> attribute = new Attribute<>();
attribute.setKey(c);
attribute.setObjectId(objectId);
convertType(attributes.get(c), attribute);
attributeDao.updateAttributes(table, attribute);
updated.put(c, AttributeChange.builder().previous(previousMap.get(c)).current(attributes.get(c)).build());
});
if (!CollectionUtil.isEmpty(removeKeyList)) {
removeKeyList.forEach(c -> removed.put(c, AttributeChange.builder().previous(previousMap.get(c)).current(null).build()));
attributeDao.deleteAttributes(table, objectId, removeKeyList);
}
return buildResult(objectId, added, updated, removed);
}
@Override
public AttributesChange<OID> addAttributes(OID objectId, Map<String, Object> attributes) {
Assert.notNull(objectId, "objectId is not null");
Assert.notNull(attributes, "attributes is not null");
Map<String, AttributeChange> added = Maps.newHashMap();
Map<String, AttributeChange> updated = Maps.newHashMap();
Map<String, AttributeChange> removed = Maps.newHashMap();
if (!CollectionUtil.isEmpty(attributes)) {
Map<String, Object> previousMap = getAttributes(objectId);
List<String> previousKeyList = Lists.newArrayList(previousMap.keySet());
List<String> currentKeyList = Lists.newArrayList(attributes.keySet());
List<String> addKeyList = CollectionUtil.subtract(currentKeyList, previousKeyList);
List<String> updateKeyList = CollectionUtil.intersection(currentKeyList, previousKeyList);
List<Attribute<OID>> addAttrList = addKeyList.stream().map(c -> {
Attribute<OID> attribute = new Attribute<>();
attribute.setKey(c);
attribute.setObjectId(objectId);
convertType(attributes.get(c), attribute);
added.put(c, AttributeChange.builder().previous(null).current(attributes.get(c)).build());
return attribute;
}).collect(Collectors.toList());
if (!CollectionUtil.isEmpty(addAttrList)) {
attributeDao.addAttributes(table, addAttrList);
}
updateKeyList.forEach(c -> {
Attribute<OID> attribute = new Attribute<>();
attribute.setKey(c);
attribute.setObjectId(objectId);
convertType(attributes.get(c), attribute);
attributeDao.updateAttributes(table, attribute);
updated.put(c, AttributeChange.builder().previous(previousMap.get(c)).current(attributes.get(c)).build());
});
}
return buildResult(objectId, added, updated, removed);
}
@Override
public AttributesChange<OID> deleteAttribute(OID objectId, String key) {
return this.deleteAttributes(objectId, Lists.newArrayList(key));
}
@Override
public AttributesChange<OID> deleteAttributes(OID objectId) {
Assert.notNull(objectId, "objectId is not null");
Map<String, AttributeChange> added = Maps.newHashMap();
Map<String, AttributeChange> updated = Maps.newHashMap();
Map<String, AttributeChange> removed = Maps.newHashMap();
List<String> removeKeyList = Lists.newArrayList();
Map<String, Object> previousMap = getAttributes(objectId);
if (!CollectionUtil.isEmpty(previousMap)) {
for (Map.Entry<String, Object> entry : previousMap.entrySet()) {
removed.put(entry.getKey(), AttributeChange.builder().previous(entry.getValue()).current(null).build());
removeKeyList.add(entry.getKey());
}
if (!CollectionUtil.isEmpty(removeKeyList)) {
attributeDao.deleteAttributes(table, objectId, removeKeyList);
}
}
return buildResult(objectId, added, updated, removed);
}
@Override
public AttributesChange<OID> deleteAttributes(OID objectId, Iterable<String> keys) {
Assert.notNull(objectId, "objectId is not null");
Assert.notNull(keys, "keys is not null");
Map<String, AttributeChange> added = Maps.newHashMap();
Map<String, AttributeChange> updated = Maps.newHashMap();
Map<String, AttributeChange> removed = Maps.newHashMap();
Map<String, Object> previousMap = getAttributes(objectId);
List<String> previousKeyList = Lists.newArrayList(previousMap.keySet());
List<String> currentKeyList = Lists.newArrayList(keys);
List<String> removeKeyList = CollectionUtil.intersection(previousKeyList, currentKeyList);
if (!CollectionUtil.isEmpty(previousMap) && !CollectionUtil.isEmpty(removeKeyList)) {
for (String key : removeKeyList) {
removed.put(key, AttributeChange.builder().previous(previousMap.get(key)).current(null).build());
}
attributeDao.deleteAttributes(table, objectId, removeKeyList);
}
return buildResult(objectId, added, updated, removed);
}
/** ä¿åæ©å±å±æ§æ¶å¯¹è±¡ç±»åè½¬æ¢ */
private void convertType(Object obj, Attribute<OID> attribute) {
String type = null;
String value = null;
if (obj instanceof Integer) {
type = Integer.class.getSimpleName();
value = obj.toString();
} else if (obj instanceof Float) {
type = Float.class.getSimpleName();
value = obj.toString();
} else if (obj instanceof Double) {
type = Double.class.getSimpleName();
value = obj.toString();
} else if (obj instanceof BigDecimal) {
type = BigDecimal.class.getSimpleName();
value = obj.toString();
} else if (obj instanceof Long) {
type = Long.class.getSimpleName();
value = obj.toString();
} else if (obj instanceof Date) {
type = Date.class.getSimpleName();
Date date = (Date) obj;
value = String.valueOf(date.getTime());
} else if (obj instanceof Boolean) {
type = Boolean.class.getSimpleName();
value = obj.toString();
} else if (obj instanceof String) {
type = String.class.getSimpleName();
value = obj.toString();
} else {
if (null != obj ) {
type = String.class.getSimpleName();
value = obj.toString();
}
}
attribute.setType(type);
attribute.setValue(value);
}
/**
* è¿åå¼ç±»å转æ¢
*/
private Object convertType(Attribute<OID> attribute) {
String type = attribute.getType();
String value = attribute.getValue();
Object result = null;
if (null != type && null != value) {
if (Integer.class.getSimpleName().equals(type)) {
result = Integer.valueOf(value);
} else if (Float.class.getSimpleName().equals(type)) {
result = Float.valueOf(value);
} else if (Double.class.getSimpleName().equals(type)) {
result = Double.valueOf(value);
} else if (BigDecimal.class.getSimpleName().equals(type)) {
result = BigDecimal.valueOf(Double.valueOf(value));
} else if (Long.class.getSimpleName().equals(type)) {
result = Long.valueOf(value);
} else if (Date.class.getSimpleName().equals(type)) {
result = new Date(Long.valueOf(value));
} else if (Boolean.class.getSimpleName().equals(type)) {
result = Boolean.valueOf(value);
} else if (String.class.getSimpleName().equals(type)) {
result = String.valueOf(value);
} else {
result = value;
}
}
return result;
}
private AttributesChange<OID> buildResult(OID objectId, Map<String, AttributeChange> added, Map<String, AttributeChange> updated, Map<String, AttributeChange> removed) {
AttributesChange<OID> result = AttributesChange.<OID>builder().objectId(objectId).added(added).updated(updated).removed(removed).build();
if (!CollectionUtil.isEmpty(added) || !CollectionUtil.isEmpty(updated) || !CollectionUtil.isEmpty(removed)) {
sendAttributesChangeEvent(result);
}
return result;
}
/**
* åéå±æ§åæ´æ¶æ¯
*/
private void sendAttributesChangeEvent(AttributesChange<OID> attributesChange) {
if (eventPublisher == null) {
return;
}
AttributesChangedEvent<OID> event = AttributesChangedEvent.<OID>builder()
.data(attributesChange)
.occurredTime(new Date())
.build();
eventPublisher.publishAttributesChangedEvent(event, table);
log.debug("{} is published.", event);
}
}
å¤æ³¨
- å®ç°é»è¾ä»£ç æ¶æ¯è¾åé¿ï¼æ¬ä¸æ³ç²è´´åºæ¥çï¼ä½æ¯ä¸ºäºä»£ç çå®æ´æ§ï¼è¿æ¯ç²è´´åºæ¥å§_ï¼æ们çå°ï¼ä»£ç ä¸æåä¼ç»ä¸å°è£ ä¸ä¸ªå±æ§åæ´äºä»¶ï¼å¹¶å°äºä»¶æç¨spring cloud stream æåºï¼å ·ä½äºä»¶ç±»è¯·çä¸é¢
AttributesChangedEventå±æ§äºä»¶åæ´
package com.zm.zhuma.commons.attributes.model;
import java.io.Serializable;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AttributesChangedEvent<OID> implements Serializable {
private static final long serialVersionUID = -5098574719305009319L;
private AttributesChange<OID> data;
private Date occurredTime;
}
package com.zm.zhuma.commons.attributes.model;
import java.io.Serializable;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AttributesChange<OID> implements Serializable {
private static final long serialVersionUID = -5008407345712737581L;
private String objectType;
private OID objectId;
private Map<String, AttributeChange> added;
private Map<String, AttributeChange> updated;
private Map<String, AttributeChange> removed;
}
package com.zm.zhuma.commons.attributes.model;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AttributeChange implements Serializable {
private static final long serialVersionUID = -662090239071614840L;
private Object previous;
private Object current;
}
å¤æ³¨
- å¯ä»¥çå°ææçè½å½±åå±æ§è¡¨çæ¹æ³é½ç»ä¸çè¿åäºå±æ§åæ´äºä»¶ï¼å ¶å®å®æ¯ç¨addedãupdateãremoveçmapç±»åæ¥æ¶ï¼è¿åäºå¢å ãä¿®æ¹ãå é¤å±æ§æ¶ï¼å±æ§çåæ´åå段ååæ´åçå段ï¼ä¸ºä»ä¹è¿ä¹åå¢ï¼åå æ两ç¹ï¼ä¸ä¸ªæ¯è¿æå©äºæ们对å±æ§ä¿®æ¹å对åæ´æ åµççææ§ï¼æå©äºè°ç¨ç«¯å¯¹ç»æç使ç¨ï¼å ¶å®è¿æä¸ç¹ï¼å°±æ¯æ们ä¼å¨éç¨å±æ§æå¡å®ç°é»è¾ä¸å å ¥stream rabbitMQçæ¶æ¯æåºï¼ä¹ä¼å ¬ç¨è¯¥å¯¹è±¡
æµè¯
å±æ§æµè¯æ§å¶å¨
package com.zhuma.demo.web.demo5;
import com.zm.zhuma.commons.attributes.model.AttributesChange;
import com.zm.zhuma.commons.attributes.service.AttributeService;
import com.zm.zhuma.commons.model.bo.Node;
import com.zm.zhuma.commons.web.annotations.ResponseResult;
import com.zm.zhuma.user.client.OrgClient;
import com.zm.zhuma.user.model.po.Org;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* @desc ç¨æ·ç®¡çæ§å¶å¨
*
* @author zhumaer
* @since 7/16/2018 16:37 PM
*/
@ResponseResult
@RestController("demo4UserAttrController")
@RequestMapping("demo4/users/{userId}/attrs")
public class UserAttrController {
@Autowired
private AttributeService<String> userAttributeService;
@PostMapping
AttributesChange<String> add(@PathVariable("userId") String userId,@RequestBody Map<String, Object> attrMap) {
return userAttributeService.addAttributes(userId, attrMap);
}
@GetMapping
Map<String, Object> get(@PathVariable("userId") String userId) {
return userAttributeService.getAttributes(userId);
}
@PutMapping
AttributesChange<String> put(@PathVariable("userId") String userId,@RequestBody Map<String, Object> attrMap) {
return userAttributeService.setAttributes(userId, attrMap);
}
@DeleteMapping
AttributesChange<String> delete(@PathVariable("userId") String userId) {
return userAttributeService.deleteAttributes(userId);
}
}
POST MANæªå¾
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2Lc1DOWlVNGdVZwZkMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39TO1cDM1QDM5AzNxcDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
æ°æ®åºæªå¾
å¤æ³¨
- æä»¬ä» æµè¯äºä¸ä¸ªæ°å¢å±æ§çåºæ¯ï¼è¯¾åï¼å¤§å®¶è¯ä¸ä¸ä¿®æ¹å é¤åè·åçåºæ¯å§_
ç»æè¯
éç¨å±æ§æå¡çä»ç»å°æ¤ç»æï¼è¯¥æå¡è¿ç¨å°å¹³æ¶å¼åä¸ï¼ä¸å®ä¼å¤§å¤§å¢å å¼åæçï¼ä½æ¯ææææ å¿çä¸ç¹å°±æ¯ï¼å 为å±æ§è¡¨çå¢å ï¼ä½¿ç¨äººä¼æåç»ä¸å¡æ°å¢å段é½å½ç»ä¸ºæ©å±å±æ§ï¼é½æå°å±æ§è¡¨ä¸ï¼è¿å¹¶ä¸æ¯ä¸ç§å¥½çæ¹æ³ï¼è¿æ¯å»ºè®®ä¸»è¡¨å段åæ©å±å±æ§å段åç¦»æ¸ æ¥ãç¥å¥½ ~~~
éä¸æ¬å®ä¾ä»£ç githubå°åï¼æ¬å®ä¾å¨zhuma-demo项ç®ä¸ï¼demo5模åï¼ï¼https://github.com/zhumaer/zhuma
æºç githubå°åï¼https://github.com/zhumaer/zhuma
QQ群å·ï¼629446754ï¼æ¬¢è¿å 群ï¼
欢è¿å ³æ³¨æ们çå ¬ä¼å·æå 群ï¼çä½ å¦ï¼