当前位置:网站首页>Flutter SQLite使用
Flutter SQLite使用
2022-07-01 13:00:00 【xiangxiongfly915】
Flutter SQLite使用
概述
保存数据到本地是应用程序非常重要的功能之一,比如如下场景:一个新闻类或者博客类的应用程序,打开后进入首页,如果本地没有保存数据,则需要通过网络获取数据,在返回数据之前,用户看到的是空白页面,而如果本地保存了部分新闻,则显示这部分数据,等待最新的数据返回时在刷新即可,对用户体验来说,明显第二种体验更佳。
SQLite 是目前最受欢迎的本地存储框架之一。
添加依赖
dependencies:
path_provider: ^2.0.11
sqflite: ^2.0.2+1
使用SQLite
使用单例类
class DBManager {
static final DBManager _instance = DBManager._internal();
factory DBManager() {
return _instance;
}
DBManager._internal();
}
初始化
class DBManager {
static Database? _db;
Future<Database?> get db async {
// if (_db != null) {
// return _db;
// }
// _db = await _initDB();
// return _db;
return _db ??= await _initDB();
}
/// 初始化数据库
Future<Database> _initDB() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = join(directory.path, "dbName");
return await openDatabase(
path,
version: 1,
onCreate: _onCreate,
onUpgrade: _onUpgrade,
);
}
/// 创建表
Future _onCreate(Database db, int version) async {
const String sql = """
CREATE TABLE Student(
id INTEGER primary key AUTOINCREMENT,
name TEXT,
age INTEGER,
sex INTEGER
)
""";
return await db.execute(sql);
}
/// 更新表
Future _onUpgrade(Database db, int oldVersion, int newVersion) async {}
}
增删改查操作
/// 保存数据
Future saveData(Student student) async {
var _db = await db;
return await _db?.insert("Student", student.toJson());
}
/// 使用SQL保存数据
Future saveDataBySQL(Student student) async {
const String sql = """
INSERT INTO Student(name,age,sex) values(?,?,?)
""";
var _db = await db;
return await _db?.rawInsert(sql, [student.name, student.age, student.sex]);
}
/// 查询全部数据
Future<List<Student>?> findAll() async {
var _db = await db;
List<Map<String, Object?>>? result = await _db?.query("Student");
if (result == null) {
return null;
} else {
if (result.isNotEmpty) {
return result.map((e) => Student.fromJson(e)).toList();
} else {
return [];
}
}
}
///条件查询
Future<List<Student>?> find(int sex) async {
var _db = await db;
List<Map<String, dynamic>>? result = await _db?.query("Student", where: "sex=?", whereArgs: [sex]);
if (result == null) {
return null;
} else {
if (result.isNotEmpty) {
return result.map((e) => Student.fromJson(e)).toList();
} else {
return [];
}
}
}
/// 修改
Future<int> update(Student student) async {
var _db = await db;
student.age = 99;
int? count = await _db?.update("Student", student.toJson(), where: "id=?", whereArgs: [student.id]);
return count ?? 0;
}
/// 删除
Future<int> delete(int id) async {
var _db = await db;
int? count = await _db?.delete("Student", where: "id=?", whereArgs: [id]);
return count ?? 0;
}
/// 删除全部
Future<int> deleteAll() async {
var _db = await db;
int? count = await _db?.delete("Student");
return count ?? 0;
}
完整代码如下



