图 1. DAO Generator的体系结构:该图展示了用于PHP和MySQL的的DAO Generator的体系结构和数据流程
二、DAO类入门
下面简要介绍各种重要的DAO类:
- ConnectionFactory类:这个类与数据库密切相关。这个工厂类用于连接数据库,或者说打开一个数据库的连接。 连接数据库时,这个类要用到getConnection方法,该方法需要三个参数,分别对应于数据库名称、用户名和口令。这些参数将按照POJO的风格映射到类ConnectionProperty中。
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
static
public
function getConnection() {
$conn
=
mysql_connect(ConnectionProperty::getHost(),
ConnectionProperty::getUser(),
ConnectionProperty::getPassword());
mysql_select_db(ConnectionProperty::getDatabase());
if
(
!
$conn){
throw
new
Exception(
'
could not connect to database
'
);
}
return
$conn;
}
- Connection类:这个类代表的是单个数据库连接,该连接是通过Connection构造函数引自ConnectionFactory类的。
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
public
function Connection() {
$
this
->
connection
=
ConnectionFactory::getConnection();
}
这个类还负责关闭连接以及执行SQL查询。
- Transaction类:这个类封装了一组对数据库进行事务性操作的函数。此外,这个类还提供了事务数组,这些事务是通过助手类 ArrayList来提供的,其中ArrayList可以通过PHP数组来模拟一个集合。这些事务将使用Connection类所提供的连接。此 外,Transaction类的getCurrentTransaction函数提供了对当前事务的访问能力。
- QueryExecutor类:这个类为我们提供了执行SQL语句的各种函数。实际上,这些函数都实现了CRUD语法。函数execute可以执行所有的SELECT语句,而函数executeUpdate则执行UPDATE、DELETE和INSERT语句:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
public
static
function execute($sqlQuery){
$transaction
=
Transaction::getCurrentTransaction();
if
(
!
$transaction){
$connection
=
new
Connection();
}
else
{
$connection
=
$transaction
->
getConnection();
}
$query
=
$sqlQuery
->
getQuery();
$result
=
$connection
->
executeQuery($query);
if
(
!
$result){
throw
new
Exception(mysql_error());
}
$i
=
0
;
$tab
=
array();
while
($row
=
mysql_fetch_array($result)){
$tab[$i
++
]
=
$row;
}
mysql_free_result($result);
if
(
!
$transaction){
$connection
->
close();
}
return
$tab;
}
public
static
function executeUpdate($sqlQuery){
$transaction
=
Transaction::getCurrentTransaction();
if
(
!
$transaction){
$connection
=
new
Connection();
}
else
{
$connection
=
$transaction
->
getConnection();
}
$query
=
$sqlQuery
->
getQuery();
$result
=
$connection
->
executeQuery($query);
if
(
!
$result){
throw
new
Exception(mysql_error());
}
return
mysql_affected_rows();
}
- {databasename}MySqlDAO类:这是由DAO Generator创建的一个类,它提供了一组特定于某种数据库的DAO函数。生成的类位于generated/class/mysql文件夹内,并且它们的名称是由数据库名称和后缀MySqlDAO结合而成的。在本文的后面,我们将介绍如何生成和使用这个类。
注意,类QueryExecutor和类{databasename}MySqlDAO使用了一个名为SqlQuery的助手类,它封装有表示和存储 SQL语句的各种函数。
为了便于读者深入理解,我们下面将通过一个实例加以阐述。
三、生成DAO工件
下面我们说明一个使用名为bookstore的数据库的DAO工件的生成进程。该数据库含有一个表,表的名称为books,其结构如图2所示。
图 2. 表Books的结构:该图展示了数据库bookstore中的表Books中的一些样本数据及其结构
为了创建如图2所示的表,可以执行如下所示的SQL语句:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
create table books
(id
int
not
null
auto_increment primary key,
title varchar(
50
),
author varchar(
50
),
yearofpublication
int
,
publisher varchar(
50
),
price
int
);
生成该DAO工件之前,需要使用以下INSERT语句向表books中填入五条记录:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
insert into books values(
1
,
"
Annabel Lee
"
,
"
Edgar Allan Poe
"
,
1849
,
"
The Literature Page
"
,
256
);
insert into books values(
2
,
"
The Ballad of Reading Gaol
"
,
"
Oscar Wilde
"
,
1898
,
"
The Literature Page
"
,
475
);
insert into books values(
3
,
"
The Sonnets
"
,
"
Edgar Allan Poe
"
,
1602
,
"
The Literature Page
"
,
300
);
insert into books values(
4
,
"
Winnetow
"
,
"
Karl May
"
,
1956
,
"
The truth
"
,
123
);
insert into books values(
5
,
"
JBoss Tools 3
"
,
"
Anghel Leonard
"
,
2009
,
"
Packt
"
,
569
);
创建并填充好有关数据库和表之后,我们就可以执行DAO Generator来创建DAO工件了。若要运行该生成器,需要执行下列操作:
⒈ 在ConnectionProperty类中设置连接属性:host、user、password和database。
2. 运行generated.php脚本。
3. 我们将得到如下所示的输出结果:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
generated
/
class
/
dto
/
Books.
class
.php
varchar(
50
)
varchar(
50
)
varchar(
50
)
varchar(
50
)
int
(
11
)
int
(
11
)
varchar(
50
)
varchar(
50
)
int
(
11
)
int
(
11
)
generated
/
class
/
mysql
/
BooksMySqlDAO.
class
.php
varchar(
50
)
varchar(
50
)
int
(
11
)
varchar(
50
)
int
(
11
)
generated
/
class
/
dao
/
BooksDAO.
class
.php
generated
/
include_dao.php
generated
/
class
/
dao
/
DAOFactory.
class
.php
4. 输出结果中的最后三行是生成的类的名称,这些类被放入phpdao-1.7目录的新建子目录中。
为应用程序生成的这三个类都用到表books。第一个类位于generated/class/dto/Books.php文件中,它定义了一个表示表books的对象:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
<?
php
/**
* Object represents table 'books'
*
*
@author
:
http://phpdao.com
* @date: 2009-08-10 22:50
*/
class
Books{
var $id;
var $title;
var $author;
var $yearofpublication;
var $publisher;
var $price;
}
?>
第二个类位于generated/class/dao/BooksDAO.php文件中(请参阅清单1),它是一个接口,定义了针对表books的各种各样的操作。
第三个类,也是最后一个类位于/class/mysql/BooksMySqlDAO.php文件中,它实现了前面的接口。您可以在相应的文件夹中看到这个类,由于它很长,所以这里就不列出来了。
四、使用事务
本节展示如何使用PHP和MySQL的DAO Generator来创建一个事务。这里将要使用PHP和MySQL的DAO Generator来创建example.php脚本并将其放到generated文件夹中,其中generated文件夹中存放了所有的DAO文件。在本例中,我们的事务将生成两个SQL语句,即SELECT和DELETE语句:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
<?
php
//
包含所有的DAO文件
require_once(
'
include_dao.php
'
);
$transaction
=
new
Transaction();
//
将表清空
//
DAOFactory::getBooksDAO()->clean();
$transaction
->
rollback();
//
启动一个新的事务
$transaction
=
new
Transaction();
echo
'
****** Query All the books table ******
'
.
'
<br/>
'
;
$arr
=
DAOFactory::getBooksDAO()
->
queryAll();
for
($i
=
0
;$i
<
count($arr);$i
++
){
$row
=
$arr[$i];
echo $row
->
id.
'
'
.$row
->
title.
'
'
.$row
->
author.
'
'
.
$row
->
yearofpublication.
'
'
.$row
->
publisher.
'
'
.
$row
->
price.
'
<br/><br/>
'
;
}
echo
'
****** Deleting the third row ******
'
.
'
<br/>
'
;
$rowDeleted
=
DAOFactory::getBooksDAO()
->
delete(
3
);
echo
'
rows deleted =
'
.$rowDeleted.
'
<br/><br/>
'
;
echo
'
****** Loading the fifth row ******
'
.
'
<br/>
'
;
$art
=
DAOFactory::getBooksDAO()
->
load(
5
);
echo
'
Price for the fifth record book is =
'
.$art
->
price.
'
<br/><br/>
'
;
echo
'
****** Printing all rows order by title ******
'
.
'
<br/>
'
;
$article
=
DAOFactory::getBooksDAO()
->
queryAllOrderBy(
'
title
'
);
for
($i
=
0
;$i
<
count($article);$i
++
){
$row
=
$article[$i];
echo $row
->
id.
'
'
.$row
->
title.
'
'
.$row
->
author.
'
'
.
$row
->
yearofpublication.
'
'
.$row
->
publisher.
'
'
.
$row
->
price.
'
<br/><br/>
'
;
}
//
提交事务
$transaction
->
commit();
?>
当运行该例子时,将输出下列内容:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
******
Query All the books table
******
1
Annabel Lee Edgar Allan Poe
1849
The Literature Page
256
2
The Ballad of Reading Gaol Oscar Wilde
1898
The Literature Page
45
3
The Sonnets Edgar Allan Poe
1602
The Literature Page
300
4
Winnetow Karl May
1956
The truth
123
5
JBoos Tools
3
Anghel Leonard
2009
Packt
569
******
Deleting the third row
******
rows deleted
=
1
******
Loading the fifth row
******
Price
for
the fifth record book is
=
569
******
Printing all rows order by title
******
1
Annabel Lee Edgar Allan Poe
1849
The Literature Page
256
5
JBoos Tools
3
Anghel Leonard
2009
Packt
569
2
The Ballad of Reading Gaol Oscar Wilde
1898
The Literature Page
45
4
Winnetow Karl May
1956
The truth
123
五、新添加DAO函数
本节展示如何创建一个新的DAO函数,该函数用于打印出版日期介于1850到2009之间的所有记录。将其添加到BooksMySQLDAO.class.php中所有现有的query函数的后面:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
public
function queryByYear(){
$sql
=
"
SELECT * FROM books WHERE yearofpublication
"
.
"
BETWEEN '1850' AND '2009'
"
;
$sqlQuery
=
new
SqlQuery($sql);
return
$
this
->
getList($sqlQuery);
}
您也可以使用example.php页面来调用前面的函数,并打印yearofpublication介于1850到2009之间的记录:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
echo
"
****** Printing all rows where yearofpublication is between.
'
1850
'
and
'
2009
'
******
"
.'<br/>';
$arr
=
DAOFactory::getBooksDAO()
->
queryByYear();
for
($i
=
0
;$i
<
count($arr);$i
++
){
$row
=
$arr[$i];
echo $row
->
id.
'
'
.$row
->
title.
'
'
.$row
->
author.
'
'
.
$row
->
yearofpublication.
'
'
.$row
->
publisher.
'
'
.$row
->
price.
'
<br/><br/>
'
;
输出结果为:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
******
Printing all rows where yearofpublication is between
'
1850
'
AND
'
2009
'
******
2
The Ballad of Reading Gaol Oscar Wilde
1898
The Literature Page
45
4
Winnetow Karl May
1956
The truth
123
5
JBoss Tools
3
Anghel Leonard
2009
Packt
569
六、小结
我们已经学习了DAO机制的工作原理,包括使用工厂类模式生成指定数据库(bookstore)的DAO工件的过程,使用DAO generator工具及其工厂类创建应用程序的过程,创建一个数据库bookstore的事务过程,以及为生成的{databasename}MySqlDAO 类添加新的DAO函数的方法。当然,我们可以手工方式编程实现所有这些功能,但是最好将这些重复性的工作自动化,因为这样不仅能够降低出错率,而且还能节约宝贵的时间。