数据库 — MySQL
Finch 提供三层 MySQL 架构:MTable/MField 用于模式定义,Sqler 用于构建查询,DatabaseDriver 用于执行。
配置
FinchConfigs(
mysqlConfig: FinchMysqlConfig(
enable: true,
host: env['MYSQL_HOST'] ?? 'localhost',
port: (env['MYSQL_PORT'] ?? '3306').toInt(def: 3306),
user: env['MYSQL_USER'] ?? 'db_user',
pass: env['MYSQL_PASS'] ?? 'db_password',
databaseName: env['MYSQL_DATABASE'] ?? 'my_db',
),
)
表定义
使用 MTable 和 MField* 类型定义表:
// lib/db/tables.dart
import 'package:finch/finch_mysql.dart';
MTable usersTable = MTable(
tableName: 'users',
fields: [
MFieldId(), // PRIMARY KEY AUTO_INCREMENT
MFieldString(name: 'name', length: 100),
MFieldString(name: 'email', length: 255, unique: true),
MFieldString(name: 'password_hash', length: 255),
MFieldBool(name: 'is_active', defaultValue: true),
MFieldTimestamp(name: 'created_at', defaultNow: true),
],
);
MField 类型
| 类型 | SQL 等效 | 关键属性 |
|---|---|---|
MFieldId() |
INT PRIMARY KEY AUTO_INCREMENT |
— |
MFieldString |
VARCHAR(n) |
length、unique、nullable |
MFieldText |
TEXT |
nullable |
MFieldInt |
INT |
defaultValue、nullable |
MFieldBool |
TINYINT(1) |
defaultValue |
MFieldDouble |
DOUBLE |
defaultValue |
MFieldTimestamp |
TIMESTAMP |
defaultNow |
MFieldJson |
JSON |
— |
MFieldForeignKey |
INT + FOREIGN KEY |
references、onDelete |
使用 Sqler 进行查询
SELECT
var sqler = Sqler(table: usersTable);
// 获取所有活跃行
var rows = await sqler
.where('is_active', '=', true)
.orderBy('created_at', desc: true)
.limit(20)
.get();
INSERT
var id = await sqler.insert({
'name': 'Ali',
'email': '[email protected]',
'password_hash': hashPassword(password),
'is_active': true,
});
UPDATE
await sqler
.where('id', '=', userId)
.update({'name': 'Ali Ahmadi'});
DELETE
await sqler
.where('id', '=', userId)
.delete();
GROUP BY 和 HAVING
var stats = await sqler
.select(['role', 'COUNT(*) as count'])
.groupBy('role')
.having('count', '>', 5)
.get();
结果处理
// 获取 Map 列表
List<Map<String, dynamic>> rows = await sqler.get();
// 获取单行
Map<String, dynamic>? row = await sqler.first();
// 检查行是否存在
bool exists = await sqler.where('email', '=', email).exists();
// 计数
int count = await sqler.where('is_active', '=', true).count();
原始 DatabaseDriver
用于原始 SQL:
var db = DatabaseDriver();
var results = await db.query('SELECT * FROM users WHERE id = ?', [userId]);