数据库管理类
class DBManager {
static final DBManager _instance = DBManager._internal();
factory DBManager() {
return _instance;
}
DBManager._internal();
static Database? _db;
Future<Database?> get db async {
// if (_db != null) {
// return _db;
// }
// _db = await _initDB();
// return _db;
return _db ??= await _initDB();
}
/// 初始化数据库
Future<Database> _initDB() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = join(directory.path, "dbName");
return await openDatabase(
path,
version: 1,
onCreate: _onCreate,
onUpgrade: _onUpgrade,
);
}
/// 创建表
Future _onCreate(Database db, int version) async {
const String sql = """
CREATE TABLE Student(
id INTEGER primary key AUTOINCREMENT,
name TEXT,
age INTEGER,
sex INTEGER
)
""";
return await db.execute(sql);
}
/// 更新表
Future _onUpgrade(Database db, int oldVersion, int newVersion) async {}
/// 保存数据
Future saveData(Student student) async {
var _db = await db;
return await _db?.insert("Student", student.toJson());
}
/// 使用SQL保存数据
Future saveDataBySQL(Student student) async {
const String sql = """
INSERT INTO Student(name,age,sex) values(?,?,?)
""";
var _db = await db;
return await _db?.rawInsert(sql, [student.name, student.age, student.sex]);
}
/// 查询全部数据
Future<List<Student>?> findAll() async {
var _db = await db;
List<Map<String, Object?>>? result = await _db?.query("Student");
if (result == null) {
return null;
} else {
if (result.isNotEmpty) {
return result.map((e) => Student.fromJson(e)).toList();
} else {
return [];
}
}
}
///条件查询
Future<List<Student>?> find(int age) async {
var _db = await db;
List<Map<String, dynamic>>? result = await _db?.query("Student", where: "age=?", whereArgs: [age]);
if (result == null) {
return null;
} else {
if (result.isNotEmpty) {
return result.map((e) => Student.fromJson(e)).toList();
} else {
return [];
}
}
}
/// 修改
Future<int> update(Student student) async {
var _db = await db;
student.age = 99;
int? count = await _db?.update("Student", student.toJson(), where: "id=?", whereArgs: [student.id]);
return count ?? 0;
}
/// 删除
Future<int> delete(int id) async {
var _db = await db;
int? count = await _db?.delete("Student", where: "id=?", whereArgs: [id]);
return count ?? 0;
}
/// 删除全部
Future<int> deleteAll() async {
var _db = await db;
int? count = await _db?.delete("Student");
return count ?? 0;
}
}
定义实体类
Student studentFromJson(String str) => Student.fromJson(json.decode(str));
String studentToJson(Student data) => json.encode(data.toJson());
class Student {
Student({
this.id,
this.name,
this.age,
this.sex,
});
Student.fromJson(dynamic json) {
id = json['id'];
name = json['name'];
age = json['age'];
sex = json['sex'];
}
int? id;
String? name;
int? age;
int? sex;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['name'] = name;
map['age'] = age;
map['sex'] = sex;
return map;
}
}
首页代码
class SqlitePage extends StatefulWidget {
const SqlitePage({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _SqlitePageState();
}
}
class _SqlitePageState extends State<SqlitePage> {
List<Student>? _studentList;
loadAllData() async {
_studentList = await DBManager().findAll();
setState(() {});
}
loadData() async {
_studentList = await DBManager().find(1);
setState(() {});
}
updateData(Student student) async {
var count = await DBManager().update(student);
if (count > 0) {
showSnackBar(context, "修改成功");
} else {
showSnackBar(context, "修改失败");
}
}
deleteData(int id) async {
var count = await DBManager().delete(id);
if (count > 0) {
showSnackBar(context, "删除成功");
} else {
showSnackBar(context, "删除失败");
}
}
deleteAllData() async {
var count = await DBManager().deleteAll();
if (count > 0) {
showSnackBar(context, "删除成功");
} else {
showSnackBar(context, "删除失败");
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("SQLite"),
actions: [
IconButton(
icon: const Icon(Icons.add),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return const AddStudentPage();
}));
},
)
],
),
body: SingleChildScrollView(
child: Center(
child: Column(
children: [
ElevatedButton(
onPressed: () {
loadAllData();
},
child: const Text("查询所有数据"),
),
ElevatedButton(
onPressed: () {
loadData();
},
child: const Text("条件查询"),
),
ElevatedButton(
onPressed: () {
deleteAllData();
},
child: const Text("删除全部"),
),
Padding(
padding: const EdgeInsets.all(10),
child: _buildTable(),
),
],
),
),
),
);
}
_buildTable() {
return Table(
border: TableBorder.all(),
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
children: [
const TableRow(children: [
TableCell(child: Text("id")),
TableCell(child: Text("姓名")),
TableCell(child: Text("年龄")),
TableCell(child: Text("性别")),
TableCell(child: Text("修改")),
TableCell(child: Text("删除")),
]),
...?_studentList
?.map((e) => TableRow(children: [
TableCell(child: Text("${e.id}")),
TableCell(child: Text("${e.name}")),
TableCell(child: Text("${e.age}")),
TableCell(child: Text("${e.sex}")),
TableCell(
child: TextButton(
onPressed: () {
updateData(e);
},
child: const Text("修改"),
),
),
TableCell(
child: TextButton(
onPressed: () {
deleteData(e.id!);
},
child: const Text("删除"),
),
),
]))
.toList(),
],
);
}
}
添加数据页面
class AddStudentPage extends StatefulWidget {
const AddStudentPage({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _AddStudentPageState();
}
}
class _AddStudentPageState extends State<AddStudentPage> {
int _sexValue = 0;
late TextEditingController _nameController;
late TextEditingController _ageController;
@override
void initState() {
_nameController = TextEditingController();
_ageController = TextEditingController();
super.initState();
}
@override
void dispose() {
_nameController.dispose();
_ageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("增加学生"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
TextField(
controller: _nameController,
decoration: const InputDecoration(labelText: "姓名:"),
),
TextField(
controller: _ageController,
decoration: const InputDecoration(labelText: "年龄:"),
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
],
),
Row(
children: [
Expanded(
child: RadioListTile<int>(
title: const Text("女"),
value: 0,
groupValue: _sexValue,
onChanged: (value) {
setState(() {
_sexValue = value!;
});
},
),
),
Expanded(
child: RadioListTile<int>(
title: const Text("男"),
value: 1,
groupValue: _sexValue,
onChanged: (value) {
setState(() {
_sexValue = value!;
});
},
),
),
],
),
Builder(builder: (BuildContext context) {
return Column(
children: [
ElevatedButton(
onPressed: () async {
var student = Student(
name: _nameController.text.toString(),
age: int.parse(_ageController.text.toString()),
sex: _sexValue,
);
int result = await DBManager().saveData(student);
if (result > 0) {
showSnackBar(context, '保存数据成功,result:$result');
} else {
showSnackBar(context, '保存数据失败,result:$result');
}
},
child: const Text("保存数据"),
),
ElevatedButton(
onPressed: () async {
var student = Student(
name: _nameController.text.toString(),
age: int.parse(_ageController.text.toString()),
sex: _sexValue,
);
int result = await DBManager().saveDataBySQL(student);
if (result > 0) {
showSnackBar(context, '保存数据成功,result:$result');
} else {
showSnackBar(context, '保存数据失败,result:$result');
}
},
child: const Text("使用SQL保存数据"),
),
],
);
}),
],
),
),
);
}
}
边栏推荐
- 有没有大佬 遇到过flink监控postgresql数据库, 检查点无法使用的问题
- 机器学习—性能度量
- logstash报错:Cannot reload pipeline, because the existing pipeline is not reloadable
- R language uses conf of yardstick package_ The mat function calculates the confusion matrix of the multiclass model on each fold of each cross validation (or resampling), and uses the summary to outpu
- Update a piece of data from the database. Will CDC get two pieces of data with OP fields D and C at the same time? I remember before, only OP was U
- be based on. NETCORE development blog project starblog - (13) add friendship link function
- Perl 5.10.0 installation package download
- What are the solutions for session sharing of highly paid programmers & interview questions series 118?
- Tencent always takes epoll, which is annoying
- Professor Li Zexiang, Hong Kong University of science and technology: I'm wrong. Why is engineering consciousness more important than the best university?
猜你喜欢

