在seagull框架下操作数据库

在seagull框架下操作数据库

开发项目,和数据库打交道是重要的一个环节。在使用seagull框架开发时也不例外。对于初学seagull的人来说,肯定会比较关心在seagull框架下开发时是如何实现对数据库的操作?

一、前期设置(或者说是准备DSN -数据连接符或数据源)
事实上,在我们安装seagull框架的第四,五步中我们就是进行数据库相关的配置,包括DSN的各大要素:

1、数据库后台类型(phptype)
2、数据库服务器(名称或IP)
3、数据库用户名
4、数据库密码
5、数据库名
6、通信协议
7、通信端口

下面是相关截图:

虽然说在安装seagull时需要进行设置,不过在有需要的时候我们可以通过修改seagull的全局配置文件(var目录下[host].conf.php)的DB相关配置选项:

$conf[’db’][’type’] = ‘mysql_SGL’;
$conf[’db’][’host’] = ‘localhost’;
$conf[’db’][’protocol’] = ‘unix’;
$conf[’db’][’user’] = ‘george’;
$conf[’db’][’pass’] = ‘pto.george’;
$conf[’db’][’name’] = ‘XYZ’;
$conf[’db’][’socket’] = ‘’;
$conf[’db’][’port’] = ‘3306′;

$conf[’db’][’postConnect’] = ‘SET NAMES utf8′;
$conf[’db’][’mysqlDefaultStorageEngine’] = ‘0′;
$conf[’db’][’charset’] = ‘utf8′;
$conf[’db’][’collation’] = ‘utf8_unicode_ci’;
$conf[’db’][’sepTableForEachSequence’] = ‘0′;
$conf[’db’][’prefix’] = ‘’;

二、初始化数据库连接

做完了第一步我们已经是万事俱备,只欠东风了。按照平常的做法,我们需要先根据上一步提供的DSN资料初始化一个数据库连接?没错,但是这不需要我 们来做,像这样的日常任务已经由seagull代劳了,集中你的精力去处理核心的业务逻辑或美工之类的问题吧。seagull中的任何一个manager 都继承了SGL_Manager父类,并从父类继承了dbh属性 --指向一个PEAR::DB实例的指针或参考(DB对象实例中包含有已经初始化的数据库连接)。也就是说我们在manager内可以直接$this- dbh调用PEAR::DB的API接口轻松地进行数据库操作了,而不需要考虑诸如后台数据库类型,后期可能会碰到的移植,而且处理事务也是很方便的。

不过,如果我们不是在manager的范围内工作时是不是意味着我们就无法操作数据库了,我们岂不是要重新来过?虽然说在seagull下开发时很 少需要我们去考虑数据库初始化连接这类事情,但是确实有些情况下我们不是在manager的范围内工作,比如你的项目需要一个定期执行的任务,这个时候你 可能想使用cronjob来实现来执行一个轻量php脚本,而不是模块内的manager,你可以通过下列代码来实现对数据的操作:

$locator = &SGL_ServiceLocator::singleton();
$dbh = $locator->get(’DB’);
if (!$dbh) {
$dbh = & SGL_DB::singleton();
$locator->register(’DB’, $dbh);
}


三、如何实现跨数据库操作

虽然说跨数据库操作比较少见,但是难免我们有这种需要。不用担心,比起我们平常使用PHP直接开发,在seagull下实现跨数据库操作是容易的。 当你需要访问当前数据库以外的数据库时,你只需要指定好DSN,然后调用seagull对pear::db的封装类的singleton访求即可:

$dsn = ‘pgsql://someuser:apasswd@localhost/thedb’;
$dbh = & SGL_DB::singleton($dsn);

这个时候你就可以对thedb进行操作,需要注意是:
1,通常情况下我们只会使用db来操作数据库,如果要有ORM(dataobject)则需要注意你是否有生成相应表格的dataobject类
2,数据库操作完毕应该注意释放$dbh

 

四、如何实现查询结果集的分页
在seagull框架下,我们可以很容易的实现地查询结果集的分页,而不用从头去写一个方法,因为seagull的pear::db封装类SGL_DB提供了一个获取分页后数据集的方法:

function getPagedData(&$db, $query, $pager_options = array(), $disabled = false,
$fetchMode = DB_FETCHMODE_ASSOC, $dbparams = array())

