dbeav 使用手册

dbeav简介

  • 对数据库进行meta扩展
  • 对数据进行多表操作

dbeav中的dbschema(表)介绍


meta_register 用于存储扩展字段的一些信息

meta_value_datetime
meta_value_decimal
meta_value_int
meta_value_longtext
meta_value_text
meta_value_varchar
用于存放数据,不同的数据类型存放在不同的表中

recycle

meta扩展

什么是meta扩展?

在不改动原表的情况下,增加扩展表字段。在二次开发中不推荐直接修改dbschema文件,那么在不修改原来dbschema(表)的情况下,
推荐使用meta扩展来增加要修改表的字段

怎么使用meta扩展?

  • 在对需要扩展字段的表的model中添加下面的构造方法,此model需要继承dbeav_model
    <?php
    ...
    function 
    __construct($app){
        
    parent::__construct($app);
        
    //使用meta系统进行存储
        
    $this->use_meta();
    }
    ...
  • 进行扩展字段注册
    注册字段一般会在进行安装app的时候进行注册,所以一般注册字段方法会放在task.php文件中
    还有一种是放在model中,先判断表中是否有需要注册的字段,如果没有则进行注册.
    
  1. model中注册一般是在调用这字段的时候需要判断是否注册了,如果没注册则需要调用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);//注意:这只可以注册一个字段,如果要一次注册多个字段则可以循环
    }
    ...
  2. task.php 中注册(推荐使用此方法)
    <?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扩展效果

meta扩展前
  1. 先来看原表的表结构


  2. 查询表中数据:
    <?php
    ...
     
    $arr $this->app->model('member')->getList('*');
     echo 
    '<pre>';
     
    print_r($arr);
    ...
  3. 得到的数据:
meta扩展后
  1. 在扩展后中插入一条数据
    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);
    }
    
  2. 查询到的数据是


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


使用dbeav进行多表操作

在ECOS中对数据表进行多表操作,推荐使用dbeav中的内置的方法(save,dump,delete)进行多表操作

如果要使用dbeav中的多表操作方法进行多表操作则需要进行如下配置

    • 对表进行关联
    • 配置subSdf
    • 使用对应的方法进行多表操作

对表进行关联

对表进行关联在ECOS中有两种方法,一种是直接在dbschema中进行定义,另外一种是用has_many,has_one进行关联

  • dbschema中对表进行关联
    <?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 用法类似,都是标明表的关系
    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?

一个主表可以关联多个子表,但是有些操作则只需要对一个主表和其中关联的一个子表进行操作。那么则需要定义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
  • 在哪定义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');
    

dbeav中函数接口

_filter

在_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语句
);

count

统计满足条件的记录条数

function count(){
	$filter = array(
		'member_user'=>'XXXX'
	);

	$this->app->model('member')->count($filter);
}

getList

用法和传递的参数和base_db_model中的getList 一样

如果用到 了meta扩展则需要调用dbeav中的getList.

insert

加了一层判断,如果在做插入的时候,有用到过 meta 扩展则要做是否注册此扩展字段

insert用法参照: insert

dump

使用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

使用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 中定义的节点
}
...
得到的数据为空,因为在member表中把member_id = 10 的这条记录给删除了!但是在数据库中可以看到表item把member_id=10

的记录全部删除了,但是表pam_account,中的account_id=10,的数据还没有删除,

因为在执行delete 的时候,节点删除是根据$subSdf中来删除的

注意:$this->delete($filter);如果没有定义删除节点,默认会把所有关联的子表的相关信息删除

update

用法和传递的参数和base_db_model中的update 一样

如果用到 了meta扩展则需要调用dbeav中的update.

save

如果需要用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

如果需要用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