CÔNG NGHỆ THÔNG TIN >> BÀI VIẾT CHỌN LỌC

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 - 382

Trong 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

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!

QUẢNG CÁO - TIẾP THỊ