- 浏览: 40061 次
- 性别:
- 来自: 厦门
最新评论
PHP V5 新的面向对象编程特性显著提升了这个流行语言中的功能层次。学习如何用 PHP V5 动态特性创建可以满足需求的对象。
PHP V5 中新的面向对象编程(OOP)特性的引入显著提升了这个编程语言的功能层次。现在不仅有了私有的、受保护的和公共的成员变量和函数 —— 就像在 Java™、 C++ 或 C# 编程语言中一样 —— 但是还可以创建在运行时变化的对象,即动态地创建新方法和成员变量。而使用 Java、C++ 或 C# 语言是做不到这件事的。这种功能使得超级快速的应用程序开发系统(例如 Ruby on Rails)成为可能。
但是,在进入这些之前,有一点要注意:本文介绍 PHP V5 中非常高级的 OOP 特性的使用,但是这类特性不是在每个应用程序中都需要的。而且,如果不具备 OOP 的坚实基础以及 PHP 对象语法的初步知识,这类特性将会很难理解。
动态的重要性
对象是把双刃剑。一方面,对象是封装数据和逻辑并创建更容易维护的系统的重大方式。但另一方面,它们会变得很繁琐,需要许多冗余的代码,这时可能最希望做到的就是不要犯错。这类问题的一个示例来自数据库访问对象。一般来说,想用一个类代表每个数据库表,并执行以下功能:对象从数据库读出数据行;允许更新字段,然后用新数据更新数据库或删除行。还有一种方法可以创建新的空对象,设置对象的字段,并把数据插入数据库。
如果在数据库中有一个表,名为 Customers,那么就应当有一个对象,名为 Customer,它应当拥有来自表的字段,并代表一个客户。而且 Customer 对象应当允许插入、更新或删除数据库中对应的记录。现在,一切都很好,而且有也很多意义。但是,有许多代码要编写。如果在数据库中有 20 个表,就需要 20 个类。
有三个解决方案可以采用。第一个解决方案就是,坐在键盘前,老老实实地录入一段时间。对于小项目来说,这还可以,但是我很懒。第二个解决方案是用代码生成器,读取数据库模式,并自动编写代码。这是个好主意,而且是另一篇文章的主题。第三个解决方案,也是我在本文中介绍的,是编写一个类,在运行时动态地把自己塑造成指定表的字段。这个类执行起来比起特定于表的类可能有点慢 —— 但是把我从编写大量代码中解脱出来。这个解决方案在项目开始的时候特别有用,因为这时表和字段不断地变化,所以跟上迅速的变化是至关重要的。
所以
在这里,把类的名称从 Book 改成 DBObject。然后,把构造函数修改成接受表的名称和表中字段的名称。之后,大多数变化发生在类的方法中,过去使用一些硬编码结构化查询语言(SQL),现在则必须用表和字段的名称动态地创建 SQL 字符串。
代码的惟一假设就是只有一个主键字段,而且这个字段的名称是表名加上 _id。所以,在 book 表这个示例中,有一个主键字段叫做 book_id。主键的命名标准可能不同;如果这样,需要修改代码以符合标准。
这个类比最初的 Book 类复杂得多。但是,从类的客户的角度来看,这个类用起来仍很简单。也就是说,我认为这个类能更简单。具体来说,我不愿意每次创建图书的时候都要指定表和字段的名称。如果我四处拷贝和粘贴这个代码,然后修改了 book 表的字段结构,那么我可能就麻烦了。在清单 6 中,通过创建一个继承自 DBObject 的简单 Book 类,我解决了这个问题。
清单 6. 新的 Book 类
,如何才能编写一个能够弯曲 的类呢?
回页首
写一个柔性的类
对象有两个方面:成员变量 和方法。在编译语言(例如 Java)中,如果想调用不存在的方法或引用不存在的成员变量,会得到编译时错误。但是,在非编译语言,例如 PHP 中,会发生什么?
在 PHP 中的方法调用是这样工作的。首先,PHP 解释器在类上查找方法。如果方法存在,PHP 就调用它。如果没有,那么就调用类上的魔法方法 __call(如果这个方法存在的话)。如果 __call 失败,就调用父类方法,依此类推。
魔法方法
魔法方法是有特定名称的方法,PHP 解释器在脚本执行的特定点上会查找魔法方法。最常见的魔法方法就是对象创始时调用的构造函数。
__call 方法有两个参数:被请求的方法的名称和方法参数。如果创建的 __call 方法接受这两个参数,执行某项功能,然后返回 TRUE,那么调用这个对象的代码就永远不会知道在有代码的方法和 __call 机制处理的方法之间的区别。通过这种方式,可以创建这样的对象,即动态地模拟拥有无数方法的情况。
除了 __call 方法,其他魔法方法 —— 包括 __get 和 __set —— 调用它们的时候,都是因为引用了不存在的实例变量。脑子里有了这个概念之后,就可以开始编写能够适应任何表的动态数据库访问类了。
回页首
经典的数据库访问
先从一个简单的数据库模式开始。清单 1 所示的模式针对的是单一的数据表数据库,容纳图书列表。
清单 1. MySQL 数据库模式
DROP TABLE IF EXISTS book;
CREATE TABLE book (
book_id INT NOT NULL AUTO_INCREMENT,
title TEXT,
publisher TEXT,
author TEXT,
PRIMARY KEY( book_id )
);
请把这个模式装入到名为 bookdb 的数据库。
接下来,编写一个常规的数据库类,然后再把它修改成动态的。清单 2 显示了图书表的简单的数据库访问类。
清单 2. 基本的数据库访问客户机
<?php require_once("DB.php"); $dsn = 'mysql://root:password@localhost/bookdb'; $db =& DB::Connect( $dsn, array() ); if (PEAR::isError($db)) { die($db->getMessage()); } class Book { private $book_id; private $title; private $author; private $publisher; function __construct() { } function set_title( $title ) { $this->title = $title; } function get_title( ) { return $this->title; } function set_author( $author ) { $this->author = $author; } function get_author( ) { return $this->author; } function set_publisher( $publisher ) { $this->publisher = $publisher; } function get_publisher( ) { return $this->publisher; } function load( $id ) { global $db; $res = $db->query( "SELECT * FROM book WHERE book_id=?", array( $id ) ); $res->fetchInto( $row, DB_FETCHMODE_ASSOC ); $this->book_id = $id; $this->title = $row['title']; $this->author = $row['author']; $this->publisher = $row['publisher']; } function insert() { global $db; $sth = $db->prepare( 'INSERT INTO book ( book_id, title, author, publisher ) VALUES ( 0, ?, ?, ? )' ); $db->execute( $sth, array( $this->title, $this->author, $this->publisher ) ); $res = $db->query( "SELECT last_insert_id()" ); $res->fetchInto( $row ); return $row[0]; } function update() { global $db; $sth = $db->prepare( 'UPDATE book SET title=?, author=?, publisher=? WHERE book_id=?' ); $db->execute( $sth, array( $this->title, $this->author, $this->publisher, $this->book_id ) ); } function delete() { global $db; $sth = $db->prepare( 'DELETE FROM book WHERE book_id=?' ); $db->execute( $sth, array( $this->book_id ) ); } function delete_all() { global $db; $sth = $db->prepare( 'DELETE FROM book' ); $db->execute( $sth ); } } $book = new Book(); $book->delete_all(); $book->set_title( "PHP Hacks" ); $book->set_author( "Jack Herrington" ); $book->set_publisher( "O'Reilly" ); $id = $book->insert(); echo ( "New book id = $id\n" ); $book2 = new Book(); $book2->load( $id ); echo( "Title = ".$book2->get_title()."\n" ); $book2->delete( ); ?>
为了保持代码简单,我把类和测试代码放在一个文件中。文件首先得到数据库句柄,句柄保存在一个全局变量中。然后定义 Book 类,用私有成员变量代表每个字段。还包含了一套用来从数据库装入、插入、更新和删除行的方法。
底部的测试代码先删除数据库中的所有条目。然后,代码插入一本书,输出新记录的 ID。然后,代码把这本书装入另一个对象并输出书名。
清单 3 显示了在命令行上用 PHP 解释器运行代码的效果。
清单 3. 在命令行运行代码
% php db1.php
New book id = 25
Title = PHP Hacks
%
不需要看太多,就已经得到重点了。Book 对象代表图书数据表中的行。通过使用上面的字段和方法,可以创建新行、更新行和删除行。
回页首
初识动态
下一步是让类变得稍微动态一些:动态地为每个字段创建 get_ 和 set_ 方法。清单 4 显示了更新后的代码。
清单 4. 动态 get_ 和 set_ 方法
<?php require_once("DB.php"); $dsn = 'mysql://root:password@localhost/bookdb'; $db =& DB::Connect( $dsn, array() ); if (PEAR::isError($db)) { die($db->getMessage()); } class Book { private $book_id; private $fields = array(); function __construct() { $this->fields[ 'title' ] = null; $this->fields[ 'author' ] = null; $this->fields[ 'publisher' ] = null; } function __call( $method, $args ) { if ( preg_match( "/set_(.*)/", $method, $found ) ) { if ( array_key_exists( $found[1], $this->fields ) ) { $this->fields[ $found[1] ] = $args[0]; return true; } } else if ( preg_match( "/get_(.*)/", $method, $found ) ) { if ( array_key_exists( $found[1], $this->fields ) ) { return $this->fields[ $found[1] ]; } } return false; } function load( $id ) { global $db; $res = $db->query( "SELECT * FROM book WHERE book_id=?", array( $id ) ); $res->fetchInto( $row, DB_FETCHMODE_ASSOC ); $this->book_id = $id; $this->set_title( $row['title'] ); $this->set_author( $row['author'] ); $this->set_publisher( $row['publisher'] ); } function insert() { global $db; $sth = $db->prepare( 'INSERT INTO book ( book_id, title, author, publisher ) VALUES ( 0, ?, ?, ? )' ); $db->execute( $sth, array( $this->get_title(), $this->get_author(), $this->get_publisher() ) ); $res = $db->query( "SELECT last_insert_id()" ); $res->fetchInto( $row ); return $row[0]; } function update() { global $db; $sth = $db->prepare( 'UPDATE book SET title=?, author=?, publisher=? WHERE book_id=?' ); $db->execute( $sth, array( $this->get_title(), $this->get_author(), $this->get_publisher(), $this->book_id ) ); } function delete() { global $db; $sth = $db->prepare( 'DELETE FROM book WHERE book_id=?' ); $db->execute( $sth, array( $this->book_id ) ); } function delete_all() { global $db; $sth = $db->prepare( 'DELETE FROM book' ); $db->execute( $sth ); } } ..
要做这个变化,需要做两件事。首先,必须把字段从单个实例变量修改成字段和值组合构成的散列表。然后必须添加一个 __call 方法,它只查看方法名称,看方法是 set_ 还是 get_ 方法,然后在散列表中设置适当的字段。
注意,load 方法通过调用 set_title、set_author 和 set_publisher方法 —— 实际上都不存在 —— 来实际使用 __call 方法。
回页首
走向完全动态
删除 get_ 和 set_ 方法只是一个起点。要创建完全动态的数据库对象,必须向类提供表和字段的名称,还不能有硬编码的引用。清单 5 显示了这个变化。
清单 5. 完全动态的数据库对象类
<?php require_once("DB.php"); $dsn = 'mysql://root:password@localhost/bookdb'; $db =& DB::Connect( $dsn, array() ); if (PEAR::isError($db)) { die($db->getMessage()); } class DBObject { private $id = 0; private $table; private $fields = array(); function __construct( $table, $fields ) { $this->table = $table; foreach( $fields as $key ) $this->fields[ $key ] = null; } function __call( $method, $args ) { if ( preg_match( "/set_(.*)/", $method, $found ) ) { if ( array_key_exists( $found[1], $this->fields ) ) { $this->fields[ $found[1] ] = $args[0]; return true; } } else if ( preg_match( "/get_(.*)/", $method, $found ) ) { if ( array_key_exists( $found[1], $this->fields ) ) { return $this->fields[ $found[1] ]; } } return false; } function load( $id ) { global $db; $res = $db->query( "SELECT * FROM ".$this->table." WHERE ". $this->table."_id=?", array( $id ) ); $res->fetchInto( $row, DB_FETCHMODE_ASSOC ); $this->id = $id; foreach( array_keys( $row ) as $key ) $this->fields[ $key ] = $row[ $key ]; } function insert() { global $db; $fields = $this->table."_id, "; $fields .= join( ", ", array_keys( $this->fields ) ); $inspoints = array( "0" ); foreach( array_keys( $this->fields ) as $field ) $inspoints []= "?"; $inspt = join( ", ", $inspoints ); $sql = "INSERT INTO ".$this->table." ( $fields ) VALUES ( $inspt )"; $values = array(); foreach( array_keys( $this->fields ) as $field ) $values []= $this->fields[ $field ]; $sth = $db->prepare( $sql ); $db->execute( $sth, $values ); $res = $db->query( "SELECT last_insert_id()" ); $res->fetchInto( $row ); $this->id = $row[0]; return $row[0]; } function update() { global $db; $sets = array(); $values = array(); foreach( array_keys( $this->fields ) as $field ) { $sets []= $field.'=?'; $values []= $this->fields[ $field ]; } $set = join( ", ", $sets ); $values []= $this->id; $sql = 'UPDATE '.$this->table.' SET '.$set. ' WHERE '.$this->table.'_id=?'; $sth = $db->prepare( $sql ); $db->execute( $sth, $values ); } function delete() { global $db; $sth = $db->prepare( 'DELETE FROM '.$this->table.' WHERE '. $this->table.'_id=?' ); $db->execute( $sth, array( $this->id ) ); } function delete_all() { global $db; $sth = $db->prepare( 'DELETE FROM '.$this->table ); $db->execute( $sth ); } } $book = new DBObject( 'book', array( 'author', 'title', 'publisher' ) ); $book->delete_all(); $book->set_title( "PHP Hacks" ); $book->set_author( "Jack Herrington" ); $book->set_publisher( "O'Reilly" ); $id = $book->insert(); echo ( "New book id = $id\n" ); $book->set_title( "Podcasting Hacks" ); $book->update(); $book2 = new DBObject( 'book', array( 'author', 'title', 'publisher' ) ); $book2->load( $id ); echo( "Title = ".$book2->get_title()."\n" ); $book2->delete( ); ? >
在这里,把类的名称从 Book 改成 DBObject。然后,把构造函数修改成接受表的名称和表中字段的名称。之后,大多数变化发生在类的方法中,过去使用一些硬编码结构化查询语言(SQL),现在则必须用表和字段的名称动态地创建 SQL 字符串。
代码的惟一假设就是只有一个主键字段,而且这个字段的名称是表名加上 _id。所以,在 book 表这个示例中,有一个主键字段叫做 book_id。主键的命名标准可能不同;如果这样,需要修改代码以符合标准。
这个类比最初的 Book 类复杂得多。但是,从类的客户的角度来看,这个类用起来仍很简单。也就是说,我认为这个类能更简单。具体来说,我不愿意每次创建图书的时候都要指定表和字段的名称。如果我四处拷贝和粘贴这个代码,然后修改了 book 表的字段结构,那么我可能就麻烦了。在清单 6 中,通过创建一个继承自 DBObject 的简单 Book 类,我解决了这个问题。
清单 6. 新的 Book 类
.. class Book extends DBObject { function __construct() { parent::__construct( 'book', array( 'author', 'title', 'publisher' ) ); } } $book = new Book( ); $book->delete_all(); $book->{'title'} = "PHP Hacks"; $book->{'author'} = "Jack Herrington"; $book->{'publisher'} = "O'Reilly"; $id = $book->insert(); echo ( "New book id = $id\n" ); $book->{'title'} = "Podcasting Hacks"; $book->update(); $book2 = new Book( ); $book2->load( $id ); echo( "Title = ".$book2->{'title'}."\n" ); $book2->delete( ); ?>
现在,Book 类真的是简单了。而且 Book 类的客户也不再需要知道表或字段的名称了。
回页首
改进的空间
对这个动态类我想做的最后一个改进,是用成员变量访问字段,而不是用笨重的 get_ 和 set_ 操作符。清单 7 显示了如何用 __get 和 __set 魔法方法代替 __call。
清单 7. 使用 __get 和 __set 方法
<?php require_once("DB.php"); $dsn = 'mysql://root:password@localhost/bookdb'; $db =& DB::Connect( $dsn, array() ); if (PEAR::isError($db)) { die($db->getMessage()); } class DBObject { private $id = 0; private $table; private $fields = array(); function __construct( $table, $fields ) { $this->table = $table; foreach( $fields as $key ) $this->fields[ $key ] = null; } function __get( $key ) { return $this->fields[ $key ]; } function __set( $key, $value ) { if ( array_key_exists( $key, $this->fields ) ) { $this->fields[ $key ] = $value; return true; } return false; } function load( $id ) { global $db; $res = $db->query( "SELECT * FROM ".$this->table." WHERE ". $this->table."_id=?", array( $id ) ); $res->fetchInto( $row, DB_FETCHMODE_ASSOC ); $this->id = $id; foreach( array_keys( $row ) as $key ) $this->fields[ $key ] = $row[ $key ]; } function insert() { global $db; $fields = $this->table."_id, "; $fields .= join( ", ", array_keys( $this->fields ) ); $inspoints = array( "0" ); foreach( array_keys( $this->fields ) as $field ) $inspoints []= "?"; $inspt = join( ", ", $inspoints ); $sql = "INSERT INTO ".$this->table. " ( $fields ) VALUES ( $inspt )"; $values = array(); foreach( array_keys( $this->fields ) as $field ) $values []= $this->fields[ $field ]; $sth = $db->prepare( $sql ); $db->execute( $sth, $values ); $res = $db->query( "SELECT last_insert_id()" ); $res->fetchInto( $row ); $this->id = $row[0]; return $row[0]; } function update() { global $db; $sets = array(); $values = array(); foreach( array_keys( $this->fields ) as $field ) { $sets []= $field.'=?'; $values []= $this->fields[ $field ]; } $set = join( ", ", $sets ); $values []= $this->id; $sql = 'UPDATE '.$this->table.' SET '.$set. ' WHERE '.$this->table.'_id=?'; $sth = $db->prepare( $sql ); $db->execute( $sth, $values ); } function delete() { global $db; $sth = $db->prepare( 'DELETE FROM '.$this->table.' WHERE '. $this->table.'_id=?' ); $db->execute( $sth, array( $this->id ) ); } function delete_all() { global $db; $sth = $db->prepare( 'DELETE FROM '.$this->table ); $db->execute( $sth ); } } class Book extends DBObject { function __construct() { parent::__construct( 'book', array( 'author', 'title', 'publisher' ) ); } } $book = new Book( ); $book->delete_all(); $book->{'title'} = "PHP Hacks"; $book->{'author'} = "Jack Herrington"; $book->{'publisher'} = "O'Reilly"; $id = $book->insert(); echo ( "New book id = $id\n" ); $book->{'title'} = "Podcasting Hacks"; $book->update(); $book2 = new Book( ); $book2->load( $id ); echo( "Title = ".$book2->{'title'}."\n" ); $book2->delete( ); ?>
底部的测试代码只演示了这个语法干净了多少。要得到图书的书名,只需得到 title 成员变量。这个变量会调用对象的 __get 方法,在散列表中查找 title 条目并返回。
现在就得到了单个动态的数据库访问类,它能够让自己适应到数据库中的任何表。
回页首
动态类的更多用途
编写动态类不仅限于数据库访问。请看清单 8 中的 Customer 对象这个例子。
清单 8. 简单的 Customer 对象
<?php class Customer { private $name; function set_name( $value ) { $this->name = $value; } function get_name() { return $this->name; } } $c1 = new Customer(); $c1->set_name( "Jack" ); $name = $c1->get_name(); echo( "name = $name\n" ); ?>
这个对象足够简单。但是如果我想在每次检索或设置客户名称时都记录日志,会发生什么呢?我可以把这个对象包装在一个动态日志对象内,这个对象看起来像 Customer 对象,但是会把 get 或 set 操作的通知发送给日志。清单 9 显示了这类包装器对象。
清单 9. 动态包装器对象
<?php class Customer { private $name; function set_name( $value ) { $this->name = $value; } function get_name() { return $this->name; } } class Logged { private $obj; function __call( $method, $args ) { echo( "$method( ".join( ",", $args )." )\n" ); return call_user_func_array(array(&$this->obj, $method), $args ); } function __construct( $obj ) { $this->obj = $obj; } } $c1 = new Logged( new Customer() ); $c1->set_name( "Jack" ); $name = $c1->get_name(); echo( "name = $name\n" ); ?>
调用日志版本的 Customer 的代码看起来与前面相同,但是这时,对 Customer 对象的任何访问都被记入日志。清单 10 显示了运行这个日志版代码时输出的日志。
清单 10. 运行日志版对象
% php log2.php
set_name( Jack )
get_name( )
name = Jack
%
在这里,日志输出表明用参数 Jack 调用了set_name 方法。然后,调用 get_name 方法。最后,测试代码输出 get_name 调用的结果。
回页首
结束语
如果这个动态对象素材对您来说理解起来有点难,我不会责备您。因为我自己也花了不少时间研究它并使用代码才理解它并看出它的好处。
动态对象有许多功能,但是也有相当的风险。首先,在刚开始编写魔法方法时,类的复杂性显著增加。这些类更难理解、调试和维护。另外,因为集成开发环境(IDE)变得越来越智能,所以在处理动态类时它们也会遇到这类问题,因为当它们在类上查找方法时会找不到方法。
现在,并不是说应当避免编写这类代码。相反。我非常喜欢 PHP 的设计者这么有想法,把这些魔法方法包含在语言中,这样我们才能编写这类代码。但是重要的是,既要理解优点,也要理解不足。
当然,对于应用程序(例如数据库访问)来说,在这里介绍的技术 —— 与广泛流行的 Ruby on Rails 系统上使用的技术类似 —— 能够极大地减少用 PHP 实现数据库应用程序所需要的时间。节约时间总不是坏事。
发表评论
-
PHP+JavaScript 实现动态显示服务器端运行进度条(转)
2010-12-24 09:48 1728我有一个 PHP 程序,需要循环调用 XMLRPC 500 次 ... -
PHP采集程序中常用的函数(转)
2010-09-18 22:26 787//获得当前网址 function get_php_url( ... -
ecshop数据字典(五)---关于优惠活动和品牌
2010-09-18 22:08 1043促销活动 -- -- Table structure fo ... -
ecshop数据字典(四)--关于会员,会员等级积分以及订单
2010-09-18 22:04 1920会员表 -- -- Table structure for ... -
AJAX中文乱码PHP完美解决(IE和Firefox兼容)--转载
2010-09-18 21:54 1018最近在做一个项目,遇到AJAX中文乱码问题,经过一个下午的努力 ... -
php的错误和异常(转载)
2010-09-05 10:02 1172一个正规的程序或项目 ... -
ecshop数据字典(三)---关于搜索与属性
2010-08-15 08:06 1192-- -- 表的结构 `ecs_attribute` -- ... -
ecshop数据字典(二)
2010-08-15 08:05 1146<pre lang='sql' line='1'> ... -
ecshop的数据字典(一)
2010-08-15 08:04 1267-- -- 表的结构 `ecs_shop_config` ... -
UTC和GMT时间
2010-08-15 08:01 955每个地区都有自己的本地时间,在网上以及无线电通信中时间转 ... -
php时间戳的使用
2010-08-15 07:59 781说得通俗一些,时间戳就是根据当前系统时间生成的一组随机 ... -
php中正则的使用
2010-08-15 07:57 704正则表达式,作为一种 ... -
解决php中文乱码
2010-08-15 07:55 2863一.首先是PHP网页的编码 1.php文件本身的编码与网页的 ... -
关于php的缓存技术
2010-08-15 07:40 1075在比较大型的项目中, ... -
安装Apache+PHP在Windows+IIS下
2009-11-04 10:24 701Linux+Apache+PHP+MySQL是一个 ...
相关推荐
这个库提供了一种方便的方法,通过反射机制将属性值从DBObject填充到Java对象中。以下是一个简单的转换方法: ```java import org.apache.commons.beanutils.BeanUtils; import java.lang.reflect.InvocationTarget...
通达OA是一款在中国广泛应用的企业协同办公系统,而PHP OCI8是PHP的一个扩展,用于与Oracle数据库进行连接。当你遇到“通达oa加载扩展无法启动的dll php_oci8.dll”这样的错误时,这意味着在尝试运行通达OA的过程中...
在PHP中,类是一种组织代码的方式,它可以封装数据和方法,使得代码更加模块化和易于管理。MySQLi类封装意味着创建了一个新的类,该类扩展或包装了MySQLi的功能,提供了一种更高级、更方便的方式来处理数据库交互。 ...
PHP5的框架,可以自动创建映射数据库的类,并创建获取相关对象的方法。 不要再编写getter或setter的代码! 想象一下:$ client =&Client :: factory(4)...,而不必编写Client类。
数据库第三方操作类,封装了打开和关闭数据库连接
广告管理是jmzPHP中的一个重要组成部分,通过以下方法实现: - `adTypeInfo($type = null)`:返回广告类型的详细信息。 - `qualifying($type = null)`:用于广告查询,可以获取竞价排位和竞价状态。 - `listAD($num...
这些类将继承自一个基础的`DBObject`类,包含数据库字段对应的属性,以及CRUD(创建、读取、更新、删除)操作的方法。 3. **SQL构造**:为了封装SQL语句,phpDbObject可能有专门的类或方法来生成SQL查询,避免了硬...
查询文档时,`findOne()`方法用于获取单个文档,返回一个`DBObject`;而`find()`方法返回一个`DBCursor`,可以迭代处理多个文档。例如,`DBObject doc = coll.findOne();`将获取并打印出集合中的第一条文档。 这些...
DBOBject 使用 runtime fmdb 封装 1.自动建表 2.自动检查增删表字段 3.自定义数据库名,文件路径 4.支持一对一对象数据库存储 5.支持多路径,多数据库关联查询 6.一键保存、修改、删除、查找、...
`executeCommand`方法接受一个JSON字符串或`DBObject`对象,代表MongoDB命令。例如,执行`distinct`命令来获取集合中唯一的名字: ```java String jsonSql="{distinct:'person', key:'name'}"; CommandResult ...
3. 在`toString()`方法中,构建一个包含所有或部分属性值的字符串,方便在控制台输出或日志中查看`DBObject`的状态。 了解并正确实现这三个方法对于提升代码质量和维护性非常重要。特别是在处理集合、映射等数据...
不可能直接写那么多对象上去,所以模块封装一个可以动态创建对象的方法是很有必要的且此对象不单单用于数据库操作很多方面都可以用到这里就不单单举例了。 模块方法_DBMYSQL: 这是目前对mysql数据库DAO操作的方法,...
ORM 部分将 C++ 类映射到 SQL 数据库中的表: 数据库C++ 桌子班级柱子class' 属性(或 setter/getter 方法) 排类实例SQL 编写器帮助程序允许您在本机 C++ 中编写和执行 SQL 查询,该查询在编译时经过语法验证。...
// 更新或插入时,将JGeometry对象转回STRUCT STRUCT structForUpdate = geom.store(); } ``` Oracle Spatial Java API的文档(Javadoc)可在Oracle文档集合中找到,或者在Oracle安装目录的`$ORACLE_HOME/md/doc`...
4、使用一个用户自定义的类完成对一张数据库表的schema定义,继承一个DBObject或者 MultiDBObject类(这个名字学习自一个开源项目expresso,功能也类似),只要 定义好schema,也就是手动设定一下每个column的名称、...
MongoDB 是一个流行的开源、非关系型数据库系统,以其灵活性、高性能和易用性而闻名。在Java中使用MongoDB,我们需要引入相应的Java驱动程序,这些驱动程序提供了与MongoDB服务器交互的API。以下是关于MongoDB Java...
简介: 会有人问DAO数据库操作是什么意思,我这里就解释一下...不可能直接写那么多对象上去,所以模块封装一个可以动态创建对象的方法是很有必要的且此对象不单单用于数据库操作很多方面都可以用到这里就不单单举例了。
在AutoCAD中,CAdvBA(也称为AutoCAD VBA,Visual Basic for Applications)是一种强大的编程接口,允许用户通过编写VBA代码自定义AutoCAD的功能。这个“手动添加图元到选择集_cadvba_”的示例是关于如何利用CAdvBA...
MongoDB 是一个流行的开源NoSQL数据库,而Java Driver for MongoDB是官方提供的用于Java应用程序与MongoDB之间通信的库。在本文档中,我们将探讨如何使用Java驱动程序进行基本的MongoDB操作,包括连接、添加、更新、...
4、使用一个用户自定义的类完成对一张数据库表的schema定义,继承一个DBObject或者 MultiDBObject类(这个名字学习自一个开源项目expresso,功能也类似),只要 定义好schema,也就是手动设定一下每个column的名称、...