
meta_register 用于存储扩展字段的一些信息 meta_value_datetime meta_value_decimal meta_value_int meta_value_longtext meta_value_text meta_value_varchar 用于存放数据,不同的数据类型存放在不同的表中 recycle
什么是meta扩展?
在不改动原表的情况下,增加扩展表字段。在二次开发中不推荐直接修改dbschema文件,那么在不修改原来dbschema(表)的情况下, 推荐使用meta扩展来增加要修改表的字段
怎么使用meta扩展?
<?php
...
function __construct($app){
parent::__construct($app);
//使用meta系统进行存储
$this->use_meta();
}
...
注册字段一般会在进行安装app的时候进行注册,所以一般注册字段方法会放在task.php文件中 还有一种是放在model中,先判断表中是否有需要注册的字段,如果没有则进行注册.
在需要注册的表对应的model中加入如下方法
<?php
...
//方法名自定义
//在注册的时候对此方法进行调用,则对表添加了一个新的字段
public function mytest(){
//和dbschema里的*列定义*一样, 但是没有pkey,extra,title定义
$column = array(
'qq'=>array (
'type' => 'number',
'required' => false,
'label' => __(' 短值测试列'),
'width' => 110,
'editable' => false,
),
);
return $this->meta_register($column);//注意:这只可以注册一个字段,如果要一次注册多个字段则可以循环
}
...
<?php
...
//会在安装app的时候调用,进行注册
function post_install($options){
$obj = app::get('b2c')->model('member');
$col = array(
'qq'=>array (
'type' => 'number',
'required' => false,
'label' => __(' 短值测试列'),
'width' => 110,
'editable' => false,
),
);
$obj->meta_register($col);
}
...
注册字段成功后我们会发现在sdb_dbeav_meta_register表中会有一条这样的记录
meta扩展前
<?php
...
$arr = $this->app->model('member')->getList('*');
echo '<pre>';
print_r($arr);
...

meta扩展后
function save() {
$filter = array(
'member_user' => 'XXXX',
'member_password' => md5('shopex'),
'member_email'=>'XXXX@qq.com',
'member_time'=>time(),
'qq'=>1111111,
);
$this->app->model('member')->save($filter);//保存数据
//保存后查询
$arr = $this->app->model('member')->getList('*');
echo '<pre>';
print_r($arr);
}

此记录在数据表中的表现方式是:

