管理系统(DedeCMS)中,查询表找数据是开发过程中常见的操作,尤其是在二次开发或自定义功能时,织梦基于PHP和MySQL数据库,其数据查询主要通过原生SQL语句或封装好的类方法实现,以下是详细的操作方法和注意事项。

理解织梦数据库结构
织梦的数据库表前缀默认为dede_(可在安装时修改),核心表包括:
dede_archives:文章主表,存储文章ID、标题、发布时间等基本信息。dede_addonarticle:文章附加表,存储文章内容、关键字等字段(需与archives表关联)。dede_arctype:栏目表,存储栏目名称、父栏目ID等信息。dede_admin:管理员表,存储账号和密码。dede_member:会员表,存储会员信息。
查询数据前需明确目标字段所在的表,必要时通过JOIN关联多表。
直接使用SQL查询
通过$dsql执行SQL
织梦提供了全局数据库对象$dsql(基于dedesql类),可直接执行SQL语句,例如查询文章标题和内容:
$sql = "SELECT a.title, b.body FROM dede_archives a LEFT JOIN dede_addonarticle b ON a.id = b.aid WHERE a.typeid = 1";
$row = $dsql->GetOne($sql); // 获取单条记录
echo $row['title'] . ": " . $row['body'];
// 获取多条记录
$dsql->Execute('me', $sql);
while ($row = $dsql->GetArray('me')) {
echo $row['title'] . "<br>";
}
使用query和GetArray方法
$dsql->Execute('别名', SQL):执行查询并返回结果集。$dsql->GetArray('别名'):循环获取结果集为数组。$dsql->GetOne(SQL):直接获取第一条记录。
注意事项
- 防止SQL注入:对用户输入的变量使用
$dsql->EscapeString()过滤。 - 表前缀动态获取:通过
$dsql->dbNamePrefix变量获取当前前缀,避免硬编码。
使用织梦封装的查询方法
织梦对常用查询提供了封装方法,简化操作。

查询单条记录(GetOne)
$row = $dsql->GetOne("SELECT * FROM dede_archives WHERE id = 10");
if ($row) {
echo $row['title'];
}
查询多条记录(Execute和GetArray)
$dsql->SetQuery("SELECT title, pubdate FROM dede_archives ORDER BY pubdate DESC");
$dsql->Execute();
while ($row = $dsql->GetArray()) {
echo $row['title'] . " - " . date('Y-m-d', $row['pubdate']) . "<br>";
}
使用SelectSql构建查询
$sql = $dsql->SelectSql('dede_archives', 'title, typeid', "typeid IN (1, 2) AND arcrank > 0");
$dsql->Execute('me', $sql);
while ($row = $dsql->GetArray('me')) {
echo $row['title'];
}
关联查询示例
假设需要查询文章标题及其所属栏目名称,需关联archives和arctype表:
$sql = "SELECT a.title, t.typename
FROM dede_archives a
LEFT JOIN dede_arctype t ON a.typeid = t.id
WHERE a.arcrank = 0";
$dsql->Execute('me', $sql);
while ($row = $dsql->GetArray('me')) {
echo $row['title'] . "(栏目:" . $row['typename'] . ")<br>";
}
常用查询场景与代码
分页查询
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
$pageSize = 10;
$offset = ($page - 1) * $pageSize;
$sql = "SELECT * FROM dede_archives ORDER BY id DESC LIMIT $offset, $pageSize";
$dsql->Execute('me', $sql);
while ($row = $dsql->GetArray('me')) {
echo $row['title'] . "<br>";
}
条件查询
$keyword = $dsql->GetFilter("keyword");
$sql = "SELECT * FROM dede_archives WHERE title LIKE '%$keyword%'";
统计查询
$count = $dsql->GetOne("SELECT COUNT(*) AS total FROM dede_archives");
echo "总文章数:" . $count['total'];
调试与错误处理
- 开启调试模式:在
include/config_base.php中设置$cfg_debug = true,可查看SQL执行错误。 - 错误捕获:通过
$dsql->GetError()获取错误信息。
性能优化建议
- 避免全表扫描:查询时尽量使用
WHERE和ORDER BY。 - 合理使用索引:对常用查询字段(如
typeid、pubdate)建立索引。 - 减少查询次数:使用
JOIN替代多次单表查询。
相关问答FAQs
问题1:织梦查询时如何避免SQL注入?
解答:织梦的$dsql类已内置防注入机制,但仍建议对用户输入进行过滤。
$keyword = $dsql->GetFilter($_GET['keyword']); // 自动过滤危险字符 $sql = "SELECT * FROM dede_archives WHERE title LIKE '%$keyword%'";
避免直接拼接SQL语句,使用参数化查询(如$dsql->Execute('me', "SELECT * FROM table WHERE id=?", array($id)))。
问题2:如何查询指定栏目下的所有文章(包括子栏目)?
解答:需先获取所有子栏目ID,再查询文章。

$topid = 1; // 父栏目ID
$sids = GetSonIds($topid); // 调用织梦内置函数获取子栏目ID
$sql = "SELECT * FROM dede_archives WHERE typeid IN ($sids)";
$dsql->Execute('me', $sql);
while ($row = $dsql->GetArray('me')) {
echo $row['title'] . "<br>";
}
其中GetSonIds()是织梦的递归函数,用于获取指定ID下的所有子栏目ID。
