当前位置:网站首页>Use of shutter SQLite
Use of shutter SQLite
2022-07-01 13:13:00 【xiangxiongfly915】
List of articles
Flutter SQLite Use
summary
Saving data locally is one of the most important functions of an application , For example, the following scenes : A news or blog application , Open it and go to the home page , If the data is not saved locally , You need to get data through the Internet , Before returning data , What the user sees is a blank page , And if you keep some news locally , This part of the data is displayed , When waiting for the latest data to return, refresh it , For the user experience , Obviously the second experience is better .
SQLite Is currently one of the most popular local storage frameworks .
Add dependency
dependencies:
path_provider: ^2.0.11
sqflite: ^2.0.2+1
Use SQLite
Use a singleton class
class DBManager {
static final DBManager _instance = DBManager._internal();
factory DBManager() {
return _instance;
}
DBManager._internal();
}
initialization
class DBManager {
static Database? _db;
Future<Database?> get db async {
// if (_db != null) {
// return _db;
// }
// _db = await _initDB();
// return _db;
return _db ??= await _initDB();
}
/// Initialize database
Future<Database> _initDB() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = join(directory.path, "dbName");
return await openDatabase(
path,
version: 1,
onCreate: _onCreate,
onUpgrade: _onUpgrade,
);
}
/// Create table
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);
}
/// Update table
Future _onUpgrade(Database db, int oldVersion, int newVersion) async {}
}
Add, delete, change and check operation
/// Save the data
Future saveData(Student student) async {
var _db = await db;
return await _db?.insert("Student", student.toJson());
}
/// Use SQL Save the data
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]);
}
/// Query all data
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 [];
}
}
}
/// Conditions of the query
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 [];
}
}
}
/// modify
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;
}
/// Delete
Future<int> delete(int id) async {
var _db = await db;
int? count = await _db?.delete("Student", where: "id=?", whereArgs: [id]);
return count ?? 0;
}
/// Delete all
Future<int> deleteAll() async {
var _db = await db;
int? count = await _db?.delete("Student");
return count ?? 0;
}
The complete code is as follows



Database management class
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();
}
/// Initialize database
Future<Database> _initDB() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = join(directory.path, "dbName");
return await openDatabase(
path,
version: 1,
onCreate: _onCreate,
onUpgrade: _onUpgrade,
);
}
/// Create table
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);
}
/// Update table
Future _onUpgrade(Database db, int oldVersion, int newVersion) async {}
/// Save the data
Future saveData(Student student) async {
var _db = await db;
return await _db?.insert("Student", student.toJson());
}
/// Use SQL Save the data
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]);
}
/// Query all data
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 [];
}
}
}
/// Conditions of the query
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 [];
}
}
}
/// modify
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;
}
/// Delete
Future<int> delete(int id) async {
var _db = await db;
int? count = await _db?.delete("Student", where: "id=?", whereArgs: [id]);
return count ?? 0;
}
/// Delete all
Future<int> deleteAll() async {
var _db = await db;
int? count = await _db?.delete("Student");
return count ?? 0;
}
}
Defining entity classes
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;
}
}
Home code
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, " Modification successful ");
} else {
showSnackBar(context, " Modification failed ");
}
}
deleteData(int id) async {
var count = await DBManager().delete(id);
if (count > 0) {
showSnackBar(context, " Delete successful ");
} else {
showSnackBar(context, " Delete failed ");
}
}
deleteAllData() async {
var count = await DBManager().deleteAll();
if (count > 0) {
showSnackBar(context, " Delete successful ");
} else {
showSnackBar(context, " Delete failed ");
}
}
@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(" Query all the data "),
),
ElevatedButton(
onPressed: () {
loadData();
},
child: const Text(" Conditions of the query "),
),
ElevatedButton(
onPressed: () {
deleteAllData();
},
child: const Text(" Delete all "),
),
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(" full name ")),
TableCell(child: Text(" Age ")),
TableCell(child: Text(" Gender ")),
TableCell(child: Text(" modify ")),
TableCell(child: Text(" Delete ")),
]),
...?_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(" modify "),
),
),
TableCell(
child: TextButton(
onPressed: () {
deleteData(e.id!);
},
child: const Text(" Delete "),
),
),
]))
.toList(),
],
);
}
}
Add data pages
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(" Add students "),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
TextField(
controller: _nameController,
decoration: const InputDecoration(labelText: " full name :"),
),
TextField(
controller: _ageController,
decoration: const InputDecoration(labelText: " Age :"),
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
],
),
Row(
children: [
Expanded(
child: RadioListTile<int>(
title: const Text(" Woman "),
value: 0,
groupValue: _sexValue,
onChanged: (value) {
setState(() {
_sexValue = value!;
});
},
),
),
Expanded(
child: RadioListTile<int>(
title: const Text(" male "),
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, ' Data saved successfully ,result:$result');
} else {
showSnackBar(context, ' Failed to save data ,result:$result');
}
},
child: const Text(" Save the data "),
),
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, ' Data saved successfully ,result:$result');
} else {
showSnackBar(context, ' Failed to save data ,result:$result');
}
},
child: const Text(" Use SQL Save the data "),
),
],
);
}),
],
),
),
);
}
}
边栏推荐
- 有人碰到过这种情况吗,oracle logminer 同步的时候,clob字段的值丢失
- 启动solr报错The stack size specified is too small,Specify at least 328k
- mysql统计账单信息(下):数据导入及查询
- SQLAlchemy在删除有外键约束的记录时,外键约束未起作用,何解?
- Router.use() requires a middleware function but got a Object
- MySQL gap lock
- leetcode:329. The longest incremental path in the matrix [DFS + cache + no backtracking + elegance]
- 北斗通信模块 北斗gps模块 北斗通信终端DTU
- Redis explores cache consistency
- Function test process in software testing
猜你喜欢

