Flutter链接MySQL
Flutter链接MySQL

Flutter链接MySQL

1. 前言

Flutter官方对两种数据库更加推荐,且为它们提供了更好的支持,分别是
SQLite:一种本地数据库,优点顾名思义,更加轻量化,且对移动设备的支持更好;缺点是无法云上部署并通过IP链接
FireBase:由Google官方提供的NoSQL数据库,向用户提供了非常丰富的API接口,且为多用户聊天提供了很好的原生支持,是制作聊天功能的首选

这里仍然选择MySQL的原因:

  1. 没学过数据库,用老牌数据库学一下常规操作先
  2. 可以云上部署,在自己的服务器上部署特别方便
  3. 在腾讯云服务器上部署规避Google科学上网的限制

2. MySQL 安装 简单配置

Ubuntu 服务器

打开终端用ssh命令行安装还是太麻烦了
直接用宝塔的数据库功能,点添加数据库,填写config就好
更细致的操作,如创建用户、编辑权限、创建表等,点击phpMyAdmin进入php管理页面操作

Windows

在MySQL官网下载安装包后安装

SQL 可视化管理工具

推荐DBeaver,官网下载安装即可
配置简单,界面直观,功能丰富
可以管理云端数据库
支持多种SQL

常用命令

启动:net start mysql 尽量用管理员权限
关闭:net stop mysql
本地链接 mysql -u your_username -p root用户可能不用输入密码
列出所有数据库 SHOW DATABASES;
选择要使用的数据库(进入数据库) USE your_database;
列出此数据库中的所有表 SHOW TABLES;
创建数据库 CREATE DATABASE 数据库名;
创建数据表

CREATE TABLE table_name (
    column1 datatype,
    column2 datatype,
    ...
);

插入数据

INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);

3. Flutter链接MySQL

在pub.dev中,有三种第三方编写的MySQL插件,这里使用的是mysql_client
mysql_client | Dart package (pub.dev)
根据官方页面介绍,这个插件的功能有

  1. 创建链接池
  2. 创建单链接
  3. CRUD操作(插入、删除、查询、修改)
    我们首先编写一个最最简单的Flutter界面,包含两个按钮:尝试链接、插入数据

    import 'package:flutter/material.dart';
    void main() => runApp(MyApp());
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('MySQL Insert Example'),
            ),
            body: Center(
              child: FutureBuilder<void>(
                future: _insertData(),
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.done) {
                    if (snapshot.hasError) {
                      return Text('Error: ${snapshot.error}');
                    } else {
                      return Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          ElevatedButton(
                            onPressed: (),
                            child: Text('Connect to MySQL'),
                          ),
                          SizedBox(height: 20),
                          ElevatedButton(
                            onPressed: (),
                            child: Text('Insert Data'),
                          ),
                        ],
                      );
                    }
                  } else {
                    return CircularProgressIndicator();
                  }
                },
              ),
            ),
          ),
        );
      }
    }

显而易见,后续的SQL操作需要编写独立的函数放在类里,并在ElevatedButton中的onPressed()里使用,这样点击按钮后执行我们编写的MySQL操作函数

安装包

flutter pub add mysql_client

引用包

import 'package:mysql_client/mysql_client.dart';

这里给出链接的函数

Future<void> _insertData() async {    //async是异步操作
    try {
      print("Connecting to mysql server...");
      // create connection
      final conn = await MySQLConnection.createConnection(    //链接MySQL服务器
        host: "127.0.0.1",                      //这里链接云端服务器直接改IP就够了
        port: 3306,
        userName: "root",
        password: "",
        databaseName: "test1", // optional
      );
      
      await conn.connect();

      // insert some rows
      var res = await conn.execute(
        "INSERT INTO tabletest1 (name, email, age) VALUES (:name, :email, :age )",
        {                       //上面这句其实就是MySQL命令行操作语句
          "name": "aaaaa",      //这一部分根据表的格式和自己想插入的数据写
          "email": "aaaaa.com",
          "age": 20,
        },
      );

      print(res.affectedRows);

      // close all connections  操作结束后要关闭链接
      await conn.close();
    } catch (e) {

      print('Error: $e');

    }

  }

4. 完整程序

// main.dart
import 'package:flutter/material.dart';
import 'package:mysql_client/mysql_client.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('MySQL Insert Example'),
        ),
        body: Center(
          child: FutureBuilder<void>(
            future: _insertData(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasError) {
                  return Text('Error: ${snapshot.error}');
                } else {
                  return Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      ElevatedButton(
                        onPressed: () => _showSnackbar(context, 'Connected'),
                        child: Text('Connect to MySQL'),
                      ),
                      SizedBox(height: 20),
                      ElevatedButton(
                        onPressed: () => _showSnackbar(context, 'Inserted Data'),
                        child: Text('Insert Data'),
                      ),
                    ],
                  );
                }
              } else {
                return CircularProgressIndicator();
              }
            },
          ),
        ),
      ),
    );
  }

  Future<void> _insertData() async {
    try {
      print("Connecting to mysql server...");
      // create connection
      final conn = await MySQLConnection.createConnection(
        host: "127.0.0.1",
        port: 3306,
        userName: "root",
        password: "",
        databaseName: "test1", // optional
      );
      await conn.connect();
      // insert some rows
      var res = await conn.execute(
        "INSERT INTO tabletest1 (name, email, age) VALUES (:name, :email, :age )",
        {
          "name": "aaaaa",
          "email": "aaaaa.com",
          "age": 20,
        },
      );
      
      print(res.affectedRows);
      
      // close all connections
      await conn.close();
    } catch (e) {
      print('Error: $e');
    }
  }

  void _showSnackbar(BuildContext context, String message) {    //APP底部的提示信息
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message)),
    );
  }
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注