赞
踩
本项目是个微服务项目,采用前后端分离方式进行协作开发。需求描述:表A和和表B通过equity_id进行关联,其中A->B是一对多且双向绑定关系。对此关联关系保证可编辑和新增。整体思路:新增时候直接双向绑定,修改时候先根据id全部删除,再新增关联关系。特此设计整理如下:
CREATE TABLE `equity_limit_buy_set` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`del_flag` bit(1) NOT NULL DEFAULT b'0' COMMENT '删除状态:0否,1是',
`equity_id` bigint(20) NOT NULL COMMENT '权益id',
`effective_days` tinyint(1) NOT NULL DEFAULT '0' COMMENT '自购买后有效天数:默认值0:无限制',
`limit_buy_num_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '购买次数类型限制:0不限购,1终身限购,2按周期限购,默认值0',
`limit_buy_num_cycle` tinyint(1) NOT NULL DEFAULT '0' COMMENT '购买次数周期限制:0终生,1每天,2每周,3每月',
`limit_buy_num` int(11) NOT NULL DEFAULT '-1' COMMENT '限购数量:默认值:-1不限购',
`limit_buy_user` bit(1) NOT NULL DEFAULT b'0' COMMENT '人群标签ID,0不限制购买人群,1:限制',
`mutex_equity` bit(1) NOT NULL DEFAULT b'0' COMMENT '互斥权益ID列表,默认值:0没有互斥权益,1:有互斥权益',
`stock_num` int(11) NOT NULL DEFAULT '-1' COMMENT '库存数量',
`buy_button_text` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '立即购买' COMMENT '权益详情页:按钮文本',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_equity_id` (`equity_id`)
) COMMENT='权益限购设置';
CREATE TABLE `equity_limit_buy_mutex_equity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
`del_flag` bit(1) NOT NULL DEFAULT b'0' COMMENT '删除状态:0否,1是',
`equity_id` bigint(20) NOT NULL COMMENT '权益id',
`mutex_equity_id` bigint(20) NOT NULL COMMENT '互斥权益id',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_equity_id` (`equity_id`),
KEY `idx_mutex_equity_id` (`mutex_equity_id`)
) COMMENT='互斥权益关联设置';
其中equity_limit_buy_set中如果没有mutex_equity互斥权益,则mutex_equity为0;如果有则为1。然后在equity_limit_buy_mutex_equity中维护equity_id和mutex_equity_id的双向绑定关联关系。
public class EquityLimitBuySetConstant {
/**
* 购买次数限制:0不限购,1终身限购,2按周期限购,默认值0
*/
@Getter
@AllArgsConstructor
public enum limitBuyNumTypeEnum{
no_purchase_restrictions(0,"不限购"),
lifetime_limit(1,"终身限购"),
restricted_by_cycle(2,"按周期限购");
private int code;
private String message;
}
/**
*购买次数限制:0终生,1每天,2每周,3每月
*/
@Getter
@AllArgsConstructor
public enum limitBuyNumCycleEnum{
lifetime(0,"终生") {
@Override
public Date[] getIntervalTime() {
return null;
}
},
daily(1,"每天") {
@Override
public Date[] getIntervalTime() {
return new Date[]{DateUtils.getStartOfDay(new Date()),DateUtils.getEndOfDay(new Date())};
}
},
weekly(2,"每周") {
@Override
public Date[] getIntervalTime() {
return DateUtils.getWeekStartAndEnd(0);
}
},
monthly(3,"每月") {
@Override
public Date[] getIntervalTime() {
return DateUtils.getMonthStartAndEnd();
}
};
private int code;
private String message;
protected abstract Date[] getIntervalTime();
public static Date[] getDateArray(int code){
final limitBuyNumCycleEnum cycleEnum = Arrays.stream(values()).filter(v -> v.code == code).findFirst().orElse(null);
if(Objects.isNull(cycleEnum)){
return null;
}
return cycleEnum.getIntervalTime();
}
}
@Data
public class EquityInfoEditReq {
@ApiModelProperty("权益基本信息")
@NotNull(message = "权益基本信息不能为空")
private EquityInfo baseInfo;
@ApiModelProperty("权益附加信息")
private EquityInfoExt extInfo;
@ApiModelProperty("权益限购设置")
private EquityLimitBuySetReq equityLimitBuySetReq;
}
EquityLimitBuySetReq
@Data
public class EquityLimitBuySetReq{
@ApiModelProperty("权益id")
private Long equityId;
@ApiModelProperty("自购买后有效天数:默认值0:无限制,其他值为实际有效天数")
private Integer effectiveDays;
@ApiModelProperty("购买次数限制:0不限购,1终身限购,2按周期限购,默认值0")
private Integer limitBuyNumType;
@ApiModelProperty("购买周期限制:0终生,1每天,2每周,3每月,默认值0")
private Integer limitBuyNumCycle;
@ApiModelProperty("限购数量:默认值:-1不限购,其他值为实际限购数量")
private Integer limitBuyNum;
@ApiModelProperty("限购人群设置:默认0不限制购买人群,1:限制;实际限购人群配置在limitBuyUserGroup")
private Byte limitBuyUser;
@ApiModelProperty("互斥权益设置:默认值0没有互斥权益,1:有互斥权益;实际互斥权益配置在mutexEquityIds")
private Byte mutexEquity;
@ApiModelProperty("库存数量:默认-1不限制,其他值为实际库存数量")
private Integer stockNum;
@ApiModelProperty("限购人群组列表")
private List<Long> limitBuyUserGroup;
@ApiModelProperty("互斥权益列表")
private List<Long> mutexEquityIds;
@ApiModelProperty(value = "权益详情页:购买按钮文本")
private String buyButtonText;
}
public interface EquityLimitBuySetService extends IService<EquityLimitBuySet> {
/**
* 获取权益限购设置
* @param limitBuySetByEquityId
* @return EquityLimitBuySet
*/
EquityLimitBuySet getLimitBuySetByEquityId(Long limitBuySetByEquityId);
/**
* 移除权益限购设置
* @param equityId
* @return boolean
*/
boolean removeByEquityId(Long equityId);
/**
* 获取权益购买限制配置
* @param id
* @return
* @throws Exception
*/
EquityLimitBuySetReq getLimitBuySet(Long id) throws Exception;
}
@Service
public class EquityLimitBuySetServiceImpl extends ServiceImpl<EquityLimitBuySetMapper, EquityLimitBuySet>
implements EquityLimitBuySetService{
@Autowired
private EquityLimitBuyUserService equityLimitBuyUserService;
@Autowired
private EquityLimitBuyMutexEquityService equityLimitBuyMutexEquityService;
private static final String BUY_SET = "buySet";
/**
* 获取权益限购设置
* @param equityId
* @return EquityLimitBuySet
*/
@Override
@Cacheable(value = BUY_SET,key = "#p0")
public EquityLimitBuySet getLimitBuySetByEquityId(Long equityId) {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("equity_id",equityId);
return baseMapper.selectOne(queryWrapper);
}
/**
* 移除权益限购设置
* @param equityId
* @return boolean
*/
@CacheEvict(value=BUY_SET,key="#p0")
@Override
public boolean removeByEquityId(Long equityId) {
return lambdaUpdate()
.eq(EquityLimitBuySet::getEquityId, equityId)
.remove();
}
/**
* 获取权益购买限制配置
* @param id
* @return
* @throws Exception
*/
@Override
public EquityLimitBuySetReq getLimitBuySet(Long id) throws Exception {
EquityLimitBuySet equityLimitBuySet = this.getLimitBuySetByEquityId(id);
if (equityLimitBuySet != null) {
EquityLimitBuySetReq equityLimitBuySetReq = BeanCopyUtils.copyProperties(EquityLimitBuySetReq.class, equityLimitBuySet);
if(equityLimitBuySet.getMutexEquity()){
equityLimitBuySetReq.setMutexEquityIds(equityLimitBuyMutexEquityService.getMutexEquity(id));
}
if(equityLimitBuySet.getLimitBuyUser()){
equityLimitBuySetReq.setLimitBuyUserGroup(equityLimitBuyUserService.getEquityLimitBuyUserByEquityId(id));
}
return equityLimitBuySetReq;
}
return null;
}
/**
* 重写saveOrUpdate方法,清空缓存
* */
@CacheEvict(value=BUY_SET,key="#p0.equityId")
@Override
public boolean saveOrUpdate(EquityLimitBuySet entity) {
return super.saveOrUpdate(entity);
}
}
public interface EquityLimitBuyMutexEquityService extends IService<EquityLimitBuyMutexEquity> {
/**
* 查找互斥权益
* @param limitBuyMutexByEquityId
* @return
*/
List<Long> getMutexEquity(Long limitBuyMutexByEquityId);
/**
* 保存权益和互斥权益关联关系
* @param equityId
* @param mutexEquityIds
*/
void saveOrUpdateLimitBuyMutex(Long equityId, List<Long> mutexEquityIds);
/**
* 移除互斥权益关联设置关系
* @param equityId
* @return
*/
boolean removeByEquityId(Long equityId);
}
@Service
public class EquityLimitBuyMutexEquityServiceImpl extends ServiceImpl<EquityLimitBuyMutexEquityMapper, EquityLimitBuyMutexEquity>
implements EquityLimitBuyMutexEquityService{
private final static String BUY_MUTEX_EQUITY = "buyMutexEquity";
/**
* 查找互斥权益
* @param limitBuyMutexByEquityId
* @return
*/
@Override
@Cacheable(value = BUY_MUTEX_EQUITY,key = "#p0")
public List<Long> getMutexEquity(Long limitBuyMutexByEquityId) {
final List<EquityLimitBuyMutexEquity> equities = lambdaQuery().eq(EquityLimitBuyMutexEquity::getEquityId, limitBuyMutexByEquityId)
.select(EquityLimitBuyMutexEquity::getMutexEquityId)
.list();
return equities.stream().map(EquityLimitBuyMutexEquity::getMutexEquityId).collect(Collectors.toList());
}
/**
* 保存权益和互斥权益关联关系
* @param equityId
* @param mutexEquityIds
*/
@CacheEvict(value = BUY_MUTEX_EQUITY,key="#p0")
@Override
public void saveOrUpdateLimitBuyMutex(Long equityId, List<Long> mutexEquityIds) {
List<EquityLimitBuyMutexEquity> buyMutexEquity = new ArrayList<>();
//删除双向绑定的互斥关系,采用nonIn是增量更新删除,提升效率
lambdaUpdate()
.notIn(EquityLimitBuyMutexEquity::getMutexEquityId,mutexEquityIds)
.eq(EquityLimitBuyMutexEquity::getEquityId,equityId)
.remove();
lambdaUpdate()
.notIn(EquityLimitBuyMutexEquity::getEquityId,mutexEquityIds)
.eq(EquityLimitBuyMutexEquity::getMutexEquityId,equityId)
.remove();
//查找双向绑定的互斥关系
List<EquityLimitBuyMutexEquity> mutexIdsList = lambdaQuery()
.in(EquityLimitBuyMutexEquity::getMutexEquityId, mutexEquityIds)
.eq(EquityLimitBuyMutexEquity::getEquityId,equityId)
.list();
List<EquityLimitBuyMutexEquity> equityIdsList = lambdaQuery()
.eq(EquityLimitBuyMutexEquity::getMutexEquityId, equityId)
.in(EquityLimitBuyMutexEquity::getEquityId,mutexEquityIds)
.list();
//获取双向绑定的互斥权益id和权益id
Set<Long> mutexIds = mutexIdsList.stream().map(EquityLimitBuyMutexEquity::getMutexEquityId).collect(Collectors.toSet());
Set<Long> equityIds = equityIdsList.stream().map(EquityLimitBuyMutexEquity::getEquityId).collect(Collectors.toSet());
//保存双向绑定的关联关系
mutexEquityIds.stream().forEach(
i -> {
if(!mutexIds.contains(i)){
EquityLimitBuyMutexEquity mutexIdEquity = EquityLimitBuyMutexEquity.builder()
.equityId(equityId)
.mutexEquityId(i)
.build();
buyMutexEquity.add(mutexIdEquity);
}
if(!equityIds.contains(i)){
EquityLimitBuyMutexEquity equityIdEquity = EquityLimitBuyMutexEquity.builder()
.equityId(i)
.mutexEquityId(equityId)
.build();
buyMutexEquity.add(equityIdEquity);
}
});
this.saveBatch(buyMutexEquity);
}
/**
* 移除互斥权益关联设置关系
* @param equityId
* @return
*/
@CacheEvict(value = BUY_MUTEX_EQUITY,key="#p0")
@Override
public boolean removeByEquityId(Long equityId) {
return lambdaUpdate()
.eq(EquityLimitBuyMutexEquity::getEquityId,equityId)
.remove();
}
}
/**
* 保存或修改权益限购设置
*
* @param equityId
* @param req
* @return Long
* @throws CommonException
*/
public Boolean saveOrUpdateEquityLimitBuySet(Long equityId, EquityInfoEditReq req) throws Exception {
EquityLimitBuySetReq buySetReq = req.getEquityLimitBuySetReq();
if (buySetReq != null) {
EquityLimitBuySet equityLimitBuySet = BeanCopyUtils.copyProperties(EquityLimitBuySet.class, buySetReq);
equityLimitBuySet.setDelFlag(false);
equityLimitBuySet.setEquityId(equityId);
EquityLimitBuySet limitBuySetByEquityId = equityLimitBuySetService.getLimitBuySetByEquityId(equityId);
if(limitBuySetByEquityId != null){
//后续用于保存或者新增判断标志
equityLimitBuySet.setId(limitBuySetByEquityId.getId());
}
//互斥权益id列表
List<Long> mutexEquityIds = buySetReq.getMutexEquityIds();
//保存或修改互斥权益id列表
if (CollectionUtils.isEmpty(buySetReq.getMutexEquityIds())) {
equityLimitBuySet.setMutexEquity(false);
//删除缓存
equityLimitBuyMutexEquityService.removeByEquityId(equityId);
} else {
equityLimitBuySet.setMutexEquity(true);
equityLimitBuyMutexEquityService.saveOrUpdateLimitBuyMutex(equityId, mutexEquityIds);
}
equityLimitBuySetService.saveOrUpdate(equityLimitBuySet);
}else{
//权益限购设置为空的时候移除缓存
equityLimitBuySetService.removeByEquityId(equityId);
equityLimitBuyMutexEquityService.removeByEquityId(equityId);
}
return true;
}
新增和删除关联关系表数据时候,需要考虑各种情况,尤其是对缓存淘汰时机的把控。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。