{"id":736,"date":"2019-12-14T09:08:27","date_gmt":"2019-12-14T09:08:27","guid":{"rendered":"https:\/\/citrusleaf.in\/blog\/?p=736"},"modified":"2022-12-10T10:32:29","modified_gmt":"2022-12-10T10:32:29","slug":"sqflite-flutter-tutorial-introduction","status":"publish","type":"post","link":"https:\/\/citrusleaf.in\/blog\/sqflite-flutter-tutorial-introduction\/","title":{"rendered":"SQFlite Flutter Tutorial &#8211; Introduction"},"content":{"rendered":"\n<p>The soaring technology trend in the mobile app industry is nothing but Flutter, a cross-platform SDK launched by Google. With its cross-platform features and easy to implement methods, Flutter has attracted the interest of many developers.<\/p>\n\n\n\n<p>Starting with the configuration and architecture of a Flutter app is a straightforward process. But, when you jump to the next step that is creating a Database, you might get stuck. To be precise, there is no such database method available for Flutter but one can integrate the SQLite database system to the Flutter app using SQFLite plugin.<\/p>\n\n\n\n<p>In this article, we are going to discuss how to set up a local SQLite database in a Flutter app. We are going to demonstrate it on a TODO list example.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is SQLite?<\/h2>\n\n\n\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"546\" height=\"199\" src=\"https:\/\/i0.wp.com\/citrusleaf.in\/blog\/\/wp-content\/uploads\/2019\/12\/flutter-sqflite-citrusleaf.jpg?resize=546%2C199&#038;ssl=1\" alt=\"\" class=\"wp-image-741\" srcset=\"https:\/\/i0.wp.com\/citrusleaf.in\/blog\/wp-content\/uploads\/2019\/12\/flutter-sqflite-citrusleaf.jpg?w=546&amp;ssl=1 546w, https:\/\/i0.wp.com\/citrusleaf.in\/blog\/wp-content\/uploads\/2019\/12\/flutter-sqflite-citrusleaf.jpg?resize=300%2C109&amp;ssl=1 300w\" sizes=\"auto, (max-width: 546px) 100vw, 546px\" \/><\/figure>\n\n\n\n<p>SQLite is an open-source relational database. SQLite does not have a separate server process which means that it essentially stores the data in a file (also known as an embedded mode). SQLite is the world\u2019s most used database and is used in almost every connected device. Both Android &amp; iOS relies heavily on SQLite.<\/p>\n\n\n\n<p>SQFLite is a plugin for Flutter. It supports both the native platforms i.e Android &amp; iOS.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why use the SQFlite plugin?<\/h2>\n\n\n\n<p>Flutter does not provide a built-in abstraction for accessing the SQLite Database. However, using the SQFlite plugin, one can access the SQLite database on both Android &amp; iOS. The plugin is well-maintained and is recommended by the Flutter team as well.<\/p>\n\n\n\n<p>If you are new to SQLite and SQL statements, go ahead &amp; learn the basics of SQLite from <a href=\"https:\/\/www.w3resource.com\/sql\/tutorials.php\">SQL Tutorial<\/a><\/p>\n\n\n\n<p>In this article, we will be demonstrating an example (TODO App) of using the SQFlite plugin in the Flutter application.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/citrusleaf.tech\/contact-us\/\" target=\"_blank\" rel=\"noreferrer noopener\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"790\" height=\"198\" src=\"https:\/\/i0.wp.com\/citrusleaf.in\/blog\/wp-content\/uploads\/2022\/12\/Looking-for-Dedicated-Remote-Flutter-Developers-1200-%C3%97-300px.gif?resize=790%2C198&#038;ssl=1\" alt=\"\" class=\"wp-image-1918\"\/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Depend on SQFlite<\/h2>\n\n\n\n<p>Add the following dependencies to pubspec.yml and run \u201cflutter packages get\u201d command in the terminal.<\/p>\n\n\n\n<p><strong>Dependencies:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sqflite: ^1.1.0  #sqflite package\nflutter_simple_dependency_injection: ^1.0.1 #to perform dependency injection\npath_provider: ^0.5.0+1 #helper package used by database helper class to get the database file<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Create a Database Helper Class<\/h2>\n\n\n\n<p>This class is going to be used throughout the app\u2019s lifecycle. Ideally, it should be used with some kind of Dependency Injection technique.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import 'dart:io' as io;\n\nimport 'package:path\/path.dart';\nimport 'package:path_provider\/path_provider.dart';\nimport 'package:sqflite\/sqflite.dart';\n\nclass DatabaseHelper {\n static final DatabaseHelper _instance = new DatabaseHelper.internal();\n\n factory DatabaseHelper() =&gt; _instance;\n static Database _db;\n\n DatabaseHelper.internal();\n\n initDb() async {\n   io.Directory documentsDirectory = await getApplicationDocumentsDirectory();\n   String path = join(documentsDirectory.path, \"database_name.db\");\n   _db = await openDatabase(path, version: 1, onCreate: _onCreate);\n }\n\n Database get db {\n   return _db;\n }\n\n void _onCreate(Database db, int version) async {\n   \/\/ When creating the db, create the table\n   await db.execute(\n       'CREATE TABLE todos (id INTEGER PRIMARY KEY AUTOINCREMENT,'\n'item_name TEXT,'\n           'date_created TEXT')';\n }\n}<\/code><\/pre>\n\n\n\n<p>In the class above, the initDb() method initializes the and calls onCreate() when the database is created for the first time. The version parameter is the database version and is useful when migrating\/updating the DB structure when the app is updated.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Create an Injection class<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>import 'dart:async';\n\nimport 'package:eknumber\/utils\/database_helper.dart';\nimport 'package:flutter_simple_dependency_injection\/injector.dart';\n\nclass Injection {\n static DatabaseHelper _databaseHelper = DatabaseHelper();\n static Injector injector;\n\n static Future initInjection() async {\n   await _databaseHelper.initDb();\n  \n   injector = Injector.getInjector();\n\n\n   injector.map&lt;DatabaseHelper&gt;((i) =&gt; _databaseHelper,\n       isSingleton: true);\n}\n}<\/code><\/pre>\n\n\n\n<p>The above class makes sure that there\u2019s only one instance of the database available throughout the app\u2019s lifecycle. In order to use the DB from any other class, you can get it easily by doing-<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DatabaseHelper _databaseHelper = Injection.injector.get();<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Create a Model Class <\/h2>\n\n\n\n<p>In this example, we\u2019re going to create a simple data model with few properties and few methods which will be used when doing CRUD operations on the DB table.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Todo{\n int id;\n String itemName;\n String dateCreated;\n\n Todo(\n     {this.id,\n     this.itemName,\n     this.dateCreated})\n\n \/\/to be used when inserting a row in the table\n Map&lt;String, dynamic&gt; toMapWithoutId() {\n   final map = new Map&lt;String, dynamic&gt;();\n   map&#91;\"item_name\"] = itemName;\n   map&#91;\"date_created\"] = dateCreated;\n   return map;\n }\n\nMap&lt;String, dynamic&gt; toMap() {\n   final map = new Map&lt;String, dynamic&gt;();\n   map&#91;\"id\"] = id;\n   map&#91;\"item_name\"] = itemName;\n   map&#91;\"date_created\"] = dateCreated;\n   return map;\n }\n\n \/\/to be used when converting the row into object\n factory Todo.fromMap(Map&lt;String, dynamic&gt; data) =&gt; new Todo(\n     id: data&#91;'id'],\n     itemName: data&#91;'item_name'],\n     dateCreated: data&#91;'date_created']\n );\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Performing basic CRUD operations<\/h2>\n\n\n\n<p>Now that we\u2019ve set up the basic structure along with dependency injection, we can easily perform CRUD operations on our model. Note that the below example methods are redacted and can be used in conjunction with other techniques like Repository pattern.  <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Create<\/strong><\/li><\/ul>\n\n\n\n<p>To create a row in the table, we\u2019re going to use the toMapWithoutId() in the model class- <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Future&lt;int&gt; create(String itemName, String dateCreated) async{\n    final todo = new Todo(itemName: itemName, dateCreated: dateCreated);\n    \/\/databaseHelper has been injected in the class\n    int id = await _databaseHelper.db.insert(\u201ctodos\u201d, todo.toMapWithoutId());\n    return id;\n}<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Read<\/strong><\/li><li><\/li><\/ul>\n\n\n\n<p>To read a single record, we\u2019ll write a raw SQL query. This query will return a List of Maps. The maps are nothing but rows in the table and we\u2019ll use the Todo.fromMap() factory method to get our desired objects.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Future&lt;int&gt; getItemById(int id) async{\n    \/\/databaseHelper has been injected in the class\nList&lt;Map&gt; list = await _databaseHelper.db.rawQuery(\"Select * from todos where id = ?\",&#91;id]);\nif(list.length &gt; 0){\n    return Todo.fromMap(list&#91;0]);\n}    \n    return null;\n}<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li> <strong>Update<\/strong><\/li><\/ul>\n\n\n\n<p>To update data, use the update() method from the SQFlite package. Note that you must always use where clause to avoid undesirable effects.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Future&lt;int&gt; updateItem(Todo item) async {\n     \/\/databaseHelper has been injected in the class\n     return await _databaseHelper.db.update(\"todos\", item.toMap(),\n                 where: \"id = ?\", whereArgs: &#91;item.id]);\n\n}<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Delete<\/strong><\/li><\/ul>\n\n\n\n<p>Delete is rather simple. Just pass the column name and its value in the where clause. Note that you must always use where clause to avoid undesirable effects.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Future&lt;int&gt; deleteItem(int id) async {\n\nreturn await _databaseHelper.db.delete(\"todos\", \n                 where: \"id = ?\", whereArgs: &#91;id]);\n}<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li><strong> Update the main() <\/strong><\/li><\/ul>\n\n\n\n<p>In order to initialize the db when the app starts, we need to call the init() method of the Injection class.<\/p>\n\n\n\n<p>This is how your main() method should look like-<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void main() async {\n WidgetsFlutterBinding.ensureInitialized();\n await Injection.initInjection();\n runApp(MyApp());\n}<\/code><\/pre>\n\n\n\n<p>Setting up a local database is the most crucial part of any application development which stores a lot of data along with offline capabilities.  We have demonstrated how one can implement CRUD operations against the  SQLite database system. <\/p>\n\n\n\n<p><em>Looking to get an offline Flutter app with SQFlite? Hire one of the best <a href=\"https:\/\/Citrusleaf.in\">Flutter app development companies<\/a>! Reach out to us at hello@citrusleaf.in<\/em> <\/p>\n","protected":false},"excerpt":{"rendered":"<p>The soaring technology trend in the mobile app industry is nothing but Flutter, a cross-platform SDK launched by Google. With its cross-platform features and easy to implement methods, Flutter has attracted the interest of many&hellip; <\/p>\n","protected":false},"author":2,"featured_media":739,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[7,10],"tags":[19,52,71,70,68,69],"class_list":["post-736","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","category-development","tag-flutter","tag-flutter-app-develoment","tag-flutter-app-development-company-india","tag-flutter-mobile-app","tag-sqflite-flutter","tag-sqflite-flutter-tutorial"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/citrusleaf.in\/blog\/wp-content\/uploads\/2019\/12\/SQFLite-Flutter-tutorial-introduction-citrusleaf.jpg?fit=1200%2C630&ssl=1","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pei5Vv-bS","_links":{"self":[{"href":"https:\/\/citrusleaf.in\/blog\/wp-json\/wp\/v2\/posts\/736","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/citrusleaf.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/citrusleaf.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/citrusleaf.in\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/citrusleaf.in\/blog\/wp-json\/wp\/v2\/comments?post=736"}],"version-history":[{"count":8,"href":"https:\/\/citrusleaf.in\/blog\/wp-json\/wp\/v2\/posts\/736\/revisions"}],"predecessor-version":[{"id":1921,"href":"https:\/\/citrusleaf.in\/blog\/wp-json\/wp\/v2\/posts\/736\/revisions\/1921"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/citrusleaf.in\/blog\/wp-json\/wp\/v2\/media\/739"}],"wp:attachment":[{"href":"https:\/\/citrusleaf.in\/blog\/wp-json\/wp\/v2\/media?parent=736"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/citrusleaf.in\/blog\/wp-json\/wp\/v2\/categories?post=736"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/citrusleaf.in\/blog\/wp-json\/wp\/v2\/tags?post=736"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}