Flutter căn bản-Làm việc với cơ sở dữ liệu SQLite-CRUD
Đăng lúc: 08:55 AM - 11/07/2024 bởi Charles Chung - 382Trong bài này tôi sẽ hướng dẫn các bạn các thao tác CRUD với cơ sở dữ liệu SQLite trong Flutter
![](\images\posts\100438-26062024-crud-sqlite-flutter.jpg)
Giới thiệu
SQLite là một hệ thống quản lý cơ sở dữ liệu (DBMS) phổ biến được sử dụng rộng rãi trong các ứng dụng di động, máy tính cá nhân và các dự án nhỏ đến trung bình. Đặc điểm nổi bật của SQLite là tính nhẹ nhàng, linh hoạt và dễ sử dụng. Một số điểm nổi bật về SQLite:
- Phiên bản nhẹ nhàng
- Hỗ trợ SQL đầy đủ
- Không yêu cầu cấu hình phức tạp
- Độ tin cậy cao
- Dễ dàng mở rộng
- Hỗ trợ đa nền tảng
- Miễn phí và mã nguồn mở
Làm việc với SQLite bạn cần thực hiện các bước
- Cài gói sqflite: flutter pub add sqfite
- Kết nối với sqlite: openDatabase(path_database)
- Thực hiện các thao tác CRUD: db.execute(sql,…)
Xây dựng ứng dụng làm việc với SQLite trong Flutter
- Tạo cơ sở dữ liệu SQLite với tên "bkap_database.db"
- Tạo bảng Product(productId, productName, price, quantity)
- Thực hiện các thao tác CRUD với bảng Product.
Các bước thực hiện
- Tạo mới Flutter Project có tên "ex07"
- Khai báo dependency "sqflite 2.3.2" và "path 1.8.3 như hình dưới
- Tạo các thư mục model, screen, service và tệp tin như hình dưới
- Tệp product.dart định nghĩa lớp Product biểu diễn thông tin sản phẩm
class Product{ String productId; String productName; int price; int quantity; Product(this.productId, this.productName, this.price, this.quantity); Map<String, Object?> toMap() { return { 'productId': productId, 'productName': productName, 'price': price, 'quantity': quantity, }; } }
- Tệp productservice.dart định nghĩa các nghiệp vụ làm việc cơ sở dữ liệu SQLite và bảng Product
import 'dart:async'; import 'package:ex07/model/Product.dart'; import 'package:path/path.dart'; import 'package:sqflite/sqflite.dart'; Future<Database> getDatabase() async { final database = openDatabase(join(await getDatabasesPath(), 'bkap_database.db'), onCreate: (db, version) { return db.execute( 'create table IF NOT EXISTS product(productId TEXT PRIMARY KEY, productName TEXT, price INTEGER, quantity INTEGER)'); }, version: 1); return database; } class ProductService { Database db; ProductService(this.db); Future<void> insert(Product p) async { db.insert("product", p.toMap(),conflictAlgorithm: ConflictAlgorithm.replace); } Future<void> update(Product p) async { db.update("product", p.toMap(),where: "productId=?",whereArgs: [p.productId]); } Future<List<Product>> getAll() async{ final List<Map<String, Object?>> products=await db.query("product"); return [for(final{'productId':id as String, 'productName':name as String,'price':price as int, 'quantity': quantity as int} in products) Product(id,name, price, quantity),]; } Future<List<Product>> search(String name) async{ final List<Map<String, Object?>> products=await db.query("product",where: "productName like ?",whereArgs: ["%$name%"]); return [for(final{'productId':id as String, 'productName':name as String,'price':price as int, 'quantity': quantity as int} in products) Product(id,name, price, quantity),]; } Future<Product> getById(String id) async{ final List<Map<String, Object?>> products=await db.query("product",where: 'productId=?',whereArgs: [id]); return Product(products.first['productId'].toString(), products.first['productName'].toString(), products.first['price'] as int, products.first['quantity'] as int ); } Future<void> delete(String id) async{ await db.delete("product",where: "productId=?",whereArgs: [id]); } }
- Tệp product_screen.dart chứa code thiết kế màn hình hiển thị sản phẩm trong bảng Product
import 'package:ex07/model/Product.dart'; import 'package:ex07/screen/add_product_screen.dart'; import 'package:ex07/screen/detail_product_screen.dart'; import 'package:ex07/screen/edit_product_screen.dart'; import 'package:ex07/service/productservice.dart'; import 'package:flutter/material.dart'; class HomeScreen extends StatefulWidget { @override State<StatefulWidget> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { List<Product> products = []; late ProductService service; getProducts() async { service = ProductService(await getDatabase()); var data = await service.getAll(); setState(() { products = data; }); } @override void initState() { getProducts(); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('DANH SÁCH SẢN PHẨM'), ), body: Container( child: ListView.builder( itemBuilder: (context, index) { return ListTile( title: Text(products[index].productName), subtitle: Text('Giá:' + products[index].price.toString()), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ ElevatedButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => EditProductForm(products[index].productId))) .then((value) { getProducts(); }); }, child: Icon(Icons.edit), ), SizedBox( width: 5, ), ElevatedButton( onPressed: () { showConfirm(context, products[index].productId); }, child: Icon(Icons.delete)) ], ), onTap: (){ Navigator.push(context, MaterialPageRoute( builder: (context)=>DetailProduct(products[index].productId))); }, ); }, itemCount: products.length, ), ), floatingActionButton: FloatingActionButton( onPressed: () { Navigator.push(context, MaterialPageRoute(builder: (context) => AddProductForm())) .then((value) { getProducts(); }); }, child: const Icon(Icons.add), ), ); } void showConfirm(BuildContext context, String productId) { showDialog( context: context, builder: (context) { return AlertDialog( title: Text('Xóa sản phẩm?'), content: Text('Bạn có muốn xóa sản phẩm này không?'), actions: [ TextButton( onPressed: () { Navigator.pop(context); }, child: Text('Không')), TextButton( onPressed: () { service.delete(productId); getProducts(); Navigator.pop(context); }, child: Text('Có')), ]); }); } }
- Tệp add_product_screen.dart chứa code thiết kế màn hình thêm sản phẩm vào bảng Product
import 'package:ex07/model/Product.dart'; import 'package:ex07/service/productservice.dart'; import 'package:flutter/material.dart'; class AddProductForm extends StatefulWidget { @override _AddProductFormState createState() => _AddProductFormState(); } class _AddProductFormState extends State<AddProductForm> { late ProductService service; final _formKey = GlobalKey<FormState>(); TextEditingController _productIdController = TextEditingController(); TextEditingController _productNameController = TextEditingController(); TextEditingController _productPriceController = TextEditingController(); TextEditingController _productQuantityController = TextEditingController(); connectDatabase() async{ service=ProductService(await getDatabase()); } @override void initState() { connectDatabase(); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Thêm sản phẩm'), ), body: Padding( padding: EdgeInsets.all(16.0), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ TextFormField( controller: _productIdController, decoration: InputDecoration( labelText: 'Mã sản phẩm', ), validator: (value) { if (value!.isEmpty) { return 'Hãy nhập mã'; } return null; }, ), TextFormField( controller: _productNameController, decoration: InputDecoration( labelText: 'Tên sản phẩm', ), validator: (value) { if (value!.isEmpty) { return 'Hãy nhập tên'; } return null; }, ), TextFormField( controller: _productPriceController, decoration: InputDecoration( labelText: 'Giá', ), keyboardType: TextInputType.number, validator: (value) { if (value!.isEmpty) { return 'Hãy nhập giá'; } return null; }, ), TextFormField( controller: _productQuantityController, decoration: InputDecoration( labelText: 'Số lượng', ), keyboardType: TextInputType.number, validator: (value) { if (value!.isEmpty) { return 'Hãy nhập số lượng'; } return null; }, ), Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: ElevatedButton( onPressed: () { if (_formKey.currentState!.validate()) { // Process the data, for example, add the product to a list // or send it to an API String productId=_productIdController.text; String productName = _productNameController.text; int price =int.parse(_productPriceController.text); int quantity =int.parse(_productQuantityController.text); service.insert(Product(productId, productName, price, quantity)); ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Thêm thành công!'))); _productIdController.clear(); _productNameController.clear(); _productPriceController.clear(); _productQuantityController.clear(); } }, child: Text('Lưu'), ), ), ], ), ), ), ); } }
- Tệp edit_product_screen.dart chứa code thiết kế màn hình sửa sản phẩm trong bảng Product
import 'package:ex07/model/Product.dart'; import 'package:ex07/service/productservice.dart'; import 'package:flutter/material.dart'; class EditProductForm extends StatefulWidget { String productId; EditProductForm(this.productId); @override _EditProductFormState createState() => _EditProductFormState(); } class _EditProductFormState extends State<EditProductForm> { late ProductService service; final _formKey = GlobalKey<FormState>(); TextEditingController _productIdController = TextEditingController(); TextEditingController _productNameController = TextEditingController(); TextEditingController _productPriceController = TextEditingController(); TextEditingController _productQuantityController = TextEditingController(); connectDatabase() async{ service=ProductService(await getDatabase()); Product p=await service.getById(widget.productId); setState(() { _productIdController.text=p.productId; _productNameController.text=p.productName; _productPriceController.text=p.price.toString(); _productQuantityController.text=p.quantity.toString(); }); } @override void initState() { connectDatabase(); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Sửa sản phẩm'), ), body: Padding( padding: EdgeInsets.all(16.0), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ TextFormField( controller: _productIdController, readOnly: true, decoration: InputDecoration( labelText: 'Mã sản phẩm', ), validator: (value) { if (value!.isEmpty) { return 'Hãy nhập mã'; } return null; }, ), TextFormField( controller: _productNameController, decoration: InputDecoration( labelText: 'Tên sản phẩm', ), validator: (value) { if (value!.isEmpty) { return 'Hãy nhập tên'; } return null; }, ), TextFormField( controller: _productPriceController, decoration: InputDecoration( labelText: 'Giá', ), keyboardType: TextInputType.number, validator: (value) { if (value!.isEmpty) { return 'Hãy nhập giá'; } return null; }, ), TextFormField( controller: _productQuantityController, decoration: InputDecoration( labelText: 'Số lượng', ), keyboardType: TextInputType.number, validator: (value) { if (value!.isEmpty) { return 'Hãy nhập số lượng'; } return null; }, ), Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: ElevatedButton( onPressed: () { if (_formKey.currentState!.validate()) { // Process the data, for example, add the product to a list // or send it to an API String productId=_productIdController.text; String productName = _productNameController.text; int price =int.parse(_productPriceController.text); int quantity =int.parse(_productQuantityController.text); service.update(Product(productId, productName, price, quantity)); ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Sửa thành công!'))); Navigator.pop(context); } }, child: Text('Cập nhật'), ), ), ], ), ), ), ); } }
- Tệp detail_product_screen.dart chứa code thiết kế màn hình hiển thị một sản phẩm trong bảng Product
import 'package:ex07/model/Product.dart'; import 'package:ex07/service/productservice.dart'; import 'package:flutter/material.dart'; class DetailProduct extends StatefulWidget { String id; DetailProduct(this.id); @override State<StatefulWidget> createState() => _DetailProductState(); } class _DetailProductState extends State<DetailProduct> { late ProductService service; Product p=Product("", "", 0, 0); getProduct() async { service = ProductService(await getDatabase()); var data = await service.getById(widget.id); setState(() { p=data; }); } @override void initState() { getProduct(); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Thông tin chi tiết sản phẩm"), ), body: Container( margin: EdgeInsets.all((10)), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Mã sản phẩm: ${p.productId}'), SizedBox(height: 10,), Text('Tên sản phẩm: ${p.productName}'), SizedBox(height: 10,), Text('Giá: ${p.price}'), SizedBox(height: 10,), Text('Số lươợng: ${p.quantity}'), ], ), ), ); } }
- Tệp main.dart code khởi động ứng dụng
import 'package:ex07/screen/product_screen.dart'; import 'package:flutter/material.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); runApp(ExampleSqlite()); } class ExampleSqlite extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Ex07', home: HomeScreen(), debugShowCheckedModeBanner: false, ); } }
- Khởi động Android Emulator và chạy ứng dụng
Video quay kết quả
thay lời cảm ơn!
Các bài cũ hơn
- Flutter cơ bản-Gửi nhận dữ liệu với post và get kèm JWT tới Web API (02:20 PM - 26/06/2024)
- Flutter cơ bản-Sử dụng font chữ (11:49 AM - 26/06/2024)
- Flutter cơ bản-Thiết kế màn hình hiển thị sản phẩm giống trang Shopee (07:58 PM - 24/06/2024)
- Flutter cơ bản-Thiết kế màn hình hồ sơ cá nhân (10:17 PM - 23/06/2024)
- Flutter cơ bản-Thiết kế các màn hình LogIn-Forgot Password-SignUp trong Flutter (09:05 AM - 22/06/2024)