网站系统怎么做,网站建设入账,电商网站建设图片,适合个人开店的外贸平台Flutter开发进阶之并发操作数据库
尽管 Flutter 本身不包含任何数据库功能#xff0c;但可以使用各种第三方库和插件来在 Flutter 应用程序中实现数据库功能#xff1b; 以下将使用sqflite作为例子#xff0c;sqflite允许在 Flutter 应用程序中执行 SQL 查询#xff0c;创…Flutter开发进阶之并发操作数据库
尽管 Flutter 本身不包含任何数据库功能但可以使用各种第三方库和插件来在 Flutter 应用程序中实现数据库功能 以下将使用sqflite作为例子sqflite允许在 Flutter 应用程序中执行 SQL 查询创建和管理数据库表以及执行其他常见的数据库操作。 在将sqflite添加到Flutter项目的依赖中后就可以使用代码创建数据库和表了。
import package:sqflite/sqflite.dart; FutureDatabase getDatabase() async { final dir (await getDatabasesPath()).resolve(my_database.db); return await openDatabase(dir.path, version: 1, onCreate: _onCreate);
} Future _onCreate(Database db, int version) async { await db.execute( CREATE TABLE user ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER ) );
}然后我们可以做一些插入、查询、更新和删除数据库中数据的操作。
import package:sqflite/sqflite.dart; Futurevoid insertData() async { final db await getDatabase(); await db.execute( INSERT INTO user (name, age) VALUES (?, ?), [John, 25], );
} FutureListMapString, dynamic queryData() async { final db await getDatabase(); return await db.query(user);
} Futureint updateData() async { final db await getDatabase(); return await db.update( user, {age: 26}, where: name ?, whereArgs: [John], );
} Futureint deleteData() async { final db await getDatabase(); return await db.delete(user, where: name ?, whereArgs: [John]);
}在实际应用中并不会这么简单特别是当我们有需求在多个位置去操作数据库的时候这时候可能会有线程安全的问题 比如说在一个作用域内有多台设备需要在我所在的这台设备操作数据库 首先我所在的设备作为主机要监听子机的UDP广播然后将通过我验证的子机向其发送我开放的TCP的地址和端口。 const String multicastGroup 224.0.0.1; // 定义多播组地址 const int port 5000; // 定义端口号 const int bufferSize 1024; // 定义缓冲区大小 final ByteData buffer ByteData(bufferSize); DatagramSocket socket DatagramSocket(); socket.bind(port); socket.joinMulticastGroup(multicastGroupIP); socket.listen(buffer.length); socket.onDatagramReceived (Datagram datagram) async { final String receivedData datagram.data.toString(); // 处理接收到的数据... }; 然后合法的子机会收到我的信息就可以通过TCP向主机发送命令 这时就需要主机时刻监听TCP并对其响应。 const int port 5000; // 定义端口号 final ServerSocket serverSocket ServerSocket(port); serverSocket.onAccept (ServerSocket socket) async { final Stream stream socket.accept(); stream.transform(utf8.decoder).listen((String data) { // 处理接收到的数据... }); }; 假设对其响应的本身是对数据库进行操作而主机内部也同时对数据库有了操作这时候就要注意数据库的线程安全了 首先可以通过对数据库的操作加锁来保证比如sqflite提供了事务Transaction在事务中执行数据库操作可以确保操作的原子性即要么全部成功要么全部失败 通过使用事务我们可以实现对数据库操作的加锁确保同一时间只有一个线程可以访问数据库中的特定资源。
Futurevoid insertData() async { final db await getDatabase(); await db.transaction((txn) async { // 在事务中执行数据库操作 await txn.execute(INSERT INTO user (name, age) VALUES (?, ?), (John, 25)); // 提交事务 await txn.commit(); });
} 或者直接使用synchronized创建锁。
import package:synchronized/synchronized.dart;还可以通过数据库连接池来限制最大连接数量。
import package:sqflite/sqflite.dart; class DatabaseHelper { static final DatabaseHelper _instance DatabaseHelper._internal(); static Database? _db; factory DatabaseHelper() { return _instance; } FutureDatabase get db async { if (_db ! null) return _db; _db await _openDatabase(); return _db; } Futurevoid close() async { if (_db ! null) { await _db!.close(); _db null; } } FutureDatabase _openDatabase() async { final pool await SqliteConnectionPool.forDatabase(path/to/database.db); pool.maxSize 10; // 设置最大连接数为10 return pool.openDatabase(); }
}这样同时还避免了直接使用Database实例。