• 无涯教程-Flutter - 数据库


    SQLite" class="css-1occaib">SQLite数据库是基于事实和标准SQL的嵌入式数据库引擎,它是小型且经过时间考验的数据库引擎,sqflite软件包提供了许多函数,可以有效地与SQLite数据库一起使用,它提供了操作SQLite数据库引擎的标准方法。

    • 在Android Studio中创建一个新的Flutter应用程序product_sqlite_app。

    • 用无涯教程的 product_rest_app 代码替换默认的启动代码(main.dart)。

    • 将assets文件夹从 product_nav_app 复制到 product_rest_app 并在* pubspec.yaml`文件内添加assets。

    flutter: 
       assets: 
          - assets/appimages/floppy.png 
          - assets/appimages/iphone.png 
          - assets/appimages/laptop.png 
          - assets/appimages/pendrive.png 
          - assets/appimages/pixel.png 
          - assets/appimages/tablet.png
    • 在pubspec.yaml文件中配置sqflite软件包,如下所示-

    dependencies: sqflite: any
    • 在pubspec.yaml文件中配置path_provider软件包,如下所示-

    dependencies: path_provider: any
    • 此处,path_provider软件包用于获取系统的临时文件夹路径和应用程序的路径,使用 sqflite 的最新版本号代替任何。

    • Android Studio会提醒pubspec.yaml已更新。

    Updated
    • 单击"Get dependencies"选项。 Android studio将从互联网上获取该软件包,并为应用程序正确配置它。

    • 在数据库中,无涯教程需要主键,id作为附加字段以及产品属性(如名称,价格等),因此,请在Product类中添加id属性。另外,添加新方法toMap将产品对象转换为Map对象。 fromMap和toMap用于对Product对象进行序列化和反序列化,并用于数据库操作方法中。

    class Product { 
       final int id; 
       final String name; 
       final String description; 
       final int price; 
       final String image; 
       static final columns = ["id", "name", "description", "price", "image"]; 
       Product(this.id, this.name, this.description, this.price, this.image); 
       factory Product.fromMap(Map<String, dynamic> data) {
          return Product( 
             data[id], 
             data[name], 
             data[description], 
             data[price], 
             data[image], 
          ); 
       } 
       Map<String, dynamic> toMap() => {
          "id": id, 
          "name": name, 
          "description": description, 
          "price": price, 
          "image": image 
       }; 
    }
    • 在lib文件夹中创建一个新文件Database.dart,以编写SQLite的相关函数。

    • 在Database.dart中导入必要的import语句。

    import dart:async; 
    import dart:io; 
    import package:path/path.dart; 
    import package:path_provider/path_provider.dart; 
    import package:sqflite/sqflite.dart; 
    import Product.dart;
    • 请注意以下几点-

      • async                    -  用于编写异步方法。

      • io                           -  用于访问文件和目录。

      • path                      -  用于访问与文件路径相关的dart核心实用程序函数。

      • path_provider    -  用于获取临时路径和应用程序路径。

      • sqflite                   -  用于操作SQLite的数据库。

    • 创建一个新的类SQLite的DbProvider

    •     - 声明一个基于单例的静态SQLite的DbProvider对象,如下所示:

    class SQLiteDbProvider { 
       SQLiteDbProvider._(); 
       static final SQLiteDbProvider db=SQLiteDbProvider._(); 
       static Database _database; 
    } 
    •     - 可以通过静态db变量访问SQLite的DBProvoider对象及其方法。

    SQLiteDBProvoider.db.<emthod> 
    •     - 创建一个方法来获取类型为Future 的数据库,创建产品表并在数据库本身创建期间加载初始数据。

    Future<Database> get database async { 
       if (_database != null) 
       return _database; 
       _database = await initDB(); 
       return _database; 
    }
    initDB() async { 
       Directory documentsDirectory = await getApplicationDocumentsDirectory(); 
       String path = join(documentsDirectory.path, "ProductDB.db"); 
       return await openDatabase(
          path, 
          version: 1,
          onOpen: (db) {}, 
          onCreate: (Database db, int version) async {
             await db.execute(
                "CREATE TABLE Product ("
                "id INTEGER PRIMARY KEY,"
                "name TEXT,"
                "description TEXT,"
                "price INTEGER," 
                "image TEXT" ")"
             ); 
             await db.execute(
                "INSERT INTO Product (id, name, description, price, image) 
                values (?, ?, ?, ?, ?)", 
                [1, "iPhone", "iPhone is the stylist phone ever", 1000, "iphone.png"]
             ); 
             await db.execute(
                "INSERT INTO Product (id, name, description, price, image) 
                values (?, ?, ?, ?, ?)", 
                [2, "Pixel", "Pixel is the most feature phone ever", 800, "pixel.png"]
             ); 
             await db.execute(
                "INSERT INTO Product (id, name, description, price, image) 
                values (?, ?, ?, ?, ?)", 
                [3, "Laptop", "Laptop is most productive development tool", 2000, "laptop.png"]\
             ); 
             await db.execute( 
                "INSERT INTO Product (id, name, description, price, image) 
                values (?, ?, ?, ?, ?)", 
                [4, "Tablet", "Laptop is most productive development tool", 1500, "tablet.png"]
             );
             await db.execute( 
                "INSERT INTO Product 
                (id, name, description, price, image) 
                values (?, ?, ?, ?, ?)", 
                [5, "Pendrive", "Pendrive is useful storage medium", 100, "pendrive.png"]
             );
             await db.execute( 
                "INSERT INTO Product 
                (id, name, description, price, image) 
                values (?, ?, ?, ?, ?)", 
                [6, "Floppy Drive", "Floppy drive is useful rescue storage medium", 20, "floppy.png"]
             ); 
          }
       ); 
    }
    • 在这里,无涯教程使用了以下方法-

      •     -  getApplicationDocumentsDirectory -  返回应用程序目录路径

      •     -  join                        - 用于创建系统特定的路径,无涯教程已经使用它来创建数据库路径。

      •     -  openDatabase     - 用于打开SQLite的数据库。

      •     -  onOpen                - 用于在打开数据库时编写代码

      •     -  onCreate              - 用于在首次创建数据库时编写代码

      •     -  db.execute           - 用于执行SQL查询。它接受一个查询。如果查询具有占位符(?),则它将接受值作为第二个参数中的列表。

    • 编写getAllProducts来获取数据库中的所有产品-

    Future<List<Product>> getAllProducts() async { 
       final db = await database; 
       List<Map> 
       results = await db.query("Product", columns: Product.columns, orderBy: "id ASC"); 
       
       List<Product> products = new List(); 
       results.forEach((result) { 
          Product product = Product.fromMap(result); 
          products.add(product); 
       }); 
       return products; 
    }
    • 编写getProductById来获取特定于 id的产品

    Future<Product> getProductById(int id) async {
       final db = await database; 
       var result = await db.query("Product", where: "id=", whereArgs: [id]); 
       return result.isNotEmpty ? Product.fromMap(result.first) : Null; 
    }
    • 在这里,无涯教程使用了where和whereArgs来应用过滤器。

    • 创建三种方法-插入,更新和删除方法,以从数据库中插入,更新和删除产品。

    insert(Product product) async { 
       final db = await database; 
       var maxIdResult = await db.rawQuery(
          "SELECT MAX(id)+1 as last_inserted_id FROM Product");
    
       var id = maxIdResult.first["last_inserted_id"]; 
       var result = await db.rawInsert(
          "INSERT Into Product (id, name, description, price, image)" 
          " VALUES (?, ?, ?, ?, ?)", 
          [id, product.name, product.description, product.price, product.image] 
       ); 
       return result; 
    }
    update(Product product) async { 
       final db = await database; 
       var result = await db.update("Product", product.toMap(), 
       where: "id=?", whereArgs: [product.id]); return result; 
    } 
    delete(int id) async { 
       final db = await database; 
       db.delete("Product", where: "id=?", whereArgs: [id]); 
    }
    • Database.dart的最终代码如下-

    import dart:async; 
    import dart:io; 
    import package:path/path.dart; 
    import package:path_provider/path_provider.dart; 
    import package:sqflite/sqflite.dart; 
    import Product.dart; 
    
    class SQLiteDbProvider {
       SQLiteDbProvider._(); 
       static final SQLiteDbProvider db = SQLiteDbProvider._(); 
       static Database _database; 
       
       Future<Database> get database async {
          if (_database != null) 
          return _database; 
          _database = await initDB(); 
          return _database; 
       } 
       initDB() async {
          Directory documentsDirectory = await 
          getApplicationDocumentsDirectory(); 
          String path = join(documentsDirectory.path, "ProductDB.db"); 
          return await openDatabase(
             path, version: 1, 
             onOpen: (db) {}, 
             onCreate: (Database db, int version) async {
                await db.execute(
                   "CREATE TABLE Product (" 
                   "id INTEGER PRIMARY KEY," 
                   "name TEXT," 
                   "description TEXT," 
                   "price INTEGER," 
                   "image TEXT"")"
                ); 
                await db.execute(
                   "INSERT INTO Product (id, name, description, price, image) 
                   values (?, ?, ?, ?, ?)", 
                   [1, "iPhone", "iPhone is the stylist phone ever", 1000, "iphone.png"]
                ); 
                await db.execute( 
                   "INSERT INTO Product (id, name, description, price, image) 
                   values (?, ?, ?, ?, ?)", 
                   [2, "Pixel", "Pixel is the most feature phone ever", 800, "pixel.png"]
                );
                await db.execute(
                   "INSERT INTO Product (id, name, description, price, image) 
                   values (?, ?, ?, ?, ?)", 
                   [3, "Laptop", "Laptop is most productive development tool", 2000, "laptop.png"]
                ); 
                await db.execute( 
                   "INSERT INTO Product (id, name, description, price, image) 
                   values (?, ?, ?, ?, ?)", 
                   [4, "Tablet", "Laptop is most productive development tool", 1500, "tablet.png"]
                ); 
                await db.execute( 
                   "INSERT INTO Product (id, name, description, price, image) 
                   values (?, ?, ?, ?, ?)", 
                   [5, "Pendrive", "Pendrive is useful storage medium", 100, "pendrive.png"]
                );
                await db.execute( 
                   "INSERT INTO Product (id, name, description, price, image) 
                   values (?, ?, ?, ?, ?)", 
                   [6, "Floppy Drive", "Floppy drive is useful rescue storage medium", 20, "floppy.png"]
                ); 
             }
          ); 
       }
       Future<List<Product>> getAllProducts() async {
          final db = await database; 
          List<Map> results = await db.query(
             "Product", columns: Product.columns, orderBy: "id ASC"
          ); 
          List<Product> products = new List();   
          results.forEach((result) {
             Product product = Product.fromMap(result); 
             products.add(product); 
          }); 
          return products; 
       } 
       Future<Product> getProductById(int id) async {
          final db = await database; 
          var result = await db.query("Product", where: "id=", whereArgs: [id]); 
          return result.isNotEmpty ? Product.fromMap(result.first) : Null; 
       } 
       insert(Product product) async { 
          final db = await database; 
          var maxIdResult = await db.rawQuery("SELECT MAX(id)+1 as last_inserted_id FROM Product"); 
          var id = maxIdResult.first["last_inserted_id"]; 
          var result = await db.rawInsert(
             "INSERT Into Product (id, name, description, price, image)" 
             " VALUES (?, ?, ?, ?, ?)", 
             [id, product.name, product.description, product.price, product.image] 
          ); 
          return result; 
       } 
       update(Product product) async { 
          final db = await database; 
          var result = await db.update(
             "Product", product.toMap(), where: "id=?", whereArgs: [product.id]
          ); 
          return result; 
       } 
       delete(int id) async { 
          final db = await database; 
          db.delete("Product", where: "id=?", whereArgs: [id]);
       } 
    }
    • 更改主要方法以获取产品信息。

    void main() {
       runApp(MyApp(products: SQLiteDbProvider.db.getAllProducts())); 
    }
    • 在这里,无涯教程使用了getAllProducts方法来从数据库中获取所有产品。

    • 运行该应用程序并查看结果。它与先前的示例访问产品服务API相似,不同之处在于,产品信息是从本地SQLite的数据库存储和获取的。

    Flutter - 数据库 - 无涯教程网无涯教程网提供SQLite" class="css-1occaib">SQLite数据库是基于事实和标准SQL的嵌入式数据库引擎...https://www.learnfk.com/flutter/flutter-database-concepts.html

  • 相关阅读:
    PTL货位指引标签为仓储管理打开新思路
    【机器学习】顶会冠军图像分割算法深度解密
    为什么说网上的md5加密解密站都是通过彩虹表解密的?
    Redis第三讲:分布式锁的三种实现方法
    python:list和dict的基本操作实例
    微信小程序自动化测试实践(附 Python 源码)| 实战系列
    Rust开发问题汇总
    JS 事件
    记一次python 正则表达式
    https
  • 原文地址:https://blog.csdn.net/w116858389/article/details/132624615