例子:UserMgr的viewLogin action

    function _cmd_viewLogin(&$input, &$output)
    {
        SGL::logMessage(null, PEAR_LOG_DEBUG);

        $output->template = 'userManagerLogins.html';
        $output->pageTitle = $this->pageTitle . ' :: Login Data';

        $allowedSortFields = array('date_time','remote_ip');
        if (  !empty($input->sortBy)
           && !empty($input->sortOrder)
           && in_array($input->sortBy, $allowedSortFields)) {
                $orderBy_query = ' ORDER BY ' . $input->sortBy . ' ' . $input->sortOrder ;
        } else {
            $orderBy_query = ' ORDER BY date_time DESC ';
        }
        if (!empty($input->userID) ) {
            $query = "
                SELECT  date_time, remote_ip, login_id
                FROM    {$this->conf['table']['login']}
                WHERE   usr_id = $input->userID" .
                $orderBy_query;
        } else {
            SGL::raiseError('Incorrect parameter passed to ' .
                __CLASS__ . '::' . __FUNCTION__, SGL_ERROR_INVALIDARGS);
            return false;
        }

        $limit = $_SESSION['aPrefs']['resPerPage'];
        $pagerOptions = array(
            'mode'     => 'Sliding',
            'delta'    => 3,
            'perPage'  => $limit,
            'spacesBeforeSeparator' => 0,
            'spacesAfterSeparator'  => 0,
            'curPageSpanPre'        => '<span class="currentPage">',
            'curPageSpanPost'       => '</span>',
        );
        $aPagedData = SGL_DB::getPagedData($this->dbh, $query, $pagerOptions);

        $output->aPagedData = $aPagedData;
        if (is_array($aPagedData['data']) && count($aPagedData['data'])) {
            $output->pager = ($aPagedData['totalItems'] <= $limit) ? false : true;
        }
        $output->addOnLoadEvent("switchRowColorOnHover()");
    }

五、如何实现事务

事务的应用在项目开发设计中是必不可少的部分。seagull框架下应当如何实现呢?不用担心,借助PEAR::DB丰富的API,实现事务也是非常轻松的。

范例:用户模块的UserDAO.php中的addUser方法:

function addUser($oUser)
{
SGL_DB::setConnection();
$this->dbh->autocommit(false);

$userId = $this->dbh->nextId($this->conf[’table’][’user’]);
$oUser->usr_id = $userId;
$ok = $oUser->insert();

if (!$ok) {
$this->dbh->rollback();
$this->dbh->autocommit(true);
return PEAR::raiseError(’Problem inserting user DataObject’);
}
// assign permissions associated with role user belongs to
// first get all perms associated with user’s role
$aRolePerms = $this->getPermsByRoleId($oUser->role_id);
if (PEAR::isError($aRolePerms)) {
$this->dbh->rollback();
$this->dbh->autocommit(true);
return $aRolePerms;
}

// then assign them to the user_permission table
$ok = $this->addPermsByUserId($aRolePerms, $oUser->usr_id);
if (PEAR::isError($ok)) {
$this->dbh->rollback();
$this->dbh->autocommit(true);
return $ok;
}
// assign preferences associated with org user belongs to
// first get all prefs associated with user’s org or default
// prefs if orgs are disabled
if (!empty($this->conf[’OrgMgr’][’enabled’])) {
$aPrefs = $this->getUserPrefsByOrgId($oUser->organisation_id, SGL_RET_ID_VALUE);
} else {
$aPrefs = $this->getMasterPrefs(SGL_RET_ID_VALUE);
}
if (PEAR::isError($aPrefs)) {
$this->dbh->rollback();
$this->dbh->autocommit(true);
return $aPrefs;
}

// then assign them to the user_preference table
$ok = $this->addPrefsByUserId($aPrefs, $oUser->usr_id);
if (PEAR::isError($ok)) {
$this->dbh->rollback();
$this->dbh->autocommit(true);
return $ok;
}

if ($ok && !SGL_Error::count()) {
$this->dbh->commit();
$this->dbh->autocommit(true);
return $userId;
} else {
$this->dbh->rollback();
$this->dbh->autocommit(true);
return SGL_Error::getLast();
}
}

六、seagull数据库开发的规范

与其说是seagull框架下数据库开发的规范,倒不如说是一种习惯。因为规范有点强迫让人遵守的意思。而事实并不是这样的。这边要提到的规范是 seagull认为在manager的各个action内不应当直接去操作数据库,而且应该交给DAO去处理。seagull认为在controller 和db之间应该有一个数据处理层(data access layer),数据库操作应当通过DAO进行,这样呢,对于controller而言,它只需关心dao提供什么样的API,而不去考虑这些API背后是 如何实现的,也就是说API对controller而言是透明的。这样即使数据库发生变化时我们只需要修改DAO,而controller却并不得知。我 们说这是一个习惯而不是规范是因为seagull并不强迫你必须这么做,你直接在manager内进行DB操作也是可以的。而且在数据库或业务逻辑比较简 单时我们也赞成这么做。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值