Khrisna Indrawan Eka Putra
Head of Reviewer - Dicoding Indonesia
A database is an organized collection of structured information, or data,
typically stored electronically in a computer system.
Data within the most common types of databases in operation today is
typically modeled in rows and columns in a series of tables to make
processing and data querying efficient.
https://www.oracle.com/database/what-is-database/
● Relational databases
● Object-oriented databases
● Distributed databases
● NoSQL databases
● Graph databases
● etc.
● Shared Preferences
● Setting Preferences
● SQLite
● Content Provider
● Internal/External Storage
Data Storage in Android
Storage Type Type of Data Saved Length of Time Saved
onSavedInstanceState Key-value Only when the application is opened
SharedPreferences Key-value Until the application is uninstalled / clear data
SQLite Database Local database Until the application is uninstalled / clear data
Internal/External
Storage
Multimedia or files Until the application is uninstalled / clear data
Network/Server Online database As long as the server is active
● Store data with primitive data types such as
boolean, int, long, or strings that are not related
to each other.
● The concept used in this type is a key-value pair.
● Usually used to save settings/configurations and
session.
Shared Preferences
var sharedPref: = getSharedPreferences(
"my_pref", Context.MODE_PRIVATE)
● Create Shared Preference
val editor: SharedPreferences.Editor = sharedPref.edit()
editor.putString(NAME, "Arif")
editor.putInt(AGE, 22)
editor.apply() // OR : editor.commit()
● Save Data
var name = sharedPref.getString(NAME, "")
var name = sharedPref.getString(AGE, 0)
● Get Data
Shared Preference Example
● Settings allow users to change the functionality and behavior of
an application. Such as changing theme, language, etc.
● The recommended way to integrate user configurable settings
into your application is to use the AndroidX Preference Library.
● This library manages the user interface and interacts with
storage so that you define only the individual settings that user
can configure.
● The library comes with a Material theme that provides a
consistent user experience across devices and OS versions.
Setting Preferences Example
<PreferenceScreen ...>
...
<EditTextPreference
android:key="@string/key_phone"
android:singleLine="true"
android:summary="@string/nothing"
android:title="@string/phone_number"
app:iconSpaceReserved="false" />
<CheckBoxPreference
android:defaultValue="false"
android:key="@string/key_love"
android:title="@string/is_love"
app:iconSpaceReserved="false" />
</PreferenceScreen>
Preferences Screen
Inflate Preference Screen
class MyPreferenceFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(bundle: Bundle?, s: String?) {
addPreferencesFromResource(R.xml.preferences)
...
}
}
supportFragmentManager
.beginTransaction()
.add(R.id.setting_holder, MyPreferenceFragment())
.commit()
● Create Fragment Extend to PreferenceFragmentCompat
● Add Fragment in Activity
Preference Screen & Shared Preference
<EditTextPreference
android:key="phone"
android:title="@string/phone_number" />
val pref = preferenceManager.sharedPreferences
phonePreference.summary = pref.getString("phone", DEFAULT_VALUE)
● Preference Key
● Read Data from SharedPreference
val phonePreference: EditTextPreference> = findPreference("phone")
● Initiate Preference Component
Listen for Changes to Preference Values
class MyPreferenceFragment : PreferenceFragmentCompat(),
SharedPreferences.OnSharedPreferenceChangeListener {
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
if (key == PHONE) {
phonePreference.summary = sharedPreferences.getString(PHONE, DEFAULT_VALUE)
}
}
override fun onResume() {
super.onResume()
preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
}
override fun onPause() {
super.onPause()
preferenceScreen.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
}
}
● SQLite is an open source database that supports standard
relationship operations commonly found in database engines
such as SQL syntax and transaction operations.
● Even though it runs like a database, sqlite is generally small in
size and can run on devices with limited memory such as
smartphones.
● SQLite is included by default on all Android devices and most
importantly no authentication process or administrative setup
is required as is done in large-scale database software.
SQLite
● User Experience (Not waiting loading with Blank Screen)
● Battery life
● Saving quota
● Reduce server load and network bandwidth
● Run without internet connection area
Why We Need Local Database?
Table Example
id title author genre pages
1 Clean Code: A Handbook of Agile Software Craftsmanship Robert C. Martin Programming 434
2 A Brief History of Time Stephen Hawking Science 212
3 Rich Dad, Poor Dad Robert T. Kiyosaki Business 195
4 The 7 Habits of Highly Effective People Stephen Covey Self-help 372
5 The Rainbow Troops Andrea Hirata Novel 304
class BookContract {
class BookEntry : BaseColumns {
companion object {
val TABLE_NAME = "book"
val COLUMN_TITLE = "title"
val COLUMN_AUTHOR = "author"
val COLUMN_GENRE = "genre"
val COLUMN_PAGES = "pages"
}
}
}
id title author genre pages
Database Contract
SQLiteOpenHelper
class BooksHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null,
DATABASE_VERSION) {
companion object {
val DATABASE_VERSION = 1
val DATABASE_NAME = "Book.db"
}
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(SQL_CREATE_ENTRIES)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL(SQL_DELETE_ENTRIES)
onCreate(db)
}
}
Basic Database
private val SQL_CREATE_ENTRIES="CREATE TABLE ${BookEntry.TABLE_NAME}"+
" (${BookEntry._ID} INTEGER PRIMARY KEY," +
" ${BookEntry.COLUMN_TITLE} TEXT," +
" ${BookEntry.COLUMN_AUTHOR} TEXT," +
" ${BookEntry.COLUMN_GENRE} TEXT," +
" ${BookEntry.COLUMN_PAGES} INT)"
● Create Database: "CREATE TABLE book (id INTEGER PRIMARY KEY, title
TEXT, author TEXT, genre TEXT, pages INT)"
private val SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS
$BookEntry.TABLE_NAME"
● Delete Database: "DROP TABLE IF EXISTS book"
Insert Database
// Gets the data repository in write mode
val dbHelper: BooksHelper = BooksHelper(this)
val db: SQLiteDatabase = dbHelper.getWritableDatabase()
// Create a new map of values, where column names are the keys
val values = ContentValues()
values.put(BookEntry.COLUMN_TITLE, "Clean Code")
values.put(BookEntry.COLUMN_AUTHOR, "Robert C. Martin")
values.put(BookEntry.COLUMN_GENRE, "Programming")
values.put(BookEntry.COLUMN_PAGES, 434)
// Insert the new row, returning the primary key value of the new row
val newRowId: Long = db.insert(BookEntry.TABLE_NAME, null, values)
Read Database
val db: SQLiteDatabase = dbHelper.getReadableDatabase()
val cursor: Cursor = db.query(
BookEntry.TABLE_NAME, // table
null, // column
null, // selection
null, // selectionArgs
null, // groupBy
null, // having
null, // orderBy
null // limit
)
Convert Cursor to List
val bookList = ArrayList<Book>()
cursor?.apply {
while (moveToNext()) {
val id = getInt(getColumnIndexOrThrow(BookEntry._ID))
val title = getString(getColumnIndexOrThrow(BookEntry.COLUMN_TITLE))
...
bookList.add(Book(id, title, author, genre))
}
}
Update Database
val db = dbHelper.getWritableDatabase()
val values = ContentValues()
values.put(BookEntry.COLUMN_TITLE, "Clean Architecture") // new value
val selection = BookEntry.COLUMN_GENRE + " = ?"
val selectionArgs = { "Programming" }
int count = db.update(
BookColums.TABLE_NAME,
values,
selection,
selectionArgs
)
Delete Database
// Define 'where' part of query.
val selection = BookColums.COLUMN_AUTHOR + " LIKE ?"
// Specify arguments in placeholder order.
val selectionArgs = { "Hirata" }
// Execute SQL statement
db.delete(
BookColums.TABLE_NAME,
selection,
selectionArgs
)
Raw Query
db.rawQuery("SELECT * FROM book WHERE genre = programming ORDER BY pages
DESC LIMIT 3", null)
● SELECT columns—select the columns to return, use * to return all columns
● FROM table—specify the table from which to get results
● WHERE—keyword for conditions that have to be met
● column="value"—the condition that has to be met. operators: =, LIKE, <, >
● ORDER BY—omit for default order, or ASC for ascending, DESC for
descending
● LIMIT—get a limited number of results
REPLACE ME
Contact:
(khrisna@dicoding.com)
Follow us: @dicoding

Dicoding Developer Coaching #19: Android | Menyimpan Database Secara Local di Aplikasi Androidmu

  • 1.
    Khrisna Indrawan EkaPutra Head of Reviewer - Dicoding Indonesia
  • 2.
    A database isan organized collection of structured information, or data, typically stored electronically in a computer system. Data within the most common types of databases in operation today is typically modeled in rows and columns in a series of tables to make processing and data querying efficient. https://www.oracle.com/database/what-is-database/
  • 3.
    ● Relational databases ●Object-oriented databases ● Distributed databases ● NoSQL databases ● Graph databases ● etc.
  • 4.
    ● Shared Preferences ●Setting Preferences ● SQLite ● Content Provider ● Internal/External Storage
  • 5.
    Data Storage inAndroid Storage Type Type of Data Saved Length of Time Saved onSavedInstanceState Key-value Only when the application is opened SharedPreferences Key-value Until the application is uninstalled / clear data SQLite Database Local database Until the application is uninstalled / clear data Internal/External Storage Multimedia or files Until the application is uninstalled / clear data Network/Server Online database As long as the server is active
  • 6.
    ● Store datawith primitive data types such as boolean, int, long, or strings that are not related to each other. ● The concept used in this type is a key-value pair. ● Usually used to save settings/configurations and session. Shared Preferences
  • 7.
    var sharedPref: =getSharedPreferences( "my_pref", Context.MODE_PRIVATE) ● Create Shared Preference val editor: SharedPreferences.Editor = sharedPref.edit() editor.putString(NAME, "Arif") editor.putInt(AGE, 22) editor.apply() // OR : editor.commit() ● Save Data var name = sharedPref.getString(NAME, "") var name = sharedPref.getString(AGE, 0) ● Get Data Shared Preference Example
  • 8.
    ● Settings allowusers to change the functionality and behavior of an application. Such as changing theme, language, etc. ● The recommended way to integrate user configurable settings into your application is to use the AndroidX Preference Library. ● This library manages the user interface and interacts with storage so that you define only the individual settings that user can configure. ● The library comes with a Material theme that provides a consistent user experience across devices and OS versions. Setting Preferences Example
  • 9.
  • 10.
    Inflate Preference Screen classMyPreferenceFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(bundle: Bundle?, s: String?) { addPreferencesFromResource(R.xml.preferences) ... } } supportFragmentManager .beginTransaction() .add(R.id.setting_holder, MyPreferenceFragment()) .commit() ● Create Fragment Extend to PreferenceFragmentCompat ● Add Fragment in Activity
  • 11.
    Preference Screen &Shared Preference <EditTextPreference android:key="phone" android:title="@string/phone_number" /> val pref = preferenceManager.sharedPreferences phonePreference.summary = pref.getString("phone", DEFAULT_VALUE) ● Preference Key ● Read Data from SharedPreference val phonePreference: EditTextPreference> = findPreference("phone") ● Initiate Preference Component
  • 12.
    Listen for Changesto Preference Values class MyPreferenceFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPreferenceChangeListener { override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { if (key == PHONE) { phonePreference.summary = sharedPreferences.getString(PHONE, DEFAULT_VALUE) } } override fun onResume() { super.onResume() preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this) } override fun onPause() { super.onPause() preferenceScreen.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) } }
  • 13.
    ● SQLite isan open source database that supports standard relationship operations commonly found in database engines such as SQL syntax and transaction operations. ● Even though it runs like a database, sqlite is generally small in size and can run on devices with limited memory such as smartphones. ● SQLite is included by default on all Android devices and most importantly no authentication process or administrative setup is required as is done in large-scale database software. SQLite
  • 14.
    ● User Experience(Not waiting loading with Blank Screen) ● Battery life ● Saving quota ● Reduce server load and network bandwidth ● Run without internet connection area Why We Need Local Database?
  • 15.
    Table Example id titleauthor genre pages 1 Clean Code: A Handbook of Agile Software Craftsmanship Robert C. Martin Programming 434 2 A Brief History of Time Stephen Hawking Science 212 3 Rich Dad, Poor Dad Robert T. Kiyosaki Business 195 4 The 7 Habits of Highly Effective People Stephen Covey Self-help 372 5 The Rainbow Troops Andrea Hirata Novel 304
  • 16.
    class BookContract { classBookEntry : BaseColumns { companion object { val TABLE_NAME = "book" val COLUMN_TITLE = "title" val COLUMN_AUTHOR = "author" val COLUMN_GENRE = "genre" val COLUMN_PAGES = "pages" } } } id title author genre pages Database Contract
  • 17.
    SQLiteOpenHelper class BooksHelper(context: Context): SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) { companion object { val DATABASE_VERSION = 1 val DATABASE_NAME = "Book.db" } override fun onCreate(db: SQLiteDatabase) { db.execSQL(SQL_CREATE_ENTRIES) } override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { db.execSQL(SQL_DELETE_ENTRIES) onCreate(db) } }
  • 18.
    Basic Database private valSQL_CREATE_ENTRIES="CREATE TABLE ${BookEntry.TABLE_NAME}"+ " (${BookEntry._ID} INTEGER PRIMARY KEY," + " ${BookEntry.COLUMN_TITLE} TEXT," + " ${BookEntry.COLUMN_AUTHOR} TEXT," + " ${BookEntry.COLUMN_GENRE} TEXT," + " ${BookEntry.COLUMN_PAGES} INT)" ● Create Database: "CREATE TABLE book (id INTEGER PRIMARY KEY, title TEXT, author TEXT, genre TEXT, pages INT)" private val SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS $BookEntry.TABLE_NAME" ● Delete Database: "DROP TABLE IF EXISTS book"
  • 19.
    Insert Database // Getsthe data repository in write mode val dbHelper: BooksHelper = BooksHelper(this) val db: SQLiteDatabase = dbHelper.getWritableDatabase() // Create a new map of values, where column names are the keys val values = ContentValues() values.put(BookEntry.COLUMN_TITLE, "Clean Code") values.put(BookEntry.COLUMN_AUTHOR, "Robert C. Martin") values.put(BookEntry.COLUMN_GENRE, "Programming") values.put(BookEntry.COLUMN_PAGES, 434) // Insert the new row, returning the primary key value of the new row val newRowId: Long = db.insert(BookEntry.TABLE_NAME, null, values)
  • 20.
    Read Database val db:SQLiteDatabase = dbHelper.getReadableDatabase() val cursor: Cursor = db.query( BookEntry.TABLE_NAME, // table null, // column null, // selection null, // selectionArgs null, // groupBy null, // having null, // orderBy null // limit )
  • 21.
    Convert Cursor toList val bookList = ArrayList<Book>() cursor?.apply { while (moveToNext()) { val id = getInt(getColumnIndexOrThrow(BookEntry._ID)) val title = getString(getColumnIndexOrThrow(BookEntry.COLUMN_TITLE)) ... bookList.add(Book(id, title, author, genre)) } }
  • 23.
    Update Database val db= dbHelper.getWritableDatabase() val values = ContentValues() values.put(BookEntry.COLUMN_TITLE, "Clean Architecture") // new value val selection = BookEntry.COLUMN_GENRE + " = ?" val selectionArgs = { "Programming" } int count = db.update( BookColums.TABLE_NAME, values, selection, selectionArgs )
  • 24.
    Delete Database // Define'where' part of query. val selection = BookColums.COLUMN_AUTHOR + " LIKE ?" // Specify arguments in placeholder order. val selectionArgs = { "Hirata" } // Execute SQL statement db.delete( BookColums.TABLE_NAME, selection, selectionArgs )
  • 25.
    Raw Query db.rawQuery("SELECT *FROM book WHERE genre = programming ORDER BY pages DESC LIMIT 3", null) ● SELECT columns—select the columns to return, use * to return all columns ● FROM table—specify the table from which to get results ● WHERE—keyword for conditions that have to be met ● column="value"—the condition that has to be met. operators: =, LIKE, <, > ● ORDER BY—omit for default order, or ASC for ascending, DESC for descending ● LIMIT—get a limited number of results
  • 26.