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