DouPHP DbMysql 数据库类使用手册
发布时间:2026-02-07点击数:43
# DbMysql 数据库类使用手册
## 目录
1. [简介](#简介)
2. [连接数据库](#连接数据库)
3. [基础查询方法](#基础查询方法)
4. [链式查询方法](#链式查询方法)
5. [高级查询功能](#高级查询功能)
6. [聚合函数](#聚合函数)
7. [事务和锁](#事务和锁)
8. [SQL调试](#sql调试)
9. [实用方法](#实用方法)
10. [常见问题](#常见问题)
## 简介
DbMysql 是一个功能强大的 MySQL 数据库操作类,支持链式查询、预处理语句、事务处理等特性。本类设计采用流畅的链式查询语法,易于上手和维护。
### 主要特性
- 安全的预处理语句(防 SQL 注入)
- 流畅的链式查询语法
- 支持 JOIN、UNION、GROUP BY 等复杂查询
- 分页查询功能
- 事务支持和锁机制
- 完善的调试功能
## 连接数据库
### 基本连接
```php
// 导入数据库类
require_once 'DbMysql.php';
// 创建数据库连接
$db = new DbMysql(
'localhost:3306', // 数据库主机(可包含端口)
'username', // 数据库用户名
'password', // 数据库密码
'database_name', // 数据库名
'dou_', // 表前缀
'utf8mb4' // 字符集
);
// 测试连接
if ($db->version()) {
echo '数据库连接成功!';
}
```
### 连接参数说明
| 参数 | 说明 | 是否必需 |
| ------------- | -------------------------------------- | -------- |
| $dbhost | 数据库主机,支持端口格式 `host:port` | 是 |
| $dbuser | 数据库用户名 | 是 |
| $dbpass | 数据库密码 | 是 |
| $dbname | 数据库名 | 否 |
| $prefix | 表前缀 | 否 |
| $charset | 字符集(utf8/utf8mb4/gbk等) | 否 |
| $skip_connect | 是否跳过自动连接(用于克隆) | 否 |
## 基础查询方法
### 执行原生 SQL
```php
// 执行查询
$result = $db->query("SELECT * FROM dou_user WHERE id = 1");
// 获取一行数据
$row = $db->fetch_assoc($result);
// 获取所有数据
$data = $db->fn_query("SELECT * FROM dou_user");
// 执行更新/删除
$db->query("UPDATE dou_user SET name = '张三' WHERE id = 1");
// 获取单个值
$count = $db->get_one("SELECT COUNT(*) FROM dou_user");
```
### 常用快捷方法
```php
// 获取单条记录
$user = $db->get_row('user', 'id,name', 'id = 1');
// 获取单个字段值
$name = $db->get_value('user', 'name', 'id = 1');
// 判断记录是否存在
if ($db->row_exist('user', 'email = "admin@example.com"')) {
echo '邮箱已存在';
}
// 统计数量
$count = $db->row_number('user', 'status = 1');
// 获取下一个自增ID
$next_id = $db->auto_id('user');
```
## 链式查询方法
### 开始查询
```php
// 开始一个新的查询(推荐方式,避免状态污染)
$query = $db->table('user');
// 或使用传统方式
$db->table('user'); // 直接操作原对象
```
### 查询条件(WHERE)
```php
// 简单条件
$db->table('user')
->where('id', 1)
->select();
// 多个条件
$db->table('user')
->where('status', 1)
->where('age', '>', 18)
->select();
// OR 条件
$db->table('user')
->where('status', 1)
->where_or('vip', 1)
->select();
// IN 查询
$db->table('user')
->where('id', 'IN', [1, 2, 3, 4])
->select();
// LIKE 查询
$db->table('user')
->where('name', 'LIKE', '%张%')
->select();
// BETWEEN 查询(通过两个条件实现)
$db->table('user')
->where('age', '>=', 18)
->where('age', '<=', 30)
->select();
// NULL 查询
$db->table('user')
->where('deleted_at', 'IS', null)
->select();
// 闭包查询(复杂条件)
$db->table('user')
->where(function($query) {
$query->where('status', 1)
->where_or('vip', 1);
})
->select();
```
### 字段选择
```php
// 选择所有字段
$db->table('user')->select();
// 选择特定字段
$db->table('user')
->field('id, name, email')
->select();
// 使用数组选择字段
$db->table('user')
->field(['id', 'name', 'email'])
->select();
// 字段别名
$db->table('user')
->field('id as user_id, name as user_name')
->select();
// 聚合函数
$db->table('user')
->field('COUNT(*) as count, AVG(age) as avg_age')
->select();
```
### 排序和限制
```php
// 排序
$db->table('user')
->order('id DESC')
->select();
// 多字段排序
$db->table('user')
->order('status DESC, id ASC')
->select();
// 限制数量
$db->table('user')
->limit(10)
->select();
// 分页查询(offset, limit)
$db->table('user')
->limit(0, 10) // 第一页,每页10条
->select();
// 使用 offset 方法
$db->table('user')
->offset(10) // 跳过前10条
->limit(20) // 取20条
->select();
```
### 连表查询(JOIN)
```php
// LEFT JOIN
$db->table('user u')
->join('user_profile p', 'u.id = p.user_id')
->field('u.*, p.avatar, p.bio')
->select();
// INNER JOIN
$db->table('order o')
->inner_join('user u', 'o.user_id = u.id')
->select();
// RIGHT JOIN
$db->table('department d')
->right_join('employee e', 'd.id = e.department_id')
->select();
// 多个 JOIN
$db->table('order o')
->join('user u', 'o.user_id = u.id')
->join('product p', 'o.product_id = p.id')
->select();
```
### 分组查询(GROUP BY)
```php
// 基本分组
$db->table('order')
->field('user_id, COUNT(*) as order_count')
->group_by('user_id')
->select();
// 分组后条件(HAVING)
$db->table('order')
->field('user_id, SUM(amount) as total_amount')
->group_by('user_id')
->having('total_amount', '>', 1000)
->select();
// 复杂 HAVING 条件
$db->table('order')
->field('product_id, AVG(price) as avg_price')
->group_by('product_id')
->having('AVG(price)', '>', 100)
->having_or('COUNT(*)', '>', 10)
->select();
```
### 去重查询
```php
// DISTINCT 查询
$db->table('user')
->distinct()
->field('city')
->select();
```
### UNION 查询
```php
// 单个 UNION
$query1 = $db->table('user')->field('id, name');
$query2 = $db->table('admin')->field('id, name');
$db->table('user')
->field('id, name')
->union($query2)
->select();
// UNION ALL
$db->table('user')
->field('id, name')
->union($query2, true) // true 表示 UNION ALL
->select();
```
### 聚合查询快捷方法
```php
// 单条记录查询
$user = $db->table('user')
->where('id', 1)
->find();
// 获取单个字段值
$name = $db->table('user')
->where('id', 1)
->value('name');
// 判断记录是否存在
$exists = $db->table('user')
->where('email', 'test@example.com')
->exists();
// 统计数量(链式)
$count = $db->table('user')
->where('status', 1)
->count();
```
### 插入数据
```php
// 插入单条数据
$data = [
'name' => '张三',
'email' => 'zhangsan@example.com',
'age' => 25,
'created_at' => date('Y-m-d H:i:s')
];
// 方式1:链式插入
$insert_id = $db->table('user')
->data($data)
->insert();
// 方式2:直接插入
$insert_id = $db->table('user')->insert($data);
// 批量插入
$data_list = [
['name' => '李四', 'email' => 'lisi@example.com'],
['name' => '王五', 'email' => 'wangwu@example.com'],
['name' => '赵六', 'email' => 'zhaoliu@example.com']
];
$affected_rows = $db->table('user')
->insert_all($data_list);
```
### 更新数据
```php
// 更新数据
$data = [
'name' => '张三丰',
'age' => 30,
'updated_at' => date('Y-m-d H:i:s')
];
// 方式1:链式更新
$affected_rows = $db->table('user')
->where('id', 1)
->data($data)
->update();
// 方式2:直接更新
$affected_rows = $db->table('user')
->where('id', 1)
->update($data);
// 更新单个字段
$affected_rows = $db->table('user')
->where('id', 1)
->set_field('status', 2);
// 字段自增
$affected_rows = $db->table('user')
->where('id', 1)
->inc('view_count', 1); // view_count = view_count + 1
// 字段自减
$affected_rows = $db->table('user')
->where('id', 1)
->dec('balance', 100); // balance = balance - 100
// 字段运算
$affected_rows = $db->table('product')
->where('id', 1)
->exp('price', '*', 0.9); // price = price * 0.9
```
### 删除数据
```php
// 删除数据
$affected_rows = $db->table('user')
->where('id', 1)
->delete();
// 删除多条数据
$affected_rows = $db->table('user')
->where('status', 0)
->delete();
```
## 高级查询功能
### 分页查询
```php
// 基本分页
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
$result = $db->table('user')
->where('status', 1)
->paginate(15, $page, '/user/list');
// 结果结构
// $result = [
// 'list' => [...], // 当前页数据
// 'pager' => [ // 分页信息
// 'record_count' => 100,
// 'page_size' => 15,
// 'page' => 1,
// 'page_count' => 7,
// 'first' => '/user/list?page=1',
// 'previous' => '/user/list?page=1',
// 'next' => '/user/list?page=2',
// 'last' => '/user/list?page=7',
// 'box' => [...] // 页码导航
// ]
// ];
// 带参数的分页
$result = $db->table('user')
->where('status', 1)
->paginate(15, $page, '/user/list', 'type=member&category=1');
```
### 锁机制
```php
// 共享锁(读锁)
$db->table('user')
->where('id', 1)
->lock_shared()
->select(); // SELECT ... LOCK IN SHARE MODE
// 排他锁(写锁)
$db->table('user')
->where('id', 1)
->lock_for_update()
->select(); // SELECT ... FOR UPDATE
```
## 聚合函数
### 链式聚合方法
```php
// 求和
$total = $db->table('order')
->where('status', 2)
->sum('amount');
// 平均值
$average = $db->table('user')
->where('age', '>', 0)
->avg('age');
// 最大值
$max = $db->table('product')
->max('price');
// 最小值
$min = $db->table('product')
->min('price');
// 计数
$count = $db->table('user')
->where('status', 1)
->count();
```
## 事务和锁
### 事务处理
```php
// 开始事务
$db->query("START TRANSACTION");
try {
// 执行多个操作
$db->table('account')
->where('id', 1)
->dec('balance', 100)
->update();
$db->table('account')
->where('id', 2)
->inc('balance', 100)
->update();
// 提交事务
$db->query("COMMIT");
echo "转账成功";
} catch (Exception $e) {
// 回滚事务
$db->query("ROLLBACK");
echo "转账失败:" . $e->getMessage();
}
```
## SQL调试
### 获取SQL语句
```php
// 获取最后执行的SQL(带参数)
$sql = $db->debug();
// 示例: SELECT * FROM `dou_user` WHERE `id` = 1
// 获取构建的SQL(不执行)
$sql = $db->table('user')
->where('id', 1)
->fetch_sql() // 设置为只获取SQL模式
->select(); // 返回SQL字符串,不执行
// 获取最后构建的SQL(任意时间)
$sql = $db->get_sql();
```
### 调试示例
```php
// 调试插入语句
$sql = $db->table('user')
->fetch_sql()
->insert(['name' => '测试', 'age' => 20]);
// 调试更新语句
$sql = $db->table('user')
->where('id', 1)
->fetch_sql()
->update(['name' => '新名称']);
// 调试删除语句
$sql = $db->table('user')
->where('id', 1)
->fetch_sql()
->delete();
// 调试复杂查询
$sql = $db->table('user u')
->join('profile p', 'u.id = p.user_id')
->where('u.status', 1)
->where('p.age', '>', 18)
->field('u.name, p.address')
->order('u.id DESC')
->limit(10)
->fetch_sql()
->select();
```
## 实用方法
### 表操作
```php
// 检查表是否存在
if ($db->table_exist('user')) {
echo 'user表存在';
}
// 检查字段是否存在
if ($db->field_exist('user', 'email')) {
echo 'email字段存在';
}
// 检查唯一索引
if ($db->has_unique_index('user', 'email')) {
echo 'email字段有唯一索引';
}
// 检查值是否已存在
if ($db->value_exist('user', 'email', 'test@example.com')) {
echo '邮箱已存在';
}
```
### 数据库信息
```php
// 获取数据库版本
$version = $db->version();
// 获取字符集
$charset = $db->charset();
// 获取最后插入的ID
$last_id = $db->insert_id();
// 获取受影响的行数
$affected = $db->affected_rows();
```
### SQL导入
```php
// 导入SQL文件
$sql = file_get_contents('backup.sql');
$db->fn_execute($sql);
```
## 常见问题
### 1. 链式查询状态问题
```php
// 注意:每次查询后状态会自动重置
$data1 = $db->table('user')->where('status', 1)->select();
// 这里需要重新开始查询
$data2 = $db->table('user')->where('vip', 1)->select();
```
### 2. 表前缀处理
```php
// 所有表名会自动添加前缀
$db->table('user'); // 实际查询的是 `dou_user` 表
// 使用 get_table_name 方法获取完整表名
$table_name = $db->get_table_name('user'); // 返回 `dou_user`
```
### 3. 参数绑定安全
```php
// 不安全:直接拼接SQL(不要这样做)
$name = $_GET['name'];
$db->query("SELECT * FROM user WHERE name = '$name'"); // SQL注入风险!
// 安全:使用预处理语句(自动处理)
$db->table('user')
->where('name', $_GET['name']) // 自动参数绑定
->select();
```
### 4. 性能优化建议
```php
// 1. 使用 limit 限制数据量
$db->table('log')->limit(1000)->select();
// 2. 只选择需要的字段
$db->table('user')->field('id, name')->select();
// 3. 合理使用索引字段作为条件
// 4. 避免在循环中查询数据库
// 不好
foreach ($user_ids as $id) {
$db->table('user')->where('id', $id)->find();
}
// 更好
$db->table('user')->where('id', 'IN', $user_ids)->select();
```
### 5. 错误处理
```php
try {
$result = $db->table('user')->where('id', 1)->select();
if ($result === false) {
// 查询失败处理
throw new Exception('查询失败');
}
// 处理结果
foreach ($result as $row) {
// ...
}
} catch (Exception $e) {
// 记录日志或显示错误信息
error_log('数据库错误: ' . $e->getMessage());
// 开发环境显示错误
if (defined('DEBUG') && DEBUG) {
echo '数据库错误: ' . $e->getMessage();
}
}
```
### Q1: 如何关闭表前缀?
```php
// 在实例化时不传前缀参数
$db = new DbMysql('localhost', 'user', 'pass', 'dbname');
```
### Q2: 如何执行多条 SQL 语句?
```php
// 使用 multi_query 方法
$sql = "
UPDATE user SET status = 1 WHERE id = 1;
UPDATE user SET status = 0 WHERE id = 2;
";
$db->multi_query($sql);
```
### Q3: 如何获取查询的字段信息?
```php
$result = $db->query("SELECT * FROM user LIMIT 1");
$field_count = $db->num_fields($result);
```
### Q4: 如何处理大数据量查询?
```php
// 使用分批处理
$page = 1;
$page_size = 1000;
do {
$offset = ($page - 1) * $page_size;
$data = $db->table('large_table')
->limit($offset, $page_size)
->select();
// 处理数据
foreach ($data as $row) {
// ...
}
$page++;
} while (!empty($data));
```
---
**版本**: 1.0
**最后更新**: 2026-01-29
**作者**: DouCo Co.,Ltd.
**技术支持**: http://www.douphp.com