加快开发之1--“数据插入/更新操作”基类
时间:2006-10-09 来源:放弃思考
早前写过一片文章《
利用正则表达式加快开发
》 ,开发速度快了不少,不过项目复杂了,发现缺点很多,且对结构清晰和可读性没有任何帮助,于是在新项目中就写了这个数据操作基类,专门负责数据的插入更新等操作。
使用过adodb的朋友,一定很熟悉里面的两个方法:getInsertSql()和getUpdateSql(),是根据数组生成sql语句用的。在复杂的项目,使用这两个方法带来的好处显而意见。
我写的这个类是adodb_lite版本的,改成适用其他数据库类也不难。当然也可以直接参考里面的方法,写一个适用自己情况的类。
该类的基本代码general_sql.class.php:
class GeneralSql
{
var $dbtableMessages;//数据表名称
var $db;//数据库连接对象
var $debugging = DEBUG_MODE; //调试模式:TRUE是开启,FALSE时关闭
//构造函数
function GeneralSql($dsn, $dbtableMessages='table_name')
{
$this->db =& get_dbobject($dsn); //get_dbobject() 方法是获得一个数据库连接,代码可参考附录
$this->dbtableMessages = $dbtableMessages;
}
###########扩展数据操作函数####################
//在一个表中插入多个数据
function multiInsert ($array,$table=0)
{
foreach ( $array as $key => $value )
{
if ( is_array( $value ) )
{
if ( !( $this->insert($value,$table) ) )
return false;//如果插入失败,就返回
}
}
return true;
}
//插入一条数据
function insert ($array,$table=0)
{
$sql = $this->getInsertSql($array,$table);
$this->db->Query($sql);
$results = $this->db->Insert_ID();
if($results > 0)
return $results;
else if ( $this->debugging )
{
echo '
SQL语句为:'.$sql.'
';
die($this->db->ErrorMsg());
}else
return 0;
}
//在多个表中更新同样的字段
function multiUpdate($array,$where)
{
foreach ( $where as $key => $value )//此处$key为表名,$value为条件数组。
{
if ( !($this->update($array,$value,$key)) )
return false;
}
return true;
}
//一般更新方式,只要语法合法就会返回成功
function update ($array,$where,$table=0)
{
$sql = $this->getUpdateSql($array,$where,$table);
$this->db->Query("set names 'utf8'");
$results=$this->db->Query($sql);
if($results)
return true;
else if ( $this->debugging )
{
echo '
sql语句为:'.$sql.'
';
die($this->db->ErrorMsg());
}else
return false;
}
//严格更新方式,即只有数据更新了才返回成功
function strictUpdate ($array,$where,$table=0)
{
$sql = $this->getUpdateSql($array,$where,$table);
$this->db->Query($sql);
$results = $this->db->Affected_Rows();
if($results)
return true;
else if ( $this->debugging )
{
echo '
sql语句为:'.$sql.'
';
die($this->db->ErrorMsg());
}else
return false;
}
//返回数据插入语句
function &getInsertSql ($data,$table=0)
{
$sql_head = '';
$sql_end ='';
if ( is_array( $data ) )
{
foreach ( $data as $key => $value )
{
$sql_head .= "`" . $key . "`,";
if ( is_int( $value ) )//是整数的情况
{
$sql_end .= $value . ",";
}else if ( is_string( $value ) )//是字符串的情况
{
$sql_end .= "'" . $value . "',";
}else//其他情况
{
$sql_end .= "'" . $value . "',";
}
}
if ( $table )
{
$sql = 'insert into '.$table.' (' . subStr( $sql_head,0,-1 ) .') values ('. subStr( $sql_end,0,-1) . ')';
}else
{
$sql = 'insert into '.$this->dbtableMessages.' (' . subStr( $sql_head,0,-1 ) .') values ('. subStr( $sql_end,0,-1) . ')';
}
}else
die('insert error: $data is not an array!');
return $sql;
}
//返回数据更新语句
function &getUpdateSql ($data,$where,$table=0)
{
$sql_head = '';
$sql_end = '';
if ( is_array( $data ) )
{
foreach ( $data as $key => $value )
{
$sql_head .= "`" . $key ."`=";
if ( is_int( $value ) )//是整数的情况
{
$sql_head .= $value . ',';
}else if ( is_string( $value ) )//是字符串的情况
{
$sql_head .= "'" . $value . "',";
}else if ( is_array( $value ) )//用来处理特别情况,比如 friends = friends+1 这种。
{
$sql_head .= $value[0] . ',';
}else//其他情况
{
$sql_head .= "'" . $value . "',";
}
}
}else
die('update error: $data is not an array');
if ( is_array( $where ) )
{
foreach ( $where as $key => $value )
{
if ( subStr( $key,0,6 ) == '#conj#' )//连接词(比如and 或者 or),用来处理多个条件的情况
{
$sql_end .=' ' . $value . ' ';
}else
{
$sql_end .= "`" . $key . "`=";
if ( is_int( $value ) )//是整数的情况
{
$sql_end .= $value;
}else if ( is_string( $value ) )//是字符串的情况
{
$sql_end .= "'" . $value . "'";
}else//其他情况
{
$sql_end .= "'" . $value . "'";
}
}
}
}else
die('update error: $where is not an array');
if ( $table )
{
$sql = 'update ' . $table . ' set ' . subStr( $sql_head,0,-1 ) . ' where ' . $sql_end;
}else
{
$sql = 'update ' . $this->dbtableMessages . ' set ' . subStr( $sql_head,0,-1 ) . ' where ' . $sql_end;
}
return $sql;
}
}
?>
说明:其中构造函数中用到 get_dbobject() 方法是获得一个数据库连接,在附录有源代码。
大概用法:
1 在主配置文件,或者相应的php程序中添加:
define( 'DEBUG_MODE',TRUE );//测试模式
include_once( './includes/general_sql.class.php' );
2 比如有一用户数据表user,含有user_id(主键),nickname,name,birdathday...等等字段。
那么相应的user操作类为:
db =& get_dbobject($dsn);
$this->dbtableMessages = $dbtableMessages;
}
......//其他user方法,如查询等等
?>
那么在程序,我们如果要插入一新的用户,则只需:
$user = new User(DB_DSN,'user');//DB_DSN为数据库连接用的 DSN 字符串,可参考附录
$data = $array(
'nickname' => $nickname,
'name' => $name,
'birdathday' => $birdathday,
//其他字段......
);
if($user->insert($data))
{
//用户插入成功
}
相应的,更新操作为:
$data2 = array(
'nickname' => $nickname,
'name' => $name,
'birdathday' => $birdathday,
//其他字段......
);
$where2 = array(
'user_id' => $user_id,
'#conj#' => 'and',
'status' => 1,
);
if($user->strictUpdate($data2,$where2))
{
//用户信息更新成功
}
当然如果只有上诉几个字段,那大可不必用该类,但是如果是在字段很多的情况下,且开发时间很紧的情况,那么使用这种方式可以大大的加快开发速度,最重要的是,结构的清晰,使得修改和增加功能都变得非常方便。该类的还有两个方法如:在一个表中插入多个数据(multiInsert) 和 在多个表中更新同样的字段(multiUpdate),是根据我自己的需求所写的,就不详细介绍了。
最后,当然如果您使用的是adodb,那么自然不用看该类啦,呵呵
附录:
数据库连接配置文件:
define('DB_HOST', '192.168.0.1:3306');// 数据库所在服务器
define('DB_NAME', 'test');// 数据库名称
define('DB_USER', 'root');// 数据库连接用户名
define('DB_PASS', '');// 数据库连接密码
define('DB_DSN', DB_TYPE . '://' . DB_USER . ':' . DB_PASS .
[email='@']'@'[/email]
. DB_HOST . '/' . DB_NAME); // DSN 字符串
/**
* 分析 DSN 字符串
* 如果成功返回分析结果,失败返回 false
* @param string $dsn 要分析的 dsn 字符串
* @return array|boolean
*/
function parse_dsn($dsn) {
$dsn = str_replace('@/',
[email='@localhost/']'@localhost/'[/email]
, $dsn);
$parse = parse_url($dsn);
if (empty($parse['scheme'])) { return false; }
$dsn = array();
$dsn['host'] = $parse['host'];
$dsn['port'] = $parse['port'];
$dsn['user'] = $parse['user'];
if(array_key_exists('pass',$parse))
$dsn['pass'] = $parse['pass'];
else
$dsn['pass'] = '';
$dsn['driver'] = strtolower($parse['scheme']);
$dsn['dbname'] = (isset($parse['path'])) ? substr($parse['path'], 1) : '';
$dsn['options'] = (isset($parse['query'])) ? $parse['query'] : '';
return $dsn;
}
/**
* 获得数据库连接对象
* @return object
* @access public
*/
function & get_dbobject($dsnString = DB_DSN) {
static $instances = array();
if (isset($instances[$dsnString])) { return $instances[$dsnString]; }
if (!($dsn = parse_dsn($dsnString))) { return false; }
require_once(ADOLITE_PATH . '/adodb.inc.php');
$instances[$dsnString] = ADONewConnection($dsn['driver']);
if (!$instances[$dsnString]->Connect($dsn['host'].":3307", $dsn['user'], $dsn['pass'], $dsn['dbname'])) {
die("数据库错误:" . __FILE__ . ':' . __LINE__ . "\n" . "Can't connectio to database: {$dsn['dbname']}\n" . "username and host: {$dsn['user']}@{$dsn['host']}\n");
}
$instances[$dsnString]->SetFetchMode(ADODB_FETCH_ASSOC);
if (strtolower(substr($dsn['driver'], 0, 5)) == 'mysql') {
$version = $instances[$dsnString]->GetOne('SELECT VERSION()');
if ($version >= '4.1') {
$instances[$dsnString]->Execute("SET NAMES 'latin1'");
//该处视自己的字符集设定而定。MYSQL版本4.1版本以下无需考虑
}
}
return $instances[$dsnString];
}
?>
利用正则表达式加快开发
》 ,开发速度快了不少,不过项目复杂了,发现缺点很多,且对结构清晰和可读性没有任何帮助,于是在新项目中就写了这个数据操作基类,专门负责数据的插入更新等操作。
使用过adodb的朋友,一定很熟悉里面的两个方法:getInsertSql()和getUpdateSql(),是根据数组生成sql语句用的。在复杂的项目,使用这两个方法带来的好处显而意见。
我写的这个类是adodb_lite版本的,改成适用其他数据库类也不难。当然也可以直接参考里面的方法,写一个适用自己情况的类。
该类的基本代码general_sql.class.php:
class GeneralSql
{
var $dbtableMessages;//数据表名称
var $db;//数据库连接对象
var $debugging = DEBUG_MODE; //调试模式:TRUE是开启,FALSE时关闭
//构造函数
function GeneralSql($dsn, $dbtableMessages='table_name')
{
$this->db =& get_dbobject($dsn); //get_dbobject() 方法是获得一个数据库连接,代码可参考附录
$this->dbtableMessages = $dbtableMessages;
}
###########扩展数据操作函数####################
//在一个表中插入多个数据
function multiInsert ($array,$table=0)
{
foreach ( $array as $key => $value )
{
if ( is_array( $value ) )
{
if ( !( $this->insert($value,$table) ) )
return false;//如果插入失败,就返回
}
}
return true;
}
//插入一条数据
function insert ($array,$table=0)
{
$sql = $this->getInsertSql($array,$table);
$this->db->Query($sql);
$results = $this->db->Insert_ID();
if($results > 0)
return $results;
else if ( $this->debugging )
{
echo '
SQL语句为:'.$sql.'
';
die($this->db->ErrorMsg());
}else
return 0;
}
//在多个表中更新同样的字段
function multiUpdate($array,$where)
{
foreach ( $where as $key => $value )//此处$key为表名,$value为条件数组。
{
if ( !($this->update($array,$value,$key)) )
return false;
}
return true;
}
//一般更新方式,只要语法合法就会返回成功
function update ($array,$where,$table=0)
{
$sql = $this->getUpdateSql($array,$where,$table);
$this->db->Query("set names 'utf8'");
$results=$this->db->Query($sql);
if($results)
return true;
else if ( $this->debugging )
{
echo '
sql语句为:'.$sql.'
';
die($this->db->ErrorMsg());
}else
return false;
}
//严格更新方式,即只有数据更新了才返回成功
function strictUpdate ($array,$where,$table=0)
{
$sql = $this->getUpdateSql($array,$where,$table);
$this->db->Query($sql);
$results = $this->db->Affected_Rows();
if($results)
return true;
else if ( $this->debugging )
{
echo '
sql语句为:'.$sql.'
';
die($this->db->ErrorMsg());
}else
return false;
}
//返回数据插入语句
function &getInsertSql ($data,$table=0)
{
$sql_head = '';
$sql_end ='';
if ( is_array( $data ) )
{
foreach ( $data as $key => $value )
{
$sql_head .= "`" . $key . "`,";
if ( is_int( $value ) )//是整数的情况
{
$sql_end .= $value . ",";
}else if ( is_string( $value ) )//是字符串的情况
{
$sql_end .= "'" . $value . "',";
}else//其他情况
{
$sql_end .= "'" . $value . "',";
}
}
if ( $table )
{
$sql = 'insert into '.$table.' (' . subStr( $sql_head,0,-1 ) .') values ('. subStr( $sql_end,0,-1) . ')';
}else
{
$sql = 'insert into '.$this->dbtableMessages.' (' . subStr( $sql_head,0,-1 ) .') values ('. subStr( $sql_end,0,-1) . ')';
}
}else
die('insert error: $data is not an array!');
return $sql;
}
//返回数据更新语句
function &getUpdateSql ($data,$where,$table=0)
{
$sql_head = '';
$sql_end = '';
if ( is_array( $data ) )
{
foreach ( $data as $key => $value )
{
$sql_head .= "`" . $key ."`=";
if ( is_int( $value ) )//是整数的情况
{
$sql_head .= $value . ',';
}else if ( is_string( $value ) )//是字符串的情况
{
$sql_head .= "'" . $value . "',";
}else if ( is_array( $value ) )//用来处理特别情况,比如 friends = friends+1 这种。
{
$sql_head .= $value[0] . ',';
}else//其他情况
{
$sql_head .= "'" . $value . "',";
}
}
}else
die('update error: $data is not an array');
if ( is_array( $where ) )
{
foreach ( $where as $key => $value )
{
if ( subStr( $key,0,6 ) == '#conj#' )//连接词(比如and 或者 or),用来处理多个条件的情况
{
$sql_end .=' ' . $value . ' ';
}else
{
$sql_end .= "`" . $key . "`=";
if ( is_int( $value ) )//是整数的情况
{
$sql_end .= $value;
}else if ( is_string( $value ) )//是字符串的情况
{
$sql_end .= "'" . $value . "'";
}else//其他情况
{
$sql_end .= "'" . $value . "'";
}
}
}
}else
die('update error: $where is not an array');
if ( $table )
{
$sql = 'update ' . $table . ' set ' . subStr( $sql_head,0,-1 ) . ' where ' . $sql_end;
}else
{
$sql = 'update ' . $this->dbtableMessages . ' set ' . subStr( $sql_head,0,-1 ) . ' where ' . $sql_end;
}
return $sql;
}
}
?>
说明:其中构造函数中用到 get_dbobject() 方法是获得一个数据库连接,在附录有源代码。
大概用法:
1 在主配置文件,或者相应的php程序中添加:
define( 'DEBUG_MODE',TRUE );//测试模式
include_once( './includes/general_sql.class.php' );
2 比如有一用户数据表user,含有user_id(主键),nickname,name,birdathday...等等字段。
那么相应的user操作类为:
db =& get_dbobject($dsn);
$this->dbtableMessages = $dbtableMessages;
}
......//其他user方法,如查询等等
?>
那么在程序,我们如果要插入一新的用户,则只需:
$user = new User(DB_DSN,'user');//DB_DSN为数据库连接用的 DSN 字符串,可参考附录
$data = $array(
'nickname' => $nickname,
'name' => $name,
'birdathday' => $birdathday,
//其他字段......
);
if($user->insert($data))
{
//用户插入成功
}
相应的,更新操作为:
$data2 = array(
'nickname' => $nickname,
'name' => $name,
'birdathday' => $birdathday,
//其他字段......
);
$where2 = array(
'user_id' => $user_id,
'#conj#' => 'and',
'status' => 1,
);
if($user->strictUpdate($data2,$where2))
{
//用户信息更新成功
}
当然如果只有上诉几个字段,那大可不必用该类,但是如果是在字段很多的情况下,且开发时间很紧的情况,那么使用这种方式可以大大的加快开发速度,最重要的是,结构的清晰,使得修改和增加功能都变得非常方便。该类的还有两个方法如:在一个表中插入多个数据(multiInsert) 和 在多个表中更新同样的字段(multiUpdate),是根据我自己的需求所写的,就不详细介绍了。
最后,当然如果您使用的是adodb,那么自然不用看该类啦,呵呵
附录:
数据库连接配置文件:
define('DB_HOST', '192.168.0.1:3306');// 数据库所在服务器
define('DB_NAME', 'test');// 数据库名称
define('DB_USER', 'root');// 数据库连接用户名
define('DB_PASS', '');// 数据库连接密码
define('DB_DSN', DB_TYPE . '://' . DB_USER . ':' . DB_PASS .
[email='@']'@'[/email]
. DB_HOST . '/' . DB_NAME); // DSN 字符串
/**
* 分析 DSN 字符串
* 如果成功返回分析结果,失败返回 false
* @param string $dsn 要分析的 dsn 字符串
* @return array|boolean
*/
function parse_dsn($dsn) {
$dsn = str_replace('@/',
[email='@localhost/']'@localhost/'[/email]
, $dsn);
$parse = parse_url($dsn);
if (empty($parse['scheme'])) { return false; }
$dsn = array();
$dsn['host'] = $parse['host'];
$dsn['port'] = $parse['port'];
$dsn['user'] = $parse['user'];
if(array_key_exists('pass',$parse))
$dsn['pass'] = $parse['pass'];
else
$dsn['pass'] = '';
$dsn['driver'] = strtolower($parse['scheme']);
$dsn['dbname'] = (isset($parse['path'])) ? substr($parse['path'], 1) : '';
$dsn['options'] = (isset($parse['query'])) ? $parse['query'] : '';
return $dsn;
}
/**
* 获得数据库连接对象
* @return object
* @access public
*/
function & get_dbobject($dsnString = DB_DSN) {
static $instances = array();
if (isset($instances[$dsnString])) { return $instances[$dsnString]; }
if (!($dsn = parse_dsn($dsnString))) { return false; }
require_once(ADOLITE_PATH . '/adodb.inc.php');
$instances[$dsnString] = ADONewConnection($dsn['driver']);
if (!$instances[$dsnString]->Connect($dsn['host'].":3307", $dsn['user'], $dsn['pass'], $dsn['dbname'])) {
die("数据库错误:" . __FILE__ . ':' . __LINE__ . "\n" . "Can't connectio to database: {$dsn['dbname']}\n" . "username and host: {$dsn['user']}@{$dsn['host']}\n");
}
$instances[$dsnString]->SetFetchMode(ADODB_FETCH_ASSOC);
if (strtolower(substr($dsn['driver'], 0, 5)) == 'mysql') {
$version = $instances[$dsnString]->GetOne('SELECT VERSION()');
if ($version >= '4.1') {
$instances[$dsnString]->Execute("SET NAMES 'latin1'");
//该处视自己的字符集设定而定。MYSQL版本4.1版本以下无需考虑
}
}
return $instances[$dsnString];
}
?>
相关阅读 更多 +