在ECOS中对数据表进行多表操作,推荐使用dbeav中的内置的方法(save,dump,delete)进行多表操作
如果要使用dbeav中的多表操作方法进行多表操作则需要进行如下配置
对表进行关联在ECOS中有两种方法,一种是直接在dbschema中进行定义,另外一种是用has_many,has_one进行关联
<?php
...
#这是goods表中的一个字段
#这个表示的是goods表中的type_id关联到goods_type表中的type_id
...
'type_id' =>
array (
'type' => 'table:goods_type', //关联goods_type表
'sdfpath' => 'type/type_id', //关联goods_type表中的type_id字段
'label' => app::get('b2c')->_('类型'),
'width' => 75,
'editable' => false,
'filtertype' => 'yes',
'in_list' => true,
'default_in_list' => true,
),
...
has_many,has_one 用法类似,都是标明表的关系 has_many 标明表的对外一对多 has_one 标明表对外为一对一
语法
var $has_many = array(
'sdfkey'=>'表名(@app名):操作:字段关联',
....
);
| 名称 | 说明 | 默认值 | 必须 |
| sdfkey | 对应关系在sdf树中的挂载点名 | 无 | √ |
| 表名 | 对应的表名 | 无 | √ |
| 操作 | save的操作方式( append:只对导入数据做save保存不对数据库原有数据做操作;replace:先删除数据库原有所有相关数据 再对导入数据做save;contrast:和数据数原有数据做比对 导入数据原有数据存在库中做update 不存在insert 数据库存在未导入数据delete) | append | |
| 字段关联 | 本表字段^关联表字段 2表之间 | 本表主键 与 对应表dbschema中"type=>table:本表名"字段 不能关联用此方法标识对应关系 |
<?php
class b2c_mdl_goods extends dbeav_model{
var $has_many = array(
'product' => 'products:contrast',
'rate' => 'goods_rate:replace:goods_id^goods_1',
'keywords'=>'goods_keywords:replace',
'images' => 'image_attach@image:contrast:goods_id^target_id',
'tag'=>'tag_rel@desktop:replace:goods_id^rel_id',
);
var $has_one = array(
);
为什么要配置subSdf?
一个主表可以关联多个子表,但是有些操作则只需要对一个主表和其中关联的一个子表进行操作。那么则需要定义subSdf来进行过滤
var $subSdf = array(
'key'=>array('field' subsdf),
':Foreign key'=>array(
'field',subsdf
),
)
| 名称 | 说明 |
| key | has_many/has_one定义键值 支持xpath语法 |
| field | 子表所需输出字段 |
| Foreign key | dbschema定义的外键表名 :前有string可以自定义外联表数据在sdf树中的键名 |
| subsdf | 子表subsdf |
标准sdf结构的subsdf定义在model中
例:model/goods.php
var $subSdf = array(
'default' => subsdf ......
);
default 为默认,可以自定义别的写法 basic,simple等等等
如果 $subSdf 未定义则为$has_many,$has_one的集合
例:
<?php
class b2c_mdl_goods extends dbeav_model{
var $has_many = array(
'product' => 'products:contrast',
'rate' => 'goods_rate:replace:goods_id^goods_1',
'keywords'=>'goods_keywords:replace',
'images' => 'image_attach@image:contrast:goods_id^target_id',
'tag'=>'tag_rel@desktop:replace:goods_id^rel_id',
);
var $subSdf = array(
'default' => array(
'keywords'=>array('*'),
//第二个参数是has_many定义的proudct所对应的products中关联表的subSdf
'product'=>array('*',array('price/member_lv_price'=>array('*'))),
':goods_type'=>array('*'),
':goods_cat'=>array('*'),
/*'tag'=>array('*',array(':tag'=>array('*'))),*/
'images'=>array('*',array(':image'=>array('*')))
),
'delete' => array(
'keywords'=>array('*'),
'product'=>array('*',array('price/member_lv_price'=>array('*'))),
'images'=>array('*')
)
);
使用方法:$goods = $oGoods->dump($goods_id,'*','default');
在_filter是对base_db_model中filter的扩展
扩展的数组
$FilterArray= array(
'than'=>' > '.$var,
'lthan'=>' < '.$var,
'nequal'=>' = \''.$var.'\'',
'noequal'=>' <> \''.$var.'\'',
'tequal'=>' = \''.$var.'\'',
'sthan'=>' <= '.$var,
'bthan'=>' >= '.$var,
'has'=>' like \'%'.$var.'%\'',
'head'=>' like \''.$var.'%\'',
'foot'=>' like \'%'.$var.'\'',
'nohas'=>' not like \'%'.$var.'%\'',
'between'=>' {field}>='.$var[0].' and '.' {field}<'.$var[1],
'in' =>" in ('".implode("','",(array)$var)."') ",
'notin' =>" not in ('".implode("','",(array)$var)."') ",
);
代码:
$filter = array(
'id|than'=>1,//这个表示 id>1
'filter_sql'=>' `name`= wuwei or sex=male', //filter_sql 可以自己写sql语句
);
统计满足条件的记录条数
function count(){
$filter = array(
'member_user'=>'XXXX'
);
$this->app->model('member')->count($filter);
}
用法和传递的参数和base_db_model中的getList 一样
如果用到 了meta扩展则需要调用dbeav中的getList.
加了一层判断,如果在做插入的时候,有用到过 meta 扩展则要做是否注册此扩展字段
insert用法参照: insert
使用dbeav中的dump进行多表查询,则需要(先进行多表关联)配置$has_many,$_has_one,subSdf
function dump($filter,$field = '*',$subSdf = null)
$subSdf 中是在 var $subSdf 中定义的节点,如果没定义,则是$has_many,$has_one的集合
例:
<?php
class notebook_mdl_members extends dbeav_model{
var $has_many = array(
'member_lv'=>'member_lv:append:member_lv_id^member_lv_id', //这表示在member表中有关联了三个表
'pam_account'=>'pam_account@pam:append:member_id^account_id',
'item'=>item:append:member_id^member_id,
);
var $subSdf = array(
'default' => array(
/*第一个参数则是members中所要查询的字段
*第二个参数表示是members表中的子表item的$subSdf,如果在item中没有关联的子表则以 null 代替
*array( 0,2,'item_id DESC' )此参数表示在item子节点中:从0到2取三条记录,按照 item_id DESC 排序
*/
'item' => array('*',null,array( 0,2,'item_id DESC' )),
),
'delete'=>array('*'),
);
function __construct($app){
parent::__construct($app);
//使用meta系统进行存储
$this->use_meta();
}
function item_dump(){
$filter = array(
'member_id'=>10,
);
$aDate = $this->dump($filter,"*",'default');//dump1 输出的是$subSdf 中的item中定义的节点
echo "<pre>";
print_r($aDate);
}
}
Array
(
[member_id] => 10
[member_user] => XXXX
[member_password] => 1e236443e5a30b09910e0d48c994b8e6
[member_time] => 1305280926
[member_email] => XXXX@qq.com
[qq] => 1111111
[item] => Array
(
[3] => Array //注意这里 $subSdf 里面定义的排序
(
[item_id] => 3
[member_id] => 10
[item_subject] => fsdafsd
)
[1] => Array
(
[test1_id] => 1
[member_id] => 10
[item_subject] =>测试测试
)
)
)
注意:用dump进行多表连查则第三个参数是必须,否则查不出数据
使用delete进行多表删除,需要先进行多表关联(配置好has_many,has_one, subSdf)
function delete($filter,$subSdf = 'delete')
接着上面member的model,添加下面的方法
<?php
...
function member_delect(){
$filter = array(
'member_id'=>10,
);
$this->delete($filter,'delete');//会删除在$subSdf 中定义的节点
}
...
的记录全部删除了,但是表pam_account,中的account_id=10,的数据还没有删除,
因为在执行delete 的时候,节点删除是根据$subSdf中来删除的
注意:$this->delete($filter);如果没有定义删除节点,默认会把所有关联的子表的相关信息删除
用法和传递的参数和base_db_model中的update 一样
如果用到 了meta扩展则需要调用dbeav中的update.
如果需要用save做多表保存或则更新数据需要先进行上面的多表关联操作(配置好has_many,has_one, subSdf)function save(&$data,$mustUpdate = null)
| 名称 | 说明 | 结构 | 引用 | 必要 |
| $data | 需保存数据的 | sdf | √ | √ |
| $mustUpdate | 必须保存的结构说明 | sdf |
将单条sdf数据通过has_many,has_one配置递归save入数据库,联合主键表不支持递归save,返回bool,主键返回$data
例:刚才删除的时候把表item,member_id = 10,和 表 member,member_id=10中的数据都删除了,现在在保存;
<?php
...
function member_save() {
$filter = Array(
'member_id' => 10,
'member_user' =>'wuwei',
'member_password' => '1234656',
'member_time' => 1305280926,
'member_email' => 'wuweishopex.cn',
'qq' => 123456789,
'item' => Array
(
'1' => Array //注意这里$subSdf里面定义的排序
(
'item_id' => 1,
'item_subject' => 'jjjjjdsgfdgfd',
),
'3' => Array
(
'item_id' => 3,
'item_subject' => 'fsadfsdfsdfa',
),
)
);
$this->app->model('member')->save($filter);
}
如果需要用batch_dump做多表保存或则更新数据需要先进行上面的多表关联操作(配置好has_many,has_one, subSdf)
function batch_dump($filter,$field = '*',$subSdf = null,$start=0,$limit=20,$orderType = null )
根据$filter条件,getList出多个主键Id
在根据 主键Id dump出多条 subSdf