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. 避坑指南

  1. 连接池管理:PostgreSQL建议使用postgres_pool包实现
  2. 数据类型映射:Dart的DateTime类型在MySQL中需转换为DateTime(2023).toUtc()
  3. 安全实践:永远使用参数化查询,避免拼接SQL字符串
  4. 异步陷阱:所有数据库操作必须正确处理await

9. 终极总结

经过对五大数据库的实战演练,我们发现Dart生态已具备完善的数据访问能力。PostgreSQL适合重事务场景,MongoDB处理灵活数据得心应手,Redis的闪电速度无人能敌,MySQL仍是传统业务的首选,而SQLite则是本地存储的绝佳搭档。

建议开发者在项目初期根据数据复杂度、访问模式和团队熟悉度进行技术选型。Dart的异步特性与数据库操作天然契合,配合正确的连接策略,完全能够支撑起千万级用户的后端服务。下次当你启动新的Dart后端项目时,不妨从这些方案中挑选最趁手的"兵器"吧!