生活随笔
收集整理的這篇文章主要介紹了
ECMALL数据库关系模型的实现
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
所謂模型,則是一個(gè)一個(gè)的數(shù)據(jù)實(shí)體,換句話說就是一個(gè)數(shù)據(jù)表,你可以基于這個(gè)模
型,調(diào)用model.base.php中的數(shù)據(jù)庫操作函數(shù)來對數(shù)據(jù)進(jìn)行增、刪、改、查的操作。
這里的業(yè)務(wù)模型,是在實(shí)體模型基礎(chǔ)上,再繼承一次,然后對一些方法進(jìn)行重寫。
系統(tǒng)中只有三個(gè)實(shí)體有業(yè)務(wù)模型:
推薦類型 recommend;商品數(shù)據(jù)模型 goods;商品分類業(yè)務(wù)模型 gcategory;
具體操作例子:
//物品表的操作:
$model_goods = & m(‘goods’);
$goods_info = $model_goods->get($goods_id); 這里需要解釋一下對于數(shù)據(jù)模型的操作是怎樣的一個(gè)函數(shù)調(diào)用過程:
首先:$model_goods = &m(‘goods’);
對于數(shù)據(jù)庫關(guān)系模型的分析,我覺得需要從兩個(gè)函數(shù)說起:
//獲取一個(gè)模型 function &m($model_name, $params = array(), $is_new = false) { static $models = array(); $model_hash = md5($model_name . var_export($params, true)); if ($is_new || !isset($models[$model_hash])) { $model_file = ROOT_PATH . ‘/includes/models/’ . $model_name . ‘.model.php'; if (!is_file($model_file)) { /* 不存在該文件,則無法獲取模型 */ return false; } include_once($model_file); $model_name = ucfirst($model_name) . ‘Model'; if ($is_new) { return new $model_name($params, db()); } $models[$model_hash] = new $model_name($params, db()); } return $models[$model_hash]; } //獲取一個(gè)業(yè)務(wù)模型 function &bm($model_name, $params = array(), $is_new = false) { static $models = array(); $model_hash = md5($model_name . var_export($params, true)); if ($is_new || !isset($models[$model_hash])) { $model_file = ROOT_PATH . ‘/includes/models/’ . $model_name . ‘.model.php'; if (!is_file($model_file)) { /* 不存在該文件,則無法獲取模型 */ return false; } include_once($model_file); $model_name = ucfirst($model_name) . ‘BModel'; if ($is_new) { return new $model_name($params, db()); } $models[$model_hash] = new $model_name($params, db()); } return $models[$model_hash]; } 我們看一下&m()函數(shù)的代碼,其中var_export()函數(shù)則是將傳進(jìn)來的實(shí)體,返回相應(yīng)的實(shí)體類對象,因?yàn)樗械膍odel都繼承至model.base.php中的BaseModel類,這個(gè)類中定義了基本所有的操作函數(shù),因此$model_goods對象可以對數(shù)據(jù)庫進(jìn)行相應(yīng)的操作。
而我們再看看goods.model.php中的GoodsModel的代碼:
class GoodsModel extends BaseModel { var $table = ‘goods'; var $prikey = ‘goods_id'; var $alias = ‘g';//縮寫 var $_name = ‘goods'; var $temp; // 臨時(shí)變量 var $_relation = array( // 一個(gè)商品對應(yīng)一條商品統(tǒng)計(jì)記錄 ‘has_goodsstatistics’ => array( ‘model’ => ‘goodsstatistics’, ‘type’ => HAS_ONE, ‘foreign_key’ => ‘goods_id’, ‘dependent’ => true ), // 一個(gè)商品對應(yīng)多個(gè)規(guī)格 ‘has_goodsspec’ => array( ‘model’ => ‘goodsspec’, ‘type’ => HAS_MANY, ‘foreign_key’ => ‘goods_id’, ‘dependent’ => true ), // 一個(gè)商品對應(yīng)一個(gè)默認(rèn)規(guī)格 ‘has_default_spec’ => array( ‘model’ => ‘goodsspec’, ‘type’ => HAS_ONE, ‘refer_key’ => ‘default_spec’, ‘foreign_key’ => ‘spec_id’, ), // 一個(gè)商品對應(yīng)多個(gè)屬性 ‘has_goodsattr’ => array( ‘model’ => ‘goodsattr’, ‘type’ => HAS_MANY, ‘foreign_key’ => ‘goods_id’, ‘dependent’ => true ), // 一個(gè)商品對應(yīng)多個(gè)圖片 ‘has_goodsimage’ => array( ‘model’ => ‘goodsimage’, ‘type’ => HAS_MANY, ‘foreign_key’ => ‘goods_id’, ‘dependent’ => true ), // 一個(gè)商品只能屬于一個(gè)店鋪 ‘belongs_to_store’ => array( ‘model’ => ‘store’, ‘type’ => BELONGS_TO, ‘foreign_key’ => ‘store_id’, ‘reverse’ => ‘has_goods’, ), // 商品和分類是多對多的關(guān)系 ‘belongs_to_gcategory’ => array( ‘model’ => ‘gcategory’, ‘type’ => HAS_AND_BELONGS_TO_MANY, ‘middle_table’ => ‘category_goods’, ‘foreign_key’ => ‘goods_id’, ‘reverse’ => ‘has_goods’, ), // 商品和會員是多對多的關(guān)系(會員收藏商品) ‘be_collect’ => array( ‘model’ => ‘member’, ‘type’ => HAS_AND_BELONGS_TO_MANY, ‘middle_table’ => ‘collect’, ‘foreign_key’ => ‘item_id’, ‘ext_limit’ => array(‘type’ => ‘goods’), ‘reverse’ => ‘collect_goods’, ), // 商品和推薦類型是多對多的關(guān)系 todo ‘be_recommend’ => array( ‘model’ => ‘recommend’, ‘type’ => HAS_AND_BELONGS_TO_MANY, ‘middle_table’ => ‘recommended_goods’, ‘foreign_key’ => ‘goods_id’, ‘reverse’ => ‘recommend_goods’, ), ); var $_autov = array( ‘goods_name’ => array( ‘required’ => true, ‘filter’ => ‘trim’, ), ); } 這里貼出了實(shí)體goods模型類中的內(nèi)容,先是表格的屬性,再就是goods與其它實(shí)體之間的關(guān)聯(lián)關(guān)系的定義。然后我們再看看這個(gè)函數(shù),它是BaseModel構(gòu)造函數(shù)里調(diào)用的方法,對對象中的基礎(chǔ)變量進(jìn)行初使化:
function BaseModel($params, $db) { $this->db =& $db; !$this->alias && $this->alias = $this->table; $this->_prefix = DB_PREFIX; $this->table = $this->_prefix . $this->table; if (!emptyempty($params)) { foreach ($params as $key => $value) { $this->$key = $value; } } } 大家已經(jīng)看出$_relation 中間是此實(shí)體的關(guān)聯(lián)信息,然后在BaseModel類中的一個(gè)函數(shù):
function _getJoinString($relation_info) { switch ($relation_info['type']) { case HAS_ONE:// $model =& m($relation_info['model']); /* 聯(lián)合限制 */ $ext_limit = ”; $relation_info['ext_limit'] && $ext_limit = ‘ AND ‘ . $this->_getExtLimit($relation_info['ext_limit']); /* 獲取參考鍵,默認(rèn)是本表主鍵(直接擁有),否則為間接擁有 */ $refer_key = isset($relation_info['refer_key']) ? $relation_info['refer_key'] : $this->prikey; /* 本表參考鍵=外表外鍵 */ return ” LEFT JOIN {$model->table} {$model->alias} ON {$this->alias}.{$refer_key}={$model->alias}.{$relation_info['foreign_key']}{$ext_limit}”; break; case BELONGS_TO: /* 屬于關(guān)系與擁有是一個(gè)反向的關(guān)系 */ $model =& m($relation_info['model']); $be_related = $model->getRelation($relation_info['reverse']); if (emptyempty($be_related)) { /* 沒有找到反向關(guān)系 */ $this->_error(‘no_reverse_be_found’, $relation_info['model']); return ”; } $ext_limit = ”; !emptyempty($relation_info['ext_limit']) && $ext_limit = ‘ AND ‘ . $this->_getExtLimit($relation_info['ext_limit'], $this->alias); /* 獲取參考鍵,默認(rèn)是外表主鍵 */ $refer_key = isset($be_related['refer_key']) ? $be_related['refer_key'] :$model->prikey ; /* 本表外鍵=外表參考鍵 */ return ” LEFT JOIN {$model->table} {$model->alias} ON {$this->alias}.{$be_related['foreign_key']} = {$model->alias}.{$refer_key}{$ext_limit}”; break; case HAS_AND_BELONGS_TO_MANY: /* 連接中間表,本表主鍵=中間表外鍵 */ $malias = isset($relation_info['alias']) ? $relation_info['alias'] : $relation_info['middle_table']; $ext_limit = ”; $relation_info['ext_limit'] && $ext_limit = ‘ AND ‘ . $this->_getExtLimit($relation_info['ext_limit'], $malias); return ” LEFT JOIN {$this->_prefix}{$relation_info['middle_table']} {$malias} ON {$this->alias}.{$this->prikey} = {$malias}.{$relation_info['foreign_key']}{$ext_limit}”; break; } } /* 模型相關(guān)常量定義 */ define(‘HAS_ONE’, 1); //一對一關(guān)聯(lián) define(‘BELONGS_TO’, 2); //屬于關(guān)聯(lián) define(‘HAS_MANY’, 3); //一對多關(guān)聯(lián) define(‘HAS_AND_BELONGS_TO_MANY’, 4); //多對多關(guān)聯(lián) define(‘DROP_CONDITION_TRUNCATE’, ‘TRUNCATE’); //清空 從這個(gè)函數(shù)中,我們可以看到,對于不同的關(guān)聯(lián)關(guān)系,它會返回不同的關(guān)聯(lián)時(shí)的查詢語句片斷,然后連接上主sql語句,就可以針對實(shí)體的關(guān)聯(lián)實(shí)體進(jìn)行相應(yīng)的關(guān)聯(lián)操作了。
//物品表的操作: $model_goods = & m(‘goods’); $goods_info = $model_goods->find(array( ‘conditions’ => “if_show=1 and closed=0″, ‘fields’ => ‘goods_id,goods_name,s.store_id,s.store_name’, ‘join’ => ‘blongs_to_store’ )); 這里的’join’ => ‘blongs_to_store’ ,我們從上面的: // 一個(gè)商品只能屬于一個(gè)店鋪 ‘belongs_to_store’ => array( ‘model’ => ‘store’, ‘type’ => BELONGS_TO, ‘foreign_key’ => ‘store_id’, ‘reverse’ => ‘has_goods’, ), 這里我們可以知道這是在與store表進(jìn)行關(guān)聯(lián)查找了。ECmall二次開發(fā)
到這里,讀者就可以知道,如果在上面進(jìn)行二次開發(fā)的話,怎樣進(jìn)行數(shù)據(jù)庫操作就已經(jīng)很明確的了。
在BaseModel與cls_mysql(mysql.php)中,有很多的有關(guān)數(shù)據(jù)操作的函數(shù),這里就不需要再一一進(jìn)行解釋了,而在cls_mysql中,有一些更基礎(chǔ)的操作函數(shù),還有仿真 Adodb 的函數(shù),可以直接跳過BaseModel中的函數(shù)
以上介紹了如何在ecmall的平臺上進(jìn)行數(shù)據(jù)庫操作,如果操作更加的復(fù)雜,這里還有一種更加直接的方法:
$sql = “select g.goods_id,g.goods_name, from “.DB_PREFIX.”goods g, “.DB_PREFIX.”goods_spec gs , “.DB_PREFIX.”store s where cate_id='”.$cate_id.”‘ AND g.if_show = 1 AND g.closed = 0 and g.goods_id=gs.goods_id and g.store_id=s.store_id and gs.stock>0 and s.state=1 order by g.add_time desc limit 6″; $goods_mod =& m(‘goods’); $category_goods = $goods_mod->getAll($sql); if(!$category_goods){ $category_goods=array(); } return $category_goods; 就可以直接使用sql語句進(jìn)行數(shù)據(jù)操作了。
還可以在BaseModel中定義自己的操作方法,其中可以使用$this->db->(cls_mysql中定義的方法) 來調(diào)用cls_mysql中的函數(shù),從而可以添加更加復(fù)雜的數(shù)據(jù)操作函數(shù)。
轉(zhuǎn)載于:https://my.oschina.net/winnsay/blog/633499
總結(jié)
以上是生活随笔 為你收集整理的ECMALL数据库关系模型的实现 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。