You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 00:37:50