Flutter for OpenHarmony:postgres 直连 PostgreSQL 数据库,实现 Dart 原生的高效读写(数据库驱动) 深度解析与鸿蒙适配指南
摘要 本文介绍了如何在OpenHarmony和Flutter应用中使用纯Dart实现的PostgreSQL驱动postgres直接连接远程数据库。该方案具有纯Dart实现、SSL/TLS安全连接、流式查询和连接池管理等核心特性,支持全平台运行。文章详细讲解了集成配置、核心操作(简单查询、事务处理、数据库通知监听)以及OpenHarmony平台适配要点,并提供了一个实时数据看板的完整实战示例,展示如
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

前言
虽然移动应用大多使用本地数据库(如 SQLite),但在某些特定场景,比如内部企业应用、数据看板,或者 Serverless 架构中,客户端直接连接远程数据库进行即时查询是非常便捷的。
postgres 是一个纯 Dart 实现的 PostgreSQL 驱动,拥有完整的协议支持,不需要任何原生库绑定(JNI/FFI)。这意味着它不仅能在服务器端(Dart VM)运行完美,同样也能在 Flutter 移动端及 Web 端流畅运行,当然也包括 OpenHarmony。
一、核心特性
- 纯 Dart 实现:零原生依赖,全平台通用。
- SSL/TLS 安全连接:保障数据传输安全。
- 流式查询:支持大结果集的流式读取,避免 OOM。
- 连接池:内置连接池管理,适应高并发场景。
二、集成与配置
2.1 添加依赖
dependencies:
postgres: ^3.5.9
2.2 连接配置 (SSLMode)
在公网环境连接数据库,强烈建议开启 SSL。
import 'package:postgres/postgres.dart';
final endpoint = Endpoint(
host: 'db.example.com',
port: 5432,
database: 'my_db',
username: 'user',
password: 'password',
);
final connection = await Connection.open(
endpoint,
settings: ConnectionSettings(
sslMode: SslMode.require, // 强制 SSL
),
);

三、核心操作与示例
3.1 示例一:执行简单查询
查询用户列表并将结果映射为 Dart 对象。
Future<void> queryUsers() async {
// 假设已有 connection
final result = await connection.execute('SELECT id, name FROM users WHERE active = @active',
parameters: {'active': true},
);
for (final row in result) {
print('User: ${row[0]} - ${row[1]}');
}
}

3.2 示例二:事务处理
转账操作必须在事务中完成。
Future<void> transferMoney(int fromId, int toId, double amount) async {
await connection.runTx((session) async {
// 1. 扣款
await session.execute(
'UPDATE accounts SET balance = balance - @amount WHERE id = @from',
parameters: {'amount': amount, 'from': fromId},
);
// 2. 加款
await session.execute(
'UPDATE accounts SET balance = balance + @amount WHERE id = @to',
parameters: {'amount': amount, 'to': toId},
);
// 如果抛异常,自动回滚
});
}

3.3 示例三:监听数据库通知 (LISTEN/NOTIFY)
PostgreSQL 有个超酷的功能:发布订阅。App 可以实时收到数据库变更通知。
Future<void> listenChanges() async {
// 建立专用连接用于监听
final conn = await Connection.open(endpoint);
// 订阅频道 'user_updates'
await conn.execute("LISTEN user_updates");
// 监听通知流
conn.channels['user_updates']?.listen((payload) {
print('收到数据库通知: $payload');
// 刷新 UI
});
}

四、OpenHarmony 平台适配
4.1 网络权限
连接远程数据库必须声明网络权限。
"requestPermissions": [
{ "name": "ohos.permission.INTERNET" }
]
4.2 安全与证书
如果在内网且自签名证书,需要在连接时添加受信任的根证书。postgres 库允许通过 SecurityContext 自定义证书验证逻辑。
五、完整实战示例:实时数据看板
本示例将连接一个远程 PostgreSQL 数据库,并展示实时更新的销售数据。每当有新订单插入时(通过 LISTEN/NOTIFY),看板自动刷新。
5.1 示例代码
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:postgres/postgres.dart';
void main() {
runApp(const MaterialApp(home: DashboardPage()));
}
class DashboardPage extends StatefulWidget {
const DashboardPage({super.key});
State<DashboardPage> createState() => _DashboardPageState();
}
class _DashboardPageState extends State<DashboardPage> {
Connection? _conn;
List<Map<String, dynamic>> _salesData = [];
bool _connecting = true;
String _error = '';
void initState() {
super.initState();
_connectDB();
}
Future<void> _connectDB() async {
try {
// ⚠️ 真实项目中不要硬编码密码!应通过安全方式获取
final endpoint = Endpoint(
host: '192.168.1.100', // 替换为你的服务器 IP
port: 5432,
database: 'sales_db',
username: 'flutter_app',
password: 'secure_password',
);
_conn = await Connection.open(endpoint, settings: ConnectionSettings(sslMode: SslMode.disable));
// 订阅实时更新
await _conn!.execute("LISTEN new_sale");
_conn!.channels['new_sale']?.listen((_) => _refreshData());
await _refreshData(); // 初始加载
setState(() {
_connecting = false;
_error = '';
});
} catch (e) {
setState(() {
_connecting = false;
_error = '连接失败: $e';
});
}
}
Future<void> _refreshData() async {
if (_conn == null) return;
try {
final result = await _conn!.execute('SELECT product, amount, created_at FROM sales ORDER BY created_at DESC LIMIT 20');
final data = result.map((row) => {
'product': row[0] as String,
'amount': row[1] as double,
'time': row[2] as DateTime,
}).toList();
if (mounted) {
setState(() => _salesData = data);
}
} catch (e) {
print('查询失败: $e');
}
}
void dispose() {
_conn?.close();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('实时销售看板')),
body: _connecting
? const Center(child: CircularProgressIndicator())
: _error.isNotEmpty
? Center(child: Text(_error, style: const TextStyle(color: Colors.red)))
: RefreshIndicator(
onRefresh: _refreshData,
child: ListView.builder(
itemCount: _salesData.length,
itemBuilder: (context, index) {
final item = _salesData[index];
return ListTile(
leading: const Icon(Icons.shopping_cart),
title: Text(item['product']),
subtitle: Text(item['time'].toString().substring(11, 19)),
trailing: Text(
'¥${item['amount']}',
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16, color: Colors.green),
),
);
},
),
),
floatingActionButton: FloatingActionButton(
tooltip: '模拟下单',
child: const Icon(Icons.add),
onPressed: () {
// 仅用于演示:客户端插入一条数据触发通知
_conn?.execute("INSERT INTO sales (product, amount) VALUES ('OpenHarmony Device', 999.0); NOTIFY new_sale;");
},
),
);
}
}

六、总结
在 OpenHarmony 上通过 postgres 库直连数据库,为开发者提供了极大的灵活性,尤其适合快速原型开发、内部工具以及实时性要求极高的场景。
最佳实践:
- 安全性:不要把生产环境数据库端口直接暴露在公网,建议配合 VPN 或 SSH 隧道使用,或者至少限制 IP 白名单。
- 连接池:虽然库内置了连接池,但移动端资源有限,应谨慎开启过多连接。通常一个长连接用于监听,短连接按需使用。
- 架构设计:对于大型 C 端应用,仍建议通过 HTTP API 访问数据,直连仅限特定后端或管理端场景。
更多推荐
所有评论(0)