彩色五角星SVG动态网页背景js特效

CS5268优势替代AG9321MCQ Typec多合一扩展坞方案

硬件开发笔记(九): 硬件开发基本流程,制作一个USB转RS232的模块(八):创建asm1117-3.3V封装库并关联原理图元器件

数论基础及其代码实现

Different test techniques

Use Net core access wechat official account development

Feign & Eureka & zuul & hystrix process

Redis exploration: cache breakdown, cache avalanche, cache penetration

VM virtual machine configuration dynamic IP and static IP access
Example code of second kill based on MySQL optimistic lock
随机推荐
leetcode:329. 矩阵中的最长递增路径【dfs + cache + 无需回溯 + 优雅】
我选的热门专业,四年后成了“天坑”
快速整明白Redis中的压缩列表到底是个啥
网络socket的状态要怎么统计?
Judea pearl, Turing prize winner: 19 causal inference papers worth reading recently
Fundamentals of number theory and its code implementation
Meta再放大招!VR新模型登CVPR Oral:像人一样「读」懂语音
How to count the status of network sockets?
使用nvm管理nodejs(把高版本降级为低版本)
CS5268优势替代AG9321MCQ Typec多合一扩展坞方案
香港科技大学李泽湘教授:我错了,为什么工程意识比上最好的大学都重要?
Three stages of aho
Wave animation color five pointed star loader loading JS special effects
Introduction to reverse debugging PE structure input table output table 05/07
商汤科技崩盘 :IPO时已写好的剧本
JS discolored Lego building blocks
买卖其实也有风险
c语言学习
MHA high availability cluster deployment and failover of database
Feign & Eureka & Zuul & Hystrix 流程