这种场景参加工作几个月来,遇到了很几次了,其中还出现过两次bug。这次我还想整理下。
假定场景,活动,和门店存在绑定关系,一个活动可以绑定多个门店。一个门店也能绑定多个活动。这应该算多对多的关系吧,不过同样适应。
首先假定,一对多。一个活动绑定多个门店。
首先是要看数据库怎么存储的,一对多是可以选择的比如:
活动id为3 绑定门店id为 1,2,3,4,5,6,7 这几个门店。
可以这么存,数据库一条记录搞定
actid shopid
3 1,2,3,4,5,6,7
或者
actid shopid
3 1
3 2
.. ...
3 7
那么当我们拿到前台提交的数据应该怎么处理呢?通常我有两张方法解决,
一:直接先删除所有该活动的关系记录,然后重新插入。这是残暴型。
二:根据活动ID 找出原有的关系,然后进行对比,任何一方为空数据,则表明是要完全insert或者完全delete 若都有数据,判断数据是否有不同,若相同不处理,若不同,则找出不同部分,然后看不同部分属于谁?若是属于数据库查出来的数据,则说明要删除,反之则说明要增加。
代码:
$id = I('post.id'); $B = I('post.shopid'); $rela = M('manageshop_shop')->where(array('mid'=>$id))->select(); if($rela){ foreach($rela as $key => $val){ $A[] = $val['shopid']; } } //得出已关联的门店的id 数组 //找出AB的不同部分 //先判断B 是否有值 若没有全部删掉 关系表中相关记录 if(!empty($A) && !empty($B)){ $C = array_merge(array_diff($A,$B),array_diff($B,$A)); if(!empty($C)){ //判断这个不同的 属于哪个数组 若属于A 则表明需要删除 反之则.... if(in_array($C[0],$A) && in_array($C[count($C)-1],$A)){ //删除 //拼装sql $tempStr = implode(',',$C); $sql = 'DELETE FROM `gzsd_manageshop_shop` WHERE mid = \''.$id.'\'AND shopid IN('.$tempStr.')'; $D->execute($sql); }else if(in_array($C[0],$B) && in_array($C[count($C)-1],$B)){ //新增//拼装sql $sql = 'insert into `gzsd_manageshop_shop`(`shopid`,`mid`) values'; foreach($C as $key=>$val){ if($key == count($C)-1){ $sql .= "('$val','$id')"; }else{ $sql .= "('$val','$id'),"; } } $D->execute($sql); }else{ //两者都包含了纪要减又要加 $sql_del = null; $sql_ins = 'insert into `gzsd_manageshop_shop`(`shopid`,`mid`) values'; $temp = null; foreach($C as $key=>$val){ if(in_array($val,$A)){ //删除 $temp[] = $val; }else{ if($key == count($C)-1){ $sql_ins .= "('$val','$id')"; }else{ $sql_ins .= "('$val','$id'),"; } } } $tempStr = implode(',',$temp); $sql_del = 'DELETE FROM `gzsd_manageshop_shop` WHERE mid = \''.$id.'\'AND shopid IN('.$tempStr.')'; $D->execute($sql_del); $D->execute($sql_ins); } } //为空说明选项没有变化 }else if(empty($A)){ //直接执行添加 $sql = 'insert into `gzsd_manageshop_shop`(`shopid`,`mid`) values'; foreach($B as $key=>$val){ if($key == count($B)-1){ $sql .= "('$val','$id')"; }else{ $sql .= "('$val','$id'),"; } } $D->execute($sql); }else{ //执行删除 $sql = "delete from `gzsd_manageshop_shop` where mid = $id "; $D->execute($sql); }
这里应该属于数据库存储为,第二种方式。
第一种方式思路也是一样,只是对字符串要处理下,expload一下,就可以了。
二: 多对多的处理,这个其实从我们角度来看也是一对多,只是确定下是从那个对象过来的,是活动绑定门店,还是门店绑定活动,然后再按照方法写逻辑就好了,他们最终在数据库的存储是一样的,殊途同归呀。
,也不赘述了。