如何通过Node.js API实现Flutter与MySQL数据库的连接?
通过Node.js API实现Flutter与MySQL连接的步骤
一、环境准备
- 安装Node.js及npm(或yarn)
- 安装MySQL服务器,创建测试数据库和表(示例用
users表,包含id(自增主键)、name、email字段) - 配置好Flutter开发环境
二、搭建Node.js后端API
1. 初始化项目
mkdir flutter-mysql-api && cd flutter-mysql-api npm init -y
2. 安装核心依赖
npm install express mysql2 cors dotenv
express: 轻量API框架mysql2: 稳定的MySQL连接库cors: 解决跨域请求问题dotenv: 管理环境变量
3. 配置环境变量
创建.env文件,存储数据库敏感信息:
DB_HOST=localhost DB_USER=你的MySQL用户名 DB_PASSWORD=你的MySQL密码 DB_NAME=你的数据库名 PORT=3000
4. 创建数据库连接池
新建db.js,实现数据库连接复用:
const mysql = require('mysql2/promise'); require('dotenv').config(); const pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, connectionLimit: 10, // 连接池最大连接数 waitForConnections: true }); module.exports = pool;
5. 编写API路由
新建routes/users.js,实现用户数据的增查接口:
const express = require('express'); const router = express.Router(); const pool = require('../db.js'); // 获取所有用户 router.get('/', async (req, res) => { try { const [rows] = await pool.query('SELECT * FROM users'); res.json(rows); } catch (err) { res.status(500).json({ error: err.message }); } }); // 添加新用户 router.post('/', async (req, res) => { const { name, email } = req.body; try { const [result] = await pool.query( 'INSERT INTO users (name, email) VALUES (?, ?)', [name, email] ); res.json({ id: result.insertId, name, email }); } catch (err) { res.status(500).json({ error: err.message }); } }); module.exports = router;
6. 启动服务器入口
新建server.js,整合路由与中间件:
const express = require('express'); const cors = require('cors'); require('dotenv').config(); const userRoutes = require('./routes/users.js'); const app = express(); const port = process.env.PORT || 3000; // 中间件配置 app.use(cors()); app.use(express.json()); // 解析JSON请求体 // 挂载路由 app.use('/api/users', userRoutes); // 启动服务 app.listen(port, () => { console.log(`服务器运行在端口 ${port}`); });
7. 测试后端API
启动服务器:
node server.js
- 用浏览器访问
http://localhost:3000/api/users,应返回数据库中的用户数据 - 用POST工具(如Postman)发送
{"name":"测试用户","email":"test@example.com"}到该地址,可新增用户
三、Flutter前端调用API
1. 添加依赖
在pubspec.yaml中添加HTTP请求与JSON序列化依赖:
dependencies: flutter: sdk: flutter http: ^1.1.0 json_annotation: ^4.8.1 dev_dependencies: build_runner: ^2.4.6 json_serializable: ^6.7.1
执行flutter pub get安装依赖
2. 创建用户数据模型
新建models/user.dart:
import 'package:json_annotation/json_annotation.dart'; part 'user.g.dart'; @JsonSerializable() class User { final int? id; final String name; final String email; User({this.id, required this.name, required this.email}); factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); Map<String, dynamic> toJson() => _$UserToJson(this); }
执行命令生成序列化代码:
flutter pub run build_runner build
3. 封装API服务类
新建services/api_service.dart:
import 'dart:convert'; import 'package:http/http.dart' as http; import '../models/user.dart'; class ApiService { // Android模拟器需将localhost替换为10.0.2.2,iOS模拟器可直接用localhost static const baseUrl = 'http://10.0.2.2:3000/api/users'; // 获取用户列表 static Future<List<User>> getUsers() async { final response = await http.get(Uri.parse(baseUrl)); if (response.statusCode == 200) { List<dynamic> data = json.decode(response.body); return data.map((json) => User.fromJson(json)).toList(); } else { throw Exception('加载用户失败'); } } // 添加用户 static Future<User> addUser(User user) async { final response = await http.post( Uri.parse(baseUrl), headers: {'Content-Type': 'application/json'}, body: json.encode(user.toJson()), ); if (response.statusCode == 200) { return User.fromJson(json.decode(response.body)); } else { throw Exception('添加用户失败'); } } }
4. 编写UI示例页面
新建pages/user_list.dart:
import 'package:flutter/material.dart'; import '../models/user.dart'; import '../services/api_service.dart'; class UserListPage extends StatefulWidget { const UserListPage({super.key}); @override State<UserListPage> createState() => _UserListPageState(); } class _UserListPageState extends State<UserListPage> { late Future<List<User>> _usersFuture; final _nameController = TextEditingController(); final _emailController = TextEditingController(); @override void initState() { super.initState(); _usersFuture = ApiService.getUsers(); } void _refreshUsers() { setState(() { _usersFuture = ApiService.getUsers(); }); } void _showAddDialog() { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('添加用户'), content: Column( mainAxisSize: MainAxisSize.min, children: [ TextField(controller: _nameController, decoration: const InputDecoration(labelText: '姓名')), TextField(controller: _emailController, decoration: const InputDecoration(labelText: '邮箱')), ], ), actions: [ TextButton(onPressed: () => Navigator.pop(context), child: const Text('取消')), TextButton( onPressed: () async { final newUser = User(name: _nameController.text, email: _emailController.text); try { await ApiService.addUser(newUser); _refreshUsers(); _nameController.clear(); _emailController.clear(); Navigator.pop(context); } catch (e) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('错误:$e'))); } }, child: const Text('添加'), ), ], ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('用户列表'), actions: [IconButton(icon: const Icon(Icons.add), onPressed: _showAddDialog)], ), body: FutureBuilder<List<User>>( future: _usersFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } else if (snapshot.hasError) { return Center(child: Text('加载失败:${snapshot.error}')); } else if (snapshot.data?.isEmpty ?? true) { return const Center(child: Text('暂无用户数据')); } else { return ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (context, index) { final user = snapshot.data![index]; return ListTile(title: Text(user.name), subtitle: Text(user.email)); }, ); } }, ), ); } }
5. 运行Flutter应用
确保Node.js服务器处于运行状态,启动Flutter应用即可实现用户数据的展示与新增,数据会同步到MySQL数据库。
四、生产环境注意事项
- 给API添加身份认证(如JWT),避免未授权访问
- 优化数据库连接池配置,适配高并发场景
- 将Flutter端的API地址替换为服务器公网IP或域名
- 增加异常捕获与日志记录,便于排查问题
内容的提问来源于stack exchange,提问作者Arpit Pandey
相关产品推荐
相关产品推荐

