資料|資料庫
二、抽象資料庫介面(利用資料操作管理類)
在用mvc模式開發的時候,model層負責資料庫的所有操作,為了對資料庫的操作進行統一的管理,我們需要定義一個資料庫操作管理類,由他來接替所有的資料庫操作,也就是整個系統中只有這個資料庫操作管理類,可以直接對資料庫進行操作,如果其他的類需要對資料庫進行操作,那它就必須調用和通過這個類來實現。
下面的Db類就是一個這樣的類。
<?php
/**************************************************************
* descript : mysql資料庫操作管理類
*
* author : 大齡青年
* Email :wenadmin@sina.com
* qq : 303015292
* msn : wenguangqing@hotmail.com
*************************************************************/
/*
* example 1: 擷取序列
* <?
* $db = new Db();
* $result = $db->getSeq('art_id', 2, 1);
* ?>
*/
/*
* example 2: 分頁查詢
* <?
* $db = new Db();
* $result = $db->&queryPage('select id,name from table', 2, 10, DB_FETCH_ASSOC);
* foreach($result as $row)
* echo $row['id'],'------'.$row['name'].'<br>';
* ?>
*/
/*
* example 3: 插入資料
* <?
* $db = new Db();
* $result = $db->execute("insert into table (id, name) values(1,'name')");
* if($result>0) echo '插入資料成功';
* else echo '插入資料失敗';
* ?>
*/
/*
* 定義資料庫聯結選項
* @var DB_HOST string 資料庫主機名稱或地址
* @var DB_NAME string 資料庫名稱
* @var DB_USER string 資料庫使用者名稱稱
* @var DB_PWD string 資料庫使用者的密碼
* @var DB_PCONNECT boolean 是否建立持久串連
*/
define('DB_HOST', 'localhost');
define('DB_NAME', 'test');
define('DB_USER', 'root');
define('DB_PWD', '');
define('DB_PCONNECT', true);
/*
*定義返回資料查詢結果的類型
* @var DB_FETCH_ASSOC int 結果調用方式:$result['name']
* @var DB_FETCH_NUM int 結果調用方式:$result[0]
* @var DB_FETCH_BOTH int 結果調用方式:$result['name'] 或 $result[0]
* @var DB_FETCH_OBJECT int 結果調用方式:$result->name
*/
define('DB_FETCH_ASSOC', 0);
define('DB_FETCH_NUM', 1);
define('DB_FETCH_BOTH', 2);
define('DB_FETCH_OBJECT', 3);
/*
*定義預設序列發生器的名稱
*/
define('DB_SEQUENCE_TABLENAME', 'sequences');
class Db{
/*
* 當前資料庫聯結選項
*/
var $dbHost = DB_HOST;
var $dbName = DB_NAME;
var $dbType = 'Mysql';
var $dbUser = DB_USER;
var $dbPwd = DB_PWD;
var $pcnn = DB_PCONNECT;
/*
* 當前資料庫連接
*/
var $cnn = '';
/*
* 資料查詢結果的傳回型別
*/
var $queryFetchType = DB_FETCH_ASSOC;
/*
* 初始化函數
*/
function Db(){
$this->cnn = ($this->pcnn? mysql_connect($this->dbHost, $this->dbUser, $this->dbPwd):
mysql_connect($this->dbHost, $this->dbUser, $this->dbPwd)) or
$this->_halt('資料庫連接錯誤');
mysql_select_db($this->dbName, $this->cnn) or $this->_halt('資料庫選擇錯誤');
}
/*
* 資料查詢函數
*
* @param $sql string 資料查詢語句
* @param $fetchType int 資料查詢結果的傳回型別
*
* @return array 資料查詢結果
*/
function &query($sql, $fetchType=DB_FETCH_ASSOC){
$data = array();
$rs = &mysql_query($sql, $this->cnn) or $this->_halt('資料查詢錯誤', $sql);
$exe = $this->_getCommand($fetchType);
while($row=&$exe($rs))
$data[] = &$row;
return $data;
}
/*
* 分頁資料查詢函數
*
* @param $sql string 資料查詢語句
* @param $page int 當前預查詢頁碼
* @param $pageSize int 每頁顯示多少條紀錄
* @param $fetchType int 資料查詢結果的傳回型別
*
* 資料查詢結果,以及資料的分頁資訊
* @return array('pageSize' => 每頁顯示的條數
* 'recordCount' => 總紀錄數
* 'pageCount' => 總頁數
* 'page' => 當前頁碼
* 'isFirst' => 是否第一頁
* 'isLast' => 是否最後一頁
* 'start' => 返回結果的第一條紀錄的序號
* 'sql' => 查詢的sql語句
* 'data' => 查詢得到的資料結果
* )
* 資料查詢結果,以及資料的分頁資訊
*/
function &queryPage($sql, $page=1, $pageSize=20, $fetchType=DB_FETCH_ASSOC){
$countSql = preg_replace('|SELECT.*FROM|i','SELECT COUNT(*) count FROM', $sql);
$data['pageSize'] = (int)$pageSize<1? 20: (int)$pageSize;
$data['recordCount'] = $this->getOne($countSql, 'count');
$data['pageCount'] = ceil($data['recordCount']/$data['pageSize']);
$data['page'] = $data['pageCount']==0? 0: ((int)$page<1? 1: (int)$page);
$data['page'] = $data['page']>$data['pageCount']? $data['pageCount']:$data['page'];
$data['isFirst'] = $data['page']>1? false: true;
$data['isLast'] = $data['page']<$data['pageCount']? false: true;
$data['start'] = ($data['page']==0)? 1: ($data['page']-1)*$data['pageSize']+1;
$data['sql'] = $sql.' LIMIT '.($data['start']-1).','.$data['pageSize'];
$data['data'] = &$this->query($data['sql'], $fetchType);
return $data;
}
/*
* 進行資料查詢只返回第 1 行的資料
*
* @param $sql string 資料查詢語句
* @param $fetchType int 資料查詢結果的傳回型別
*
* @return array 資料查詢結果
*/
function &queryRow($sql, $fetchType=DB_FETCH_ASSOC){
$rs = &mysql_query($sql, $this->cnn) or $this->_halt('單行資料查詢錯誤', $sql);
$exe = $this->_getCommand($fetchType);
return $exe($rs);
}
/*
* 進行資料查詢只返回第 1 行第 n 列的資料
*
* @param $sql string 資料查詢語句
* @param $field int 返回資料列的名稱 或 數字序號
*
* @return string 返回單個欄位的值
*/
function &getOne($sql, $field = 0){
$rs = &mysql_query($sql, $this->cnn) or $this->_halt('單個資料查詢錯誤', $sql);
$row = mysql_fetch_array($rs);
return $row[$field];
}
/*
* 進行sql語句,包含 DELECT / INSERT / UPDATE.....的執行語句
*
* @param $sql string 資料查詢語句
*
* @return string 返回該語句影響的資料行數
*/
function execute($sql){
$rs = mysql_query($sql) or $this->_halt('語句執行錯誤', $sql);
return mysql_affected_rows($this->cnn);
}
/*
* 得到最後一次插入資料的編號
*/
function getInsertId(){
return mysql_insert_id($this->cnn);
}
/*
* 序列發生器,用來產生不重複的序列值
*
* @param $fieldName string 序列的名稱
* @param $step int 序號間隔
* @param $start int 序號的起始數值
*
* @return int 新的序列值
*/
function getSeq($fieldName, $step=1, $start=1){
$table = DB_SEQUENCE_TABLENAME;
$step = (int)$step;
$start = (int)$start;
$rs = mysql_query("UPDATE $table SET seq_num=seq_num+($step) WHERE seq_name='$fieldName'");
if(!$rs || mysql_affected_rows($this->cnn)<1){
$rs = mysql_query('SELECT * FROM '.DB_SEQUENCE_TABLENAME, $this->cnn);
if(!$rs){
$sql = "CREATE TABLE $table (
seq_name VARCHAR( 20 ) NOT NULL ,
seq_num BIGINT( 20 ) DEFAULT 1 NOT NULL ,
PRIMARY KEY (seq_name))";
$rs = mysql_query($sql) or $this->_halt('建立序列發生器表失敗', $sql);
}
$rs = mysql_query("INSERT INTO $table VALUES('$fieldName', $start)") or
$this->_halt('添加新序列錯誤', $sql);
$seq = $start;
}else{
$seq = &$this->getOne("SELECT seq_num FROM $table WHERE seq_name='$fieldName'");
}
return $seq;
}
function _getCommand($fetchType){
switch($fetchType){
case DB_FETCH_ASSOC: $exe = 'mysql_fetch_assoc'; break;
case DB_FETCH_NUM: $exe = 'mysql_fetch_row'; break;
case DB_FETCH_BOTH: $exe = 'mysql_fetch_array'; break;
case DB_FETCH_OBJECT: $exe = 'mysql_fetch_object'; break;
default: $exe = 'mysql_fetch_array'; break;
}
return $exe;
}
function _halt($msg){
$errNo = mysql_errno($this->cnn);
$errStr = mysql_error($this->cnn);
die("資料庫錯誤:$msg<br> $errNo : $errStr");
}
}
?>