Preamble
When writing a moblie app you often find that you need to save data between app launches. If the data is simple enough as some app settings, login information, .. you can save them as key-values in sharedPreferences. But when the data needs to be more complex and interdependent, we will need to use a more formal data storage system – the database. Database generally provides faster insertion, update and query than other local storage methods (file, sharedpreferences, …).
Like native Android or IOS programming, Flutter also uses SQlite – the most popular option for database management. In this article, I will show you how to manage database with spflite plugin. Sqflite is a popular plugin and is introduced on flutter’s document so you can safely use it
A few things about SQFLite
- SQFLite supports iOS, Android and MacOS, does not support web platform.
- Support transctions and batches.
- Automatic version management
- There is a helper for insert, query, update, delete queries
- DB operation is performed in the background thread on iOS and Android
Data types supported by sqlite:
- Integer: Dart type – int
- Real: Dart type – num
- Text: Dart type – String
- Blob: Dart type – Uint8List
Unsupported DateTime -> can be saved as millisSinceEpoch or String.
Bool is not supported -> use a different type instead, for example 0 or 1
For example
We will go into a specific example to understand it more easily. In this example we will save the information of a movie model to the database when we press favorite.
First we need
Add the necessary dependencies to the pubspec.yaml file
1 2 3 4 5 6 7 | dependencies <span class="token punctuation">:</span> flutter <span class="token punctuation">:</span> sdk <span class="token punctuation">:</span> flutter sqflite <span class="token punctuation">:</span> <span class="token operator">^</span> <span class="token number">1.3</span> <span class="token number">.1</span> path <span class="token punctuation">:</span> <span class="token number">1.6</span> <span class="token number">.4</span> equatable <span class="token punctuation">:</span> <span class="token operator">^</span> <span class="token number">1.1</span> <span class="token number">.1</span> |
Located in the Movie class, specify the information to be stored. Here we will store id, porterPath, title, overview, releaseDate, voteAverage. Where id is a unique field, we will set as a primary key.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <span class="token keyword">class</span> <span class="token class-name">Movie</span> <span class="token keyword">extends</span> <span class="token class-name">Equatable</span> <span class="token punctuation">{</span> int id <span class="token punctuation">;</span> String backdropPath <span class="token punctuation">;</span> List <span class="token operator"><</span> Genre <span class="token operator">></span> genres <span class="token punctuation">;</span> String title <span class="token punctuation">;</span> String overview <span class="token punctuation">;</span> String porterPath <span class="token punctuation">;</span> List <span class="token operator"><</span> Company <span class="token operator">></span> productionCompanies <span class="token punctuation">;</span> String releaseDate <span class="token punctuation">;</span> int runtime <span class="token punctuation">;</span> int revenue <span class="token punctuation">;</span> int budget <span class="token punctuation">;</span> List <span class="token operator"><</span> Video <span class="token operator">></span> videos <span class="token punctuation">;</span> List <span class="token operator"><</span> Actor <span class="token operator">></span> cast <span class="token punctuation">;</span> double voteAverage <span class="token punctuation">;</span> int voteCount <span class="token punctuation">;</span> <span class="token metadata symbol">@override</span> List <span class="token operator"><</span> Object <span class="token operator">></span> <span class="token keyword">get</span> props <span class="token operator">=</span> <span class="token operator">></span> <span class="token punctuation">[</span> id <span class="token punctuation">,</span> title <span class="token punctuation">]</span> <span class="token punctuation">;</span> Map <span class="token operator"><</span> String <span class="token punctuation">,</span> <span class="token keyword">dynamic</span> <span class="token operator">></span> <span class="token function">toMap</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> Map <span class="token operator"><</span> String <span class="token punctuation">,</span> <span class="token keyword">dynamic</span> <span class="token operator">></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">[</span> <span class="token string">"id"</span> <span class="token punctuation">]</span> <span class="token operator">=</span> id <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">[</span> <span class="token string">"poster_path"</span> <span class="token punctuation">]</span> <span class="token operator">=</span> porterPath <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">[</span> <span class="token string">"title"</span> <span class="token punctuation">]</span> <span class="token operator">=</span> title <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">[</span> <span class="token string">"overview"</span> <span class="token punctuation">]</span> <span class="token operator">=</span> overview <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">[</span> <span class="token string">"release_date"</span> <span class="token punctuation">]</span> <span class="token operator">=</span> releaseDate <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">[</span> <span class="token string">"vote_average"</span> <span class="token punctuation">]</span> <span class="token operator">=</span> voteAverage <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> Movie <span class="token function">formJson</span> <span class="token punctuation">(</span> Map <span class="token operator"><</span> String <span class="token punctuation">,</span> <span class="token keyword">dynamic</span> <span class="token operator">></span> json <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">Movie</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> id <span class="token operator">=</span> json <span class="token punctuation">[</span> <span class="token string">"id"</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> title <span class="token operator">=</span> json <span class="token punctuation">[</span> <span class="token string">"title"</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> overview <span class="token operator">=</span> json <span class="token punctuation">[</span> <span class="token string">"overview"</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> porterPath <span class="token operator">=</span> json <span class="token punctuation">[</span> <span class="token string">"poster_path"</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> releaseDate <span class="token operator">=</span> json <span class="token punctuation">[</span> <span class="token string">"release_date"</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> voteAverage <span class="token operator">=</span> json <span class="token punctuation">[</span> <span class="token string">"vote_average"</span> <span class="token punctuation">]</span> <span class="token operator">*</span> <span class="token number">1.0</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Open the database
Before reading and writing data to the database, we need to open a connection:
- Determine the path to the database using getDatabasePath () from the sqflite package, combined with the join function from the package path .
- Open the database with the openDatabase () function of sqflite.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token keyword">const</span> String DB_NAME <span class="token operator">=</span> <span class="token string">"movies_database.db"</span> <span class="token punctuation">;</span> Database _database <span class="token punctuation">;</span> Future <span class="token operator"><</span> Database <span class="token operator">></span> <span class="token keyword">get</span> database <span class="token keyword">async</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> _database <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> _database <span class="token punctuation">;</span> _database <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">_initDatabase</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">return</span> _database <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">_initDatabase</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">async</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">await</span> <span class="token function">openDatabase</span> <span class="token punctuation">(</span> <span class="token function">join</span> <span class="token punctuation">(</span> <span class="token keyword">await</span> <span class="token function">getDatabasesPath</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> DB_NAME <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Create a “favorite” Table
Next, create a table that stores information about favorite Movie.
- id type int -> INTEGER
- porterPath, title, overview, releaseDate of String type -> TEXT
- voteAverage type double -> REAL
1 2 3 4 5 6 7 8 9 10 | <span class="token keyword">const</span> String TABLE_FAVORITE <span class="token operator">=</span> <span class="token string">"favorite"</span> <span class="token punctuation">;</span> db <span class="token punctuation">.</span> <span class="token function">execute</span> <span class="token punctuation">(</span> <span class="token string">"""CREATE TABLE $TABLE_FAVORITE ( id INTEGER PRIMARY KEY, poster_path TEXT, title TEXT, overview TEXT, release_date TEXT, vote_average REAL )"""</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Note: the column name should be the same as the key in the row toMap (), formJson () which makes reading and inserting data easier.
Insert a Movie into the DB
1 2 | <span class="token keyword">await</span> db <span class="token punctuation">.</span> <span class="token function">insert</span> <span class="token punctuation">(</span> TABLE_FAVORITE <span class="token punctuation">,</span> movie <span class="token punctuation">.</span> <span class="token function">toMap</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
The movie is converted to Map () and saved to the TABLE_FAVORITE table, with the key being the name of the column value, which will be the value filled in that column.
You can also specify conflictAlgorithm to use in case the same movie is inserted twice.
Get the saved List Movie
1 2 3 | List <span class="token operator"><</span> Map <span class="token operator"><</span> String <span class="token punctuation">,</span> <span class="token keyword">dynamic</span> <span class="token operator">>></span> maps <span class="token operator">=</span> <span class="token keyword">await</span> db <span class="token punctuation">.</span> <span class="token function">query</span> <span class="token punctuation">(</span> TABLE_FAVORITE <span class="token punctuation">)</span> <span class="token punctuation">;</span> List <span class="token operator"><</span> Movie <span class="token operator">></span> movies <span class="token operator">=</span> maps <span class="token punctuation">.</span> <span class="token function">map</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> e <span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token operator">></span> Movie <span class="token punctuation">.</span> <span class="token function">formJson</span> <span class="token punctuation">(</span> e <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toList</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
The query db.query(TABLE_FAVORITE)
will return the list of records in the DB, each record will be a Map with the key being the column name, the value is the data of that column. What we need to do then is just convert to List <Movie> and use it.
Movie Updata is already in the table
1 2 3 4 | <span class="token keyword">final</span> db <span class="token operator">=</span> <span class="token keyword">await</span> database <span class="token punctuation">;</span> <span class="token keyword">final</span> result <span class="token operator">=</span> <span class="token keyword">await</span> db <span class="token punctuation">.</span> <span class="token function">update</span> <span class="token punctuation">(</span> TABLE_FAVORITE <span class="token punctuation">,</span> movie <span class="token punctuation">.</span> <span class="token function">toMap</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> where <span class="token punctuation">:</span> <span class="token string">"id = ?"</span> <span class="token punctuation">,</span> whereArgs <span class="token punctuation">:</span> <span class="token punctuation">[</span> movie <span class="token punctuation">.</span> id <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
The update record has id == movie.id with the new data movie.toMap ().
Delete movie
1 2 3 | <span class="token keyword">final</span> db <span class="token operator">=</span> <span class="token keyword">await</span> database <span class="token punctuation">;</span> <span class="token keyword">final</span> result <span class="token operator">=</span> <span class="token keyword">await</span> db <span class="token punctuation">.</span> <span class="token function">delete</span> <span class="token punctuation">(</span> TABLE_FAVORITE <span class="token punctuation">,</span> where <span class="token punctuation">:</span> <span class="token string">"id = ?"</span> <span class="token punctuation">,</span> whereArgs <span class="token punctuation">:</span> <span class="token punctuation">[</span> movie <span class="token punctuation">.</span> id <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Delete record has id == movie.id
Close the DB
Normally the DB will be closed when you turn off the app. However, if you want to release resources, you can close the DB by
1 2 | <span class="token keyword">await</span> db <span class="token punctuation">.</span> <span class="token function">close</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Conclude
Above I just presented a simple way of using SQLite in a Flutter application. The code of the above example section you can see the details here .
If the above is too simple, you want to learn more, you can play with the pagkage sqflite here.
Thank you for watching the article !!