这个过程的核心在于理解织梦数据库的表结构,并使用正确的SQL查询语句来获取数据。

(图片来源网络,侵删)
下面我将分步详细讲解如何操作,从基础到进阶,并提供代码示例。
第一步:了解织梦数据库的核心表结构
织梦的数据库设计虽然不算非常规范,但只要掌握了几个核心表,就能完成大部分文章读取任务。
假设你的数据库名为 dedecmsv57,以下是最重要的几个表:
-
dede_archives- 文章主表
(图片来源网络,侵删)- 这是文章的核心信息表,存储了每一篇文章最基本、最重要的数据。
- 关键字段:
id: 文章的唯一ID,主键。typeid: 文章所属的栏目ID (对应dede_arctype表的id)。typeid2: 文章的副栏目ID。arcrank: 文章状态(-1为审核通过,0为待审核,>0为审核级别)。click: 点击量。title: 文章标题。senddate: 发布时间(Unix时间戳格式)。pubdate: 发布时间(Unix时间戳格式,通常和senddate一样)。description:writer: 作者。source: 来源。litpic: 文章缩略图。
-
dede_arctype- 栏目表- 存储了网站所有的栏目信息。
- 关键字段:
id: 栏目ID,主键。typename: 栏目名称。typedir: 栏目目录(用于生成URL)。reid: 上级栏目ID(0表示顶级栏目)。
-
dede_addonarticle- 文章附加表- 这是织梦使用“附加表”来存储文章内容的地方,为了优化主表性能,文章正文内容不放在
archives表里,而是存放在这里。 - 关键字段:
aid: 文章ID,与dede_archives表的id字段关联。body: 文章的完整HTML内容。
- 这是织梦使用“附加表”来存储文章内容的地方,为了优化主表性能,文章正文内容不放在
核心关系:
dede_archives.id == dede_addonarticle.aid
要获取一篇文章的完整信息(标题、正文等),你需要同时查询 archives 和 addonarticle 这两个表。
第二步:准备数据库连接信息
在从外部读取数据之前,你需要确保你知道以下信息:
- 数据库主机名 (通常是
localhost) - 数据库名称
- 数据库用户名
- 数据库密码
- 数据库前缀 (默认是
dede_,如果你的安装时修改了,请务必使用你自己的前缀)
第三步:编写代码进行读取
下面我将提供几种不同编程语言的示例代码,这些代码都遵循一个基本逻辑:
- 连接到数据库。
- 编写SQL查询语句,联合查询
archives和addonarticle表。 - 执行查询并获取结果。
- 关闭数据库连接。
SQL查询语句示例
假设我们要读取所有“已审核”的文章,并按发布时间倒序排列,SQL语句如下:
SELECT
a.id,
a.typeid,
t.typename AS typename,
a.title,
a.description,
a.litpic,
a.senddate,
aa.body
FROM
dede_archives AS a
LEFT JOIN
dede_arctype AS t ON a.typeid = t.id
LEFT JOIN
dede_addonarticle AS aa ON a.id = aa.aid
WHERE
a.arcrank = -1 -- 只读取审核通过的文章
ORDER BY
a.senddate DESC; -- 按发布时间倒序
语句解释:
FROM dede_archives AS a: 指定主表并起别名a。LEFT JOIN ... ON ...: 将archives表与arctype和addonarticle表通过关联字段连接起来,一次性获取所有需要的数据。WHERE a.arcrank = -1: 这是一个重要的过滤条件,避免读取到草稿或待审核的文章。ORDER BY a.senddate DESC: 对结果进行排序,最新的文章排在前面。
代码示例
示例1:使用 PHP 读取
这是最常见的情况,因为织梦本身就是PHP系统。
<?php
// --- 1. 数据库配置 ---
$db_host = 'localhost';
$db_user = 'your_db_user';
$db_pass = 'your_db_password';
$db_name = 'your_db_name';
$db_prefix = 'dede_'; // 你的表前缀
// --- 2. 连接数据库 ---
$conn = new mysqli($db_host, $db_user, $db_pass, $db_name);
// 检查连接是否成功
if ($conn->connect_error) {
die("数据库连接失败: " . $conn->connect_error);
}
// 设置字符集为 utf8mb4,以支持emoji等特殊字符
$conn->set_charset("utf8mb4");
// --- 3. 编写并执行SQL查询 ---
$sql = "SELECT
a.id, a.title, a.description, a.litpic, a.senddate,
t.typename,
aa.body
FROM
" . $db_prefix . "archives AS a
LEFT JOIN
" . $db_prefix . "arctype AS t ON a.typeid = t.id
LEFT JOIN
" . $db_prefix . "addonarticle AS aa ON a.id = aa.aid
WHERE
a.arcrank = -1
ORDER BY
a.senddate DESC
LIMIT 10"; // 只读取最新的10条
$result = $conn->query($sql);
// --- 4. 处理查询结果 ---
$articles = [];
if ($result && $result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
// 将时间戳转换为可读格式
$row['formatted_date'] = date('Y-m-d H:i:s', $row['senddate']);
$articles[] = $row;
}
}
// --- 5. 关闭数据库连接 ---
$conn->close();
// --- 6. 输出结果 (这里以JSON格式为例,方便其他程序调用) ---
header('Content-Type: application/json; charset=utf-8');
echo json_encode($articles, JSON_UNESCAPED_UNICODE);
?>
示例2:使用 Python 读取
如果你使用Python来处理数据,可以使用 pymysql 或 mysql-connector-python 库。
首先安装库:
pip install pymysql
import pymysql
import json
from datetime import datetime
# --- 1. 数据库配置 ---
db_config = {
'host': 'localhost',
'user': 'your_db_user',
'password': 'your_db_password',
'database': 'your_db_name',
'charset': 'utf8mb4',
'cursorclass': pymysql.cursors.DictCursor # 以字典形式返回结果,更方便
}
# --- 2. 连接数据库并执行查询 ---
try:
connection = pymysql.connect(**db_config)
with connection.cursor() as cursor:
# --- 3. 编写SQL查询 ---
sql = """
SELECT
a.id, a.title, a.description, a.litpic, a.senddate,
t.typename,
aa.body
FROM
dede_archives AS a
LEFT JOIN
dede_arctype AS t ON a.typeid = t.id
LEFT JOIN
dede_addonarticle AS aa ON a.id = aa.aid
WHERE
a.arcrank = -1
ORDER BY
a.senddate DESC
LIMIT 10
"""
cursor.execute(sql)
# --- 4. 获取所有结果 ---
articles = cursor.fetchall()
# 处理时间戳,转换为字符串
for article in articles:
article['senddate'] = datetime.fromtimestamp(article['senddate']).strftime('%Y-%m-%d %H:%M:%S')
# --- 5. 输出结果 ---
print(json.dumps(articles, ensure_ascii=False))
finally:
# --- 6. 关闭连接 ---
if connection:
connection.close()
示例3:使用 Node.js (JavaScript) 读取
在Node.js中,你可以使用 mysql2 或 mysql 库。
首先安装库:
npm install mysql2
const mysql = require('mysql2/promise');
const { format } = require('date-fns'); // 需要安装 date-fns: npm install date-fns
// --- 1. 数据库配置 ---
const db_config = {
host: 'localhost',
user: 'your_db_user',
password: 'your_db_password',
database: 'your_db_name',
charset: 'utf8mb4'
};
// --- 2. 连接数据库并执行查询 ---
async function getArticles() {
let connection;
try {
connection = await mysql.createConnection(db_config);
// --- 3. 编写SQL查询 ---
const sql = `
SELECT
a.id, a.title, a.description, a.litpic, a.senddate,
t.typename,
aa.body
FROM
dede_archives AS a
LEFT JOIN
dede_arctype AS t ON a.typeid = t.id
LEFT JOIN
dede_addonarticle AS aa ON a.id = aa.aid
WHERE
a.arcrank = -1
ORDER BY
a.senddate DESC
LIMIT 10
`;
// --- 4. 执行查询 ---
const [rows, fields] = await connection.execute(sql);
// 处理时间戳
const articles = rows.map(row => {
row.senddate = format(new Date(row.senddate * 1000), 'yyyy-MM-dd HH:mm:ss');
return row;
});
// --- 5. 输出结果 ---
console.log(JSON.stringify(articles, null, 2));
} catch (error) {
console.error('Error:', error);
} finally {
// --- 6. 关闭连接 ---
if (connection) {
await connection.end();
}
}
}
getArticles();
第四步:高级技巧与注意事项
-
处理分页: 当文章很多时,不能一次性全部读取,你需要使用
LIMIT和OFFSET来实现分页。LIMIT: 每页显示的数量。OFFSET: 跳过的记录数。- 公式:
OFFSET = (页码 - 1) * 每页数量 - SQL示例:
SELECT ... LIMIT 10 OFFSET 20;(获取第3页,每页10条数据)
-
处理不同模型的文章: 织梦支持多种文章模型(比如普通文章、图集、软件等),它们的附加表是不同的。
- 普通文章:
dede_addonarticle - 图集:
dede_addonimages - 软件下载:
dede_addonsoft - 在
dede_archives表中有一个channel字段,可以用来判断文章属于哪个模型,你需要根据这个字段的值来动态连接不同的附加表。
- 普通文章:
-
性能优化:
- 索引: 确保
dede_archives表的typeid,arcrank,senddate等字段有索引,这会极大提升查询速度。 - 只查询需要的字段: 避免使用
SELECT *,明确列出你需要的字段,可以减少数据传输量。 - 缓存: 如果读取的数据不要求实时性,可以将读取到的数据缓存起来(比如用Redis、Memcached或文件缓存),以减轻数据库压力。
- 索引: 确保
-
安全性:
- 绝对不要将数据库密码等敏感信息硬编码在代码中,尤其是在公网环境下,应该使用环境变量或配置文件来管理。
- 如果你的查询条件来自用户输入(通过URL参数传递栏目ID),务必对输入进行验证和过滤,防止SQL注入攻击,上面的PHP示例使用了预处理语句(
prepare和execute),这是防止SQL注入的最佳实践,在Python和Node.js的示例中,cursor.execute()和connection.execute()也内置了类似的安全机制。
通过以上步骤和示例,你应该能够成功地从外部读取织梦数据库中的文章了。
