Mobile Programming SQLite Database for Data Storage and
Mobile Programming SQLite Database for Data Storage and Retrieval
Data Storage in Android provides several options for you to save your app data. The solution you choose depends on your specific needs, such as how much space your data requires, what kind of data you need to store. Different data storage options available on Android: Internal file storage: Store app-private files on the device file system. External file storage: Store files on the shared external file system. This is usually for shared user files, such as photos. Shared preferences: Store private primitive data in key-value pairs. Databases: Store structured data in a private database. Except for some types of files on external storage, all these options are intended for app-private data the data is not naturally accessible to other apps.
SQLite Database for Data Storage and Retrieval SQLite is very lightweight, open source, relational database that comes with Android OS. In Android, integrating SQLite is a tedious task as it needs writing lot of boilerplate code to store simple data. Consider SQLite when your app needs to store simple and structured data objects. Alternatively, Room Persistence Library could be used for better APIs and easier integration.
SQLite Challenges Handling an SQLite database in Android implies some challenges like: Boilerplate code to convert SQL queries to Java Data objects Database operations on the main thread Unmaintainable code - As your schema changes you need to update the affected SQL queries manually. SQL queries checked at runtime (No compile time verification of SQL queries) Untestable code
Room Persistence Library Room is an abstraction on top of SQLite database. It's part of the Architecture Components by Google. Room enables you to easily work SQLite databases in Android. The Room persistence library acts as a layer that abstracts raw SQLite and lets you make use of robust database access while keep you close to SQLite so it doesn't get in the way when you want to access low level features of SQLite.
Components of Room Library
Contd. There are 3 major components in Room: Database: Contains the database holder and serves as the main access point for the underlying connection to your app's persisted, relational data. Entity: Represents a table within the database. DAO: Contains the methods used for accessing the database.
Contd.
Making an app that uses SQLite Database to store data Add Dependencies Add Room Entities Add DAO Class Build Database
Add Dependencies Open the application level build. gradle file and the dependencies for Room: implementation "android. arch. persistence. room: runtime: 1. 1. 0" annotation. Processor "android. arch. persistence. room: compiler: 1. 1. 0" test. Implementation "android. arch. persistence. room: testing: 1. 1. 0"
Adding Room Entities @Entity public class Task { @Primary. Key(auto. Generate = true) private int id; @Column. Info(name = "task") private String task; @Column. Info(name = "desc") private String desc; //Getters and Setters public int get. Id() { return id; } public void set. Id(int id) { this. id = id; } public String get. Task() { return task; } public void set. Task(String task) { this. task = task; } public String get. Desc() { return desc; } public void set. Desc(String desc) { this. desc = desc; } }
Contd. @Entity – by using this annotation, Room will know that this class will be a table in the database and the table. Name will define the name of the table @Primary. Key – is used to set up the primary key of the table. @Column. Info – defines the name of the column from the table if we don’t want to use the name of that field You also need to add getters and setters.
Creating DAO Class @Dao public interface Task. Dao { @Query("SELECT * FROM task") List<Task> get. All(); @Insert void insert(Task task); @Delete void delete(Task task); @Update void update(Task task); }
Contd. @Dao – by using this annotation Room knows that it should provide the implementation for our interface by generating code for the defined methods. In this interface we could define the CRUD operations for our entity and also any other operations that are necessary in order to obtain the data. Also Room offers us query validation at compilation time, so if we will write incorrectly the name of a table or a field we will know if after the code will be compiled.
Database. The class should be annotated with @Database Inside of the @Database annotation Define the list of the entities we want to be saved in the database And also the version of the current database (This number will help us to make the migrations in Room) Be an abstract class that extends Room. Database. Contains abstract methods in order to have references to our Dao classes And also we should create an instance of the database. We have 2 possibilities to build the database by using: database. Builder that creates a Room. Database. Builder for a persistent database in. Memory. Database. Builder that creates a Room. Database. Builder for a in-memory database, if we don’t want to persist the data
Contd. @Database(entities = {Task. class}, version = 1) public abstract class App. Database extends Room. Database { public abstract Task. Dao task. Dao(); private static App. Database INSTANCE; public static App. Database get. App. Database(Context context) { if (INSTANCE == null) { INSTANCE = Room. database. Builder(context. get. Application. Context(), App. Database. class, “task-db”). build(); } return INSTANCE; }
Accessing Database private void get. Tasks() { class Get. Tasks extends Async. Task<Void, List<Task>> { @Override protected List<Task> do. In. Background(Void. . . voids) { task. List= App. Database. get. App. Database(get. Application. Context()). task. Dao(). get. All(); return task. List; } @Override protected void on. Post. Execute(List<Task> tasks) { super. on. Post. Execute(tasks); Array. List<String> names = new Array. List(); for(Task t: tasks){ names. add(t. get. Task()); } Array. Adapter<String> adapter = new Array. Adapter<String>(Main. Activity. this, android. R. layout. simple_list_item_1, android. R. id. text 1, names); lv. set. Adapter(adapter); } } Get. Tasks gt = new Get. Tasks(); gt. execute(); }
private void save. Task() { final String s. Task = edit. Text. Task. get. Text(). to. String(). trim(); final String s. Desc = edit. Text. Desc. get. Text(). to. String(). trim(); if (s. Task. is. Empty()) { edit. Text. Task. set. Error("Task required"); edit. Text. Task. request. Focus(); return; } if (s. Desc. is. Empty()) { edit. Text. Desc. set. Error("Desc required"); edit. Text. Desc. request. Focus(); return; } class Save. Task extends Async. Task<Void, Void> { @Override protected Void do. In. Background(Void. . . voids) { //creating a task Task task = new Task(); task. set. Task(s. Task); task. set. Desc(s. Desc); //adding to database App. Database. get. App. Database(get. Application. Context()). task. Dao(). insert(task); return null; } @Override protected void on. Post. Execute(Void a. Void) { super. on. Post. Execute(a. Void); finish(); start. Activity(new Intent(get. Application. Context(), Main. Activity. class)); Toast. make. Text(get. Application. Context(), "Saved", Toast. LENGTH_LONG). show(); } } Save. Task st = new Save. Task(); st. execute(); }
Thank You!
- Slides: 19