路由基础之OSPF LSA详细讲解

Meta再放大招!VR新模型登CVPR Oral:像人一样「读」懂语音

Colorful five pointed star SVG dynamic web page background JS special effect
基于mysql乐观锁实现秒杀的示例代码
![leetcode:226. Flip binary tree [DFS flip]](/img/b8/6c5596ac30de59f0f347bb0bddf574.png)
leetcode:226. Flip binary tree [DFS flip]
Reasons for MySQL reporting 1040too many connections and Solutions

软件测试中功能测试流程
![79. Word search [DFS + backtracking visit + traversal starting point]](/img/d6/a7693b2af435b7cf4562161ca4bd3f.png)
79. Word search [DFS + backtracking visit + traversal starting point]

Professor Li Zexiang, Hong Kong University of science and technology: I'm wrong. Why is engineering consciousness more important than the best university?
Example code of second kill based on MySQL optimistic lock
随机推荐
数据库之MHA高可用集群部署及故障切换
股票开户要认识谁?实际上网上开户安全么?
JS变色的乐高积木
C language learning
The sky is blue and misty
华为HMS Core携手超图为三维GIS注入新动能
硬件开发笔记(九): 硬件开发基本流程,制作一个USB转RS232的模块(八):创建asm1117-3.3V封装库并关联原理图元器件
Example code of second kill based on MySQL optimistic lock
oracle cdc 数据传输时,clob类型字段,在update时值会丢失,update前有值,但
I spent tens of thousands of dollars to learn and bring goods: I earned 3 yuan in three days, and the transaction depends on the bill
be based on. NETCORE development blog project starblog - (13) add friendship link function
Judea pearl, Turing prize winner: 19 causal inference papers worth reading recently
科学创业三问:关于时机、痛点与重要决策
MySQL statistical bill information (Part 2): data import and query
c语言学习
Colorful five pointed star SVG dynamic web page background JS special effect
内容审计技术
Fundamentals of number theory and its code implementation
我选的热门专业,四年后成了“天坑”
基于开源流批一体数据同步引擎 ChunJun 数据还原 —DDL 解析模块的实战分享