You are here

4 创建自己的数据库表结构

admin 的头像
Submitted by admin on 星期五, 2015-05-29 02:02

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

模块中存储所用数据的常用方式,就是为这些数据创建一个单独的数据库表。当我们决定为模块创建数据库表结构时,应该问问自己:我们需要存储哪些数据?如果我们要对这个表进行查询,那么会用到哪些字段和索引?最后,还要考虑一下,将来对这个模块,有没有可能会作些扩展?

 

    首先让我们分析一下需要存储的数据。除了上面新增表单元素里面的信息外,我们还需要保存区块的ID信息,这样我们才能知道这个更多链接信息是属于哪个区块的。使用一个mysql的管理工具,比如phpmyadmin,我们打开Drupal的数据库结构,我们发现,在Drupal中,区块的ID是由模块名和delta值共同组成的。这样对于一个区块,我们需要保存4个值,分别为moduledeltaurltitle。另外我们需要为我们的数据库表起个名字,为了简单起见,就叫做block_morelink,和我们的模块名保持一致。

 

    我们表的SQL语句如下所示:

 

CREATE TABLE block_morelink (

  module varchar(64) NOT NULL,

  delta varchar(32) NOT NULL,

  url varchar(255) NOT NULL,

  title varchar(255) NOT NULL,

  PRIMARY KEY (module,delta,url,title),

)

我们可以把这段sql语句放到我们模块的README.txt文件中,这样我们就省事了。但是对于想要安装这个模块的其他用户来说,他们需要手工的使用上述SQL语句来创建数据库表,这样做会比较麻烦。实际上,在Drupal中,有更好的解决方式,我们知道,在启用核心模块时,Drupal能自动的创建相应的数据库表;我们可以使用Drupal的这一特性。我们在前面创建的install文件中,添加以下代码

 

/**

 * Implements hook_schema().

 */

function block_morelink_schema() {

  $schema['block_morelink'] = array(

    'description' => 'Stores more link path.',

    'fields' => array(

      'module' => array(

        'type' => 'varchar',

        'length' => 64,

        'not null' => TRUE,

        'description' => "The block's origin module, from {block}.module.",

      ),

      'delta' => array(

        'type' => 'varchar',

        'length' => 32,

        'not null' => TRUE,

        'description' => "The block's unique delta within module, from {block}.delta.",

      ),

      'url' => array(

        'type' => 'varchar',

        'length' => 255,

        'not null' => TRUE,

        'description' => "The more link url of a block.",

      ),

      'title' => array(

        'type' => 'varchar',

        'length' => 255,

        'not null' => TRUE,

        'description' => "The more link title of a block.",

      ),

    ),

    'primary key' => array('module', 'delta', 'url', 'title'),

    'indexes' => array(

      'url' => array('url'),

    ),

  );

  return $schema;

}

 

在第一次启用block_morelink模块时,drupal会检查block_morelink.install文件,看里面是否实现了hook_schema钩子,它将读取hook_schema中所定义的数据库表结构模式,并将它们转化为了当前数据库的标准SQL语句。有关这方面的更多信息,可参看Schema API一章。如果一切顺利的话,这样就完成了数据库表的创建工作。让我们试验一下。由于我们在前面还没有创建数据库表的时候,就启用了该模块,所以我们需要重新安装一下这个模块,需要按照以下步骤进行重装:

 

1导航到“管理 > 模块”,先将block_morelink模块禁用。

2在管理界面“管理 模块”,找到卸载标签,点击这个标签,选择block_morelink模块,卸载。这样Drupal就会删除与这个模块有关的数据库表。

3启用这个模块。这次,在模块启用时,Drupal会创建相关的数据库表。

 

 

    当Drupal创建了用来存储数据的block_morelink表以后,现在让我们添加与数据处理相关的代码。首先,我们需要在提交处理函数中添加一些逻辑代码,这样在用户修改了区块配置信息后,它可以用来处理与更多链接相关的数据。我们的表单提交函数如下所示:

 

function block_morelink_block_admin_configure_submit($form, &$form_state){

  db_delete('block_morelink')

    ->condition('module', $form_state['values']['module'])

    ->condition('delta', $form_state['values']['delta'])

    ->execute();

    

  if(!empty($form_state['values']['morelink_url'])){

  $query = db_insert('block_morelink')->fields(array('url', 'title', 'module', 'delta'));

 $query->values(array(

    'url' => $form_state['values']['morelink_url'],

    'title' => $form_state['values']['morelink_title'],

    'module' => $form_state['values']['module'],

    'delta' => $form_state['values']['delta'],

  ));

  $query->execute();

  }

  

}

由于我们在一个区块上只允许有一个更多链接,所以我们可以先删除以前的信息,然后把最新的信息插入到数据库中。对于我们与数据库之间的交互,首先需要注意的是,我们不需要考虑数据库连接,这是因为Drupal在它的引导指令中已经完成了这一工作。其次,对于上述代码,我们目前只需要了解它做了哪些操作就可以了:首先是删除与该区块相关的更多链接信息,接着做了一个判断,如果输入的更多链接路径不为空,此时我们将更多链接有关信息插入到block_morelink表中。这里面我们使用了db_delete、db_insert两个数据库操作函数,分别用来负责删除与插入操作。

 

   最后,我们需要修改block_morelink_form_block_admin_configure_alter中代码,这样,如果已经存在了一个更多链接,那么将把它从数据库中读取出来,并用来将其作为默认值传递给我们的表单元素。我们将原有的代码:

 

  $default_morelink_url = '';

  $default_morelink_title = '';

 

   替换为

 

  $result = db_query("SELECT url, title FROM {block_morelink} WHERE module = :module AND delta = :delta", array(

    ':module' => $form['module']['#value'],

    ':delta' => $form['delta']['#value'],

  ))->fetch();

  $default_morelink_url = empty($result)?'':$result->url;

  $default_morelink_title = empty($result)?'':$result->title;

 

    这里我们使用了db_query函数从数据库中取出更多链接的url、title,并将其设置为现有表单元素的默认值。对于db_query中的sql,这里需要注意两点:首先,在我们用到一个数据库表时,我们需要把它放到花括号{}里;这样可以方便的实现在数据库表名的前面添加前缀(关于表名前缀的更多信息,可参看文件sites/default/settings.php中的注释)。其次,我们在查询语句中使用了占位符“:module”和“:delta”,并为其提供了相应的变量,这样Drupal内置的安全机制就可以帮助我们阻止SQL注入。

 


Drupal版本: