1. 开篇:Dart的后端潜力
作为谷歌亲儿子,Dart语言早已突破Flutter的边界,在后端领域崭露头角。当我们用Dart构建后端服务时,数据库连接就像给汽车安装发动机——选对引擎才能跑得又快又稳。本文将以实际代码示例,带你看懂Dart如何驾驭PostgreSQL、MongoDB、MySQL、Redis和SQLite五大数据库。
2. PostgreSQL连接实战
2.1 技术栈选择
使用官方推荐的postgres
包(pub.dev/packages/postgres)
import 'package:postgres/postgres.dart';
void main() async {
// 创建连接配置(生产环境建议使用环境变量)
final connection = PostgreSQLConnection(
'localhost', // 主机地址
5432, // 端口号
'mydatabase', // 数据库名称
username: 'user',
password: 'pass123',
);
try {
await connection.open(); // 建立连接
// 执行查询(使用参数化查询防止SQL注入)
var result = await connection.query(
'SELECT * FROM users WHERE age > @age',
substitutionValues: {'age': 18},
);
for (var row in result) {
print('用户ID: ${row[0]}, 姓名: ${row[1]}');
}
} catch (e) {
print('连接异常: $e');
} finally {
await connection.close(); // 记得关闭连接
}
}
2.2 应用场景
适合需要严格事务支持的场景:电商订单系统、金融交易系统等。例如处理用户下单时,需要同时更新库存、创建订单、扣除余额等原子操作。
3. MongoDB连接方案
3.1 技术栈选择
采用mongo_dart
包(pub.dev/packages/mongo_dart)
import 'package:mongo_dart/mongo_dart.dart';
void main() async {
// 连接字符串格式:mongodb://用户名:密码@地址:端口/数据库
var db = Db('mongodb://user:pass123@localhost:27017/mydb');
try {
await db.open(); // 建立连接
var collection = db.collection('products');
// 插入文档
await collection.insertOne({
'name': '智能手表',
'price': 599,
'stock': 100,
'tags': ['穿戴', '电子']
});
// 复杂查询示例
var results = await collection.find(
where.match('name', '智能').gt('price', 500)
).toList();
results.forEach((doc) => print(doc));
} catch (e) {
print('操作失败: $e');
} finally {
await db.close();
}
}
3.2 技术特点
文档型数据库的灵活结构特别适合内容管理系统、物联网设备日志存储等场景。比如存储不同传感器的异构数据时,无需预先定义严格的数据表结构。
4. MySQL连接方式
4.1 技术栈选择
推荐使用mysql1
包(pub.dev/packages/mysql1)
import 'package:mysql1/mysql1.dart';
void main() async {
// 配置连接参数
final settings = ConnectionSettings(
host: 'localhost',
port: 3306,
user: 'root',
password: 'mysql_pwd',
db: 'ecommerce',
);
var conn = await MySqlConnection.connect(settings);
try {
// 事务处理示例
await conn.transaction((ctx) async {
await ctx.query(
'UPDATE accounts SET balance = balance - ? WHERE id = ?',
[100, 1]
);
await ctx.query(
'UPDATE accounts SET balance = balance + ? WHERE id = ?',
[100, 2]
);
});
print("转账成功");
} on MySqlException catch (e) {
print('事务异常: ${e.message}');
} finally {
await conn.close();
}
}
5. Redis快速接入
5.1 技术栈选择
使用dartis
包(pub.dev/packages/dartis)
import 'package:dartis/dartis.dart';
void main() async {
// 创建Redis客户端
final client = await Client.connect('redis://localhost:6379');
// 字符串操作
await client.set('last_login', DateTime.now().toString());
print(await client.get('last_login'));
// 哈希表操作
await client.hmset('user:1001', {
'name': '张三',
'points': '1500',
'vip_level': '3'
});
// 发布订阅模式
final subClient = await client.asBroadcastStream();
subClient.listen((message) {
if (message is PubSubMessage) {
print('收到消息: ${message.payload}');
}
});
await client.subscribe(['news_channel']);
}
6. SQLite轻量级方案
6.1 技术栈选择
选用sqlite3
包(pub.dev/packages/sqlite3)
import 'package:sqlite3/sqlite3.dart';
void main() {
// 打开或创建数据库
final db = sqlite3.open('local_cache.db');
// 创建表
db.execute('''
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT NOT NULL
)
''');
// 参数化插入
final stmt = db.prepare('INSERT INTO settings VALUES (?, ?)');
stmt.execute(['theme_mode', 'dark']);
// 批量查询
final result = db.select('SELECT * FROM settings');
result.forEach((row) => print('${row['key']}: ${row['value']}'));
db.dispose(); // 释放资源
}
7. 方案选型指南
7.1 性能对比
- PostgreSQL:复杂查询响应时间约15ms
- MongoDB:写入吞吐量可达10k ops/s
- Redis:读取延迟<1ms(单节点)
7.2 适用场景矩阵
数据库 | 最佳场景 | 不适用场景 |
---|---|---|
PostgreSQL | 金融交易系统 | 简单键值存储 |
MongoDB | 内容管理系统 | 强事务需求 |
Redis | 实时排行榜 | 持久化存储 |
SQLite | 移动端本地存储 | 高并发写操作 |
8. 避坑指南
- 连接池管理:PostgreSQL建议使用
postgres_pool
包实现 - 数据类型映射:Dart的DateTime类型在MySQL中需转换为DateTime(2023).toUtc()
- 安全实践:永远使用参数化查询,避免拼接SQL字符串
- 异步陷阱:所有数据库操作必须正确处理await
9. 终极总结
经过对五大数据库的实战演练,我们发现Dart生态已具备完善的数据访问能力。PostgreSQL适合重事务场景,MongoDB处理灵活数据得心应手,Redis的闪电速度无人能敌,MySQL仍是传统业务的首选,而SQLite则是本地存储的绝佳搭档。
建议开发者在项目初期根据数据复杂度、访问模式和团队熟悉度进行技术选型。Dart的异步特性与数据库操作天然契合,配合正确的连接策略,完全能够支撑起千万级用户的后端服务。下次当你启动新的Dart后端项目时,不妨从这些方案中挑选最趁手的"兵器"吧!