20、ThinkPHP多表多对多关联模型的增删改查操作

阅读() @2018-07-15 14:13:39

首先需要注意下:我用的ThinkPHP版本是3.1.3。

比如我们在做RBAC权限管理、文章添加属性的时候都会用到关联模型,今天用到的是多对多和多对一关联模型。

在这个ThinkPHP版本中,使用官方提供的多对多关联模型进行插入操作的时候,中间表中的数据会执行:

delete from think_article_attr;

然后在重新插入数据,这样的结果并不是我们想要的,因为之前的数据记录会全部被删除,相信在今后的版本中ThinkPHP官方已经解决了这个问题,这个问题也仅仅存在于多对多的关联模型中,多对一、一对多、一对一模型中不存在这个问题。

那么目前我们要用到多对多关联模型,所以就不能使用官方提供的方法进行操作了,需要自己写数据库的添加方法,比如我在后台添加文章的时候,需要给文章增加一个属性(推荐、置项、喜欢等等),那么这是一个多对多的关系,方法如下:

/* 
 * 添加文章数据处理 */
public function addArticleForm(){
    //获取文章标题、所属栏目、内容
    $articleData = array(
        'title' => I('title'),
        'cate' => I('cate'),
        'content' => I('content')
    );
    //获取文章属性
    $attrList = I('attr');
    //如果指定了文章属性,就插入数据库
    if($bid = M('article')->data($articleData)->add()){
        if(count($attrList)){
            $sql = 'insert into '.C('DB_PREFIX').'article_attr(aid,bid) ';
            foreach($attrList as $value){
                $sql = 'insert into '.C('DB_PREFIX').'article_attr set aid="'.$value.'",bid="'.$bid.'"';
                M('article_attr')->query($sql);
            }
            
        }
        $this->success('添加成功', U('Admin/Index/index'));
    }else{
        $this->error('添加失败');
    }
}

在读取文章列表的时候,也要用到多对多关联模型,但是读取是没问题的,只是写入的时候有问题,例如下面使用thinkphp多对多关联模型读取数据的代码:

ArticleRelationModel.class.php模型中的代码:

<?php
    /* 
     * 文章列表关联模型 */
    class ArticleRelationModel extends RelationModel{
        //定义主表
        protected $tableName = 'article';
        //定义关联关系
        protected $_link = array(
            'attr' => array(
                'mapping_type' => MANY_TO_MANY,//关联类型
                'mapping_name' => 'attr',//副表
                'foreign_key' => 'bid',//主表外键(在中间表中)
                'relation_foreign_key' => 'aid',//副表外键(在中间表)
                'relation_table' => 'think_article_attr',//中间表
            ),
            'cate' => array(
                'mapping_type' => BELONGS_TO,
                'mapping_name' => 'cate',
                'foreign_key' => 'cate',
                'mapping_fields' => 'cname'
            )
        );
        public function articleShow($type=0){
            return $this->where(array('is_del'=>$type))->relation(true)->select();
        }
    }

控制器里边的方法:

/* 
 * 文章列表 */
public function articleList(){
    $articleList = D('ArticleRelation')->articleShow(0);
    $this->assign('articleList', $articleList);
    $this->display('articleList'); 
}

如果不想用ThinPHP提供的多表查询方法,可以自己写方法,如下:

/* 
 * 文章列表 */
public function articleList(){
   /*  $articleList = D('ArticleRelation')->articleShow(0);
    $this->assign('articleList', $articleList);
    $this->display('articleList'); */
    
  import('Class.ArticleListShow', APP_PATH);
  
  $this->assign('articleList', ArticleListShow::articleShow(0));
  $this->display();  
    
}

因为在其他地方也使用到了ArticleListShow这个类,所以进行了封装,封装代码如下:

<?php
    class ArticleListShow{
        static public function articleShow($type=0){
            $article = M('article')->where(array('is_del'=>$type))->select();
            $newArry = array();
            $aidArryMerge = array();
            foreach($article as $value){
                $cate = 'select cname from think_cate where id="'.$value["cate"].'"';
                $a = M('cate')->query($cate);
                $value['cate'] = $a[0]['cname'];
            
                $aidSql = 'select aid from think_article_attr where bid="'.$value['id'].'"';
            
                $aidArry = M('article_attr')->query($aidSql);
            
                $aidArryMerge[] = $aidArry;
            
                foreach($aidArry as $v){
                    $attrNameSql = 'select name,bgcolor from think_attr where id="'.$v["aid"].'"';
                    $attrNameArry = M('attr')->query($attrNameSql);
                    // p($attrNameArry);
                    $value['attr'][] = array(
                        'name' => $attrNameArry[0]['name'],
                        'bgcolor' => $attrNameArry[0]['bgcolor']
                    );
                }
            
            
                $newArry[] = $value;
            }
            
            
            return $newArry;
        }
    }

完!

微信二维码
锐壳主机