对于数据库关系模型的分析,我觉得需要从两个函数说起:
//获取一个模型
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];
}
//获取一个业务模型
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];
}
所谓模型,则是一个一个的数据实体,换句话说就是一个数据表,你可以基于这个模
型,调用model.base.php中的数据库操作函数来对数据进行增、删、改、查的操作。
这里的业务模型,是在实体模型基础上,再继承一次,然后对一些方法进行重写。
系统中只有三个实体有业务模型:
推荐类型 recommend;商品数据模型 goods;商品分类业务模型 gcategory;
具体操作例子:
//物品表的操作:
$model_goods = & m('goods');
$goods_info = $model_goods->get($goods_id);
这里需要解释一下对于数据模型的操作是怎样的一个函数调用过程:
首先:$model_goods = &m('goods');
我们看一下&m()函数的代码,其中var_export()函数则是将传进来的实体,返回相应的实体类对象,因为所有的model都继承至model.base.php中的BaseModel类,这个类中定义了基本所有的操作函数,因此$model_goods对象可以对数据库进行相应的操作。
而我们再看看goods.model.php中的GoodsModel的代码:
class GoodsModel extends BaseModel
{
var $table = 'goods';
var $prikey = 'goods_id';
var $alias = 'g';//缩写
var $_name = 'goods';
var $temp; // 临时变量
var $_relation = array(
// 一个商品对应一条商品统计记录
'has_goodsstatistics' => array(
'model' => 'goodsstatistics',
'type' => HAS_ONE,
'foreign_key' => 'goods_id',
'dependent' => true
),
// 一个商品对应多个规格
'has_goodsspec' => array(
'model' => 'goodsspec',
'type' => HAS_MANY,
'foreign_key' => 'goods_id',
'dependent' => true
),
// 一个商品对应一个默认规格
'has_default_spec' => array(
'model' => 'goodsspec',
'type' => HAS_ONE,
'refer_key' => 'default_spec',
'foreign_key' => 'spec_id',
),
// 一个商品对应多个属性
'has_goodsattr' => array(
'model' => 'goodsattr',
'type' => HAS_MANY,
'foreign_key' => 'goods_id',
'dependent' => true
),
// 一个商品对应多个图片
'has_goodsimage' => array(
'model' => 'goodsimage',
'type' => HAS_MANY,
'foreign_key' => 'goods_id',
'dependent' => true
),
// 一个商品只能属于一个店铺
'belongs_to_store' => array(
'model' => 'store',
'type' => BELONGS_TO,
'foreign_key' => 'store_id',
'reverse' => 'has_goods',
),
// 商品和分类是多对多的关系
'belongs_to_gcategory' => array(
'model' => 'gcategory',
'type' => HAS_AND_BELONGS_TO_MANY,
'middle_table' => 'category_goods',
'foreign_key' => 'goods_id',
'reverse' => 'has_goods',
),
// 商品和会员是多对多的关系(会员收藏商品)
'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',
),
// 商品和推荐类型是多对多的关系 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',
),
);
}
这里贴出了实体goods模型类中的内容,先是表格的属性,再就是goods与其它实体之间的关联关系的定义。然后我们再看看这个函数,它是BaseModel构造函数里调用的方法,对对象中的基础变量进行初使化:
function BaseModel($params, $db)
{
$this->db =& $db;
!$this->alias && $this->alias = $this->table;
$this->_prefix = DB_PREFIX;
$this->table = $this->_prefix . $this->table;
if (!empty($params))
{
foreach ($params as $key => $value)
{
$this->$key = $value;
}
}
}
大家已经看出$_relation 中间是此实体的关联信息,然后在BaseModel类中的一个函数:
function _getJoinString($relation_info)
{
switch ($relation_info['type'])
{
case HAS_ONE://
$model =& m($relation_info['model']);
/* 联合限制 */
$ext_limit = '';
$relation_info['ext_limit'] && $ext_limit = ' AND ' . $this->_getExtLimit($relation_info['ext_limit']);
/* 获取参考键,默认是本表主键(直接拥有),否则为间接拥有 */
$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:
/* 属于关系与拥有是一个反向的关系 */
$model =& m($relation_info['model']);
$be_related = $model->getRelation($relation_info['reverse']);
if (empty($be_related))
{
/* 没有找到反向关系 */
$this->_error('no_reverse_be_found', $relation_info['model']);
return '';
}
$ext_limit = '';
!empty($relation_info['ext_limit']) && $ext_limit = ' AND ' . $this->_getExtLimit($relation_info['ext_limit'], $this->alias);
/* 获取参考键,默认是外表主键 */
$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;
}
}
/* 模型相关常量定义 */
define('HAS_ONE', 1); //一对一关联
define('BELONGS_TO', 2); //属于关联
define('HAS_MANY', 3); //一对多关联
define('HAS_AND_BELONGS_TO_MANY', 4); //多对多关联
define('DROP_CONDITION_TRUNCATE', 'TRUNCATE'); //清空
从这个函数中,我们可以看到,对于不同的关联关系,它会返回不同的关联时的查询语句片断,然后连接上主sql语句,就可以针对实体的关联实体进行相应的关联操作了。
具体操作例子:
//物品表的操作:
$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' ,我们从上面的:
// 一个商品只能属于一个店铺
'belongs_to_store' => array(
'model' => 'store',
'type' => BELONGS_TO,
'foreign_key' => 'store_id',
'reverse' => 'has_goods',
),
这里我们可以知道这是在与store表进行关联查找了。
到这里,读者就可以知道,如果在上面进行二次开发的话,怎样进行数据库操作就已经很明确的了。
在BaseModel与cls_mysql(mysql.php)中,有很多的有关数据操作的函数,这里就不需要再一一进行解释了,而在cls_mysql中,有一些更基础的操作函数,还有仿真 Adodb 的函数,可以直接跳过BaseModel中的函数
以上介绍了如何在ecmall的平台上进行数据库操作,如果操作更加的复杂,这里还有一种更加直接的方法:
$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语句进行数据操作了。
还可以在BaseModel中定义自己的操作方法,其中可以使用$this->db->(cls_mysql中定义的方法) 来调用cls_mysql中的函数,从而可以添加更加复杂的数据操作函数。
好了,数据操作分析就这些了,有不对之处,还请拍砖!
分享到:
相关推荐
《ECMall 2.3.0-0918-SCGBK 官方版:电商系统的里程碑》 ECMall 2.3.0-0918-SCGBK,这款电商软件曾是众多商家青睐的选择,尤其对于中文用户来说,其SCGBK编码版本更是满足了国内市场的特定需求。然而,随着时代的...
ECMall 2.3 的数据库设计注重数据的一致性和完整性,通过精心设计的表结构和关联关系,实现商品管理、订单处理、用户账户等核心功能。其中,商品信息表、订单表和用户表是系统的核心数据,它们之间的交互构建了整个...
2. **模板引擎**:ECMall支持模板机制,允许用户通过修改模板文件来定制网站的外观,无需深入代码,降低维护难度。 3. **多店铺支持**:ECMall的核心功能之一是支持多商家入驻,每个商家可以拥有独立的店铺界面,...
ECMall 2.3.0 正式版更新日志:程序包说明:upload 主程序integrate 整合程序initdata 测试数据安装程序upgrade 升级程序doc 相关文档1、新增 4套店铺风格2、优化 卖家可设置是否启用团购功能3、新增 商品雷达4、...
2. Flymak模板特点: - 界面设计:Flymak模板以简洁、现代的风格为主,注重用户体验,提供良好的视觉效果,有助于提升店铺形象和用户购物体验。 - 响应式布局:该模板支持响应式设计,能够自动适应不同设备的屏幕...
1. **安装说明.txt**:这是一个文本文件,通常包含了安装和配置模板的详细步骤,包括环境要求、数据库配置、文件上传路径等,对于首次使用Ecmall模板的用户来说非常重要。 2. **data**:这个目录可能包含了一些预设...
对于基于Ecmall框架的电商平台而言,深入理解并掌握其与MySQL数据库的交互机制,无疑是实现系统二次开发的关键所在。本文将详细阐述Ecmall中MySQL数据库调用的基础原理、核心函数及其应用场景,旨在为初学者及开发者...
ECMall是一款开源的电子商务平台,其数据库设计涵盖了多个核心模块,包括广告管理、管理员操作记录、用户管理、广告位管理、文章系统、文章分类、属性管理、拍卖活动记录、黑名单管理、品牌管理以及购物车功能。...
- ecmall230-0918-scutf8:这是一个可能的压缩包主文件名,表明这是ECMall 2.3.0版本的简体UTF-8语言包,时间戳0918可能代表发布日期,通常包含所有ECMall系统的源代码和相关资源文件。 3. 安装与部署: - 在下载...
ECMall是一个根据融合了电子商务以及网络社区特色的产品,它不仅能使您的电子商务进程变得异常轻松,同时通过和康盛创想相关产品的结合还能进一步提高用户的活跃度以及黏性,从而促进用户的忠诚度。 ECMall 2.3.0...
### ECmall源码简略分析:数据库关系模型的实现 ECmall是一款开源的电子商务系统,其源码的设计与实现蕴含了丰富的技术细节,尤其是数据库关系模型的构建方式,展现了其在处理复杂数据关联上的独到之处。本文将深入...
### Ecmall 2.X 架构分析与技术指南 #### 概述 Ecmall是一款基于PHP语言的开源电子商务平台,广泛应用于构建各种在线商店系统。为了更好地理解和利用Ecmall进行二次开发,本教程将详细介绍其核心架构、关键技术点...
在电子商务平台中,数据库设计是至关重要的,因为它存储了所有业务相关的数据。ECMall是一个开源的电子商务系统,其数据库设计包括多个核心表,用于管理商品、用户、订单、属性等关键信息。以下是对这些表的详细解释...
描述中提到的“解决了preg_replace_callback等问题”,意味着开发团队可能发现了Ecmall原有代码中使用`preg_replace_callback`时存在的问题,尤其是与安全相关的隐患,并进行了修正。这可能是通过使用其他函数,如`...
数据库关系模型的实现是ECMall的核心部分。ECMall基于Model-View-Controller(MVC)架构,模型层负责数据的处理和业务逻辑,通过ORM(Object-Relational Mapping)方式简化数据库操作。开发者在进行二次开发时,可以...
ecmall电子商城源代码兼容PHP5.3-PHP7.0,由于ecmall开源代码官网已经不更新升级了,PHP5.5以上就会报错,现在做了一个兼容源代码的调整,测试了PHP5.3.29,PHP5.6.27,PHP7.0.12这三个版本可以兼容,下载资源里面附加文档...
2. **MySQL数据库**:作为一款电子商务平台,ECMall会与数据库紧密交互,存储商品信息、订单数据、用户资料等。因此,熟悉MySQL数据库管理、SQL查询语言和事务处理至关重要。 3. **MVC模式**:ECMall采用MVC设计...
《ECMall2:深度解析电商系统架构与应用》 ECMall2是一款基于PHP语言开发的开源电子商务系统,专为中小企业打造,旨在提供全面、高效且易用的在线商城解决方案。这款系统的名称"ECMall2"意为"电子商务商场第二代",...
ECMall 2.0采用了Model-View-Controller(MVC)的设计模式,这种架构将应用程序分为三个主要部分:模型(Model)负责业务逻辑,视图(View)负责展示数据,控制器(Controller)协调模型和视图之间的交互,从而实现...