The SQLite library is a core part of the Android environment. Java applications and content providers access SQLite using the interface in the
android.sqlite.database
namespace.One disadvantage of using Android's built-in SQLite support is that the application is forced to use the version of SQLite that the current version of Android happened to ship with. If your application happens to require a newer version of SQLite, or a build with a custom extension or VFS installed, you're out of luck.
In this post, I will present a simple project about creating and managing a SQLite database which contains only one table, for beginners can approach this hard and important matter. You can see this DEMO VIDEO first for project output:
Creating Database
public class Friend { private int id; private String name; private String job; public Friend() {} public Friend(String name, String job) { this.name = name; this.job = job; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } }And we would like to save each POJO object to database as a table, this is it's structure:
Field
|
Data Type
|
Key
|
ID
|
int
|
Primary
|
Name
|
Text
|
|
Job
|
Text
|
SQLiteOpenHelper
, which provided by Android SDK. Moreover, we also need to write our own methods to handle all database CRUD(Create, Read, Update and Delete) operations. After creating, we have to override 2 requirement methods:-
onCreate()
: These is where we need to write create table statements. This is called when database is created. -
onUpgrade()
: This method is called when database is upgraded like modifying the table structure, adding constraints to database,...
public class DatabaseHelper extends SQLiteOpenHelper { private static final int DATABASE_VERSION = 1; private static final String DATABASE_NAME = "myFriendDB"; // Friend table name private static final String TABLE_FRIEND = "friend"; private static final String KEY_ID = "id"; private static final String KEY_NAME = "name"; private static final String KEY_JOB = "job"; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { String CREATE_FRIEND_TABLE = "CREATE TABLE " + TABLE_FRIEND + "(" + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT," + KEY_JOB + " TEXT" + ")"; db.execSQL(CREATE_FRIEND_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // Drop older table if existed db.execSQL("DROP TABLE IF EXISTS " + TABLE_FRIEND); // Create tables again onCreate(db); } }
Inserting a new record
getWritableDatabase()
, use ContentValues
to put each record field data and after that, calling insert()
to complete our work:
public void addNewFriend(Friend friend) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(KEY_NAME, friend.getName()); values.put(KEY_JOB, friend.getJob()); // inserting this record db.insert(TABLE_FRIEND, null, values); db.close(); // Closing database connection }
Deleting a record
public void deleteFriend(Friend friend) { SQLiteDatabase db = this.getWritableDatabase(); db.delete(TABLE_FRIEND, KEY_ID + " = ?", new String[]{String.valueOf(friend.getId())}); db.close(); }
Updating a record
update()
method of SQLiteOpenHelper
:
public int updateFriend(Friend friend) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(KEY_NAME, friend.getName()); values.put(KEY_JOB, friend.getJob()); // updating row return db.update(TABLE_FRIEND, values, KEY_ID + " = ?", new String[]{String.valueOf(friend.getId())}); }
Getting all records
Cursor
object to browse through all the elements of the table:
public List<Friend> getAllFriends() { List<Friend> friendList = new ArrayList<>(); // select query String selectQuery = "SELECT * FROM " + TABLE_FRIEND; SQLiteDatabase db = this.getWritableDatabase(); Cursor cursor = db.rawQuery(selectQuery, null); // looping through all table records and adding to list if (cursor.moveToFirst()) { do { Friend friend = new Friend(); friend.setId(Integer.parseInt(cursor.getString(0))); friend.setName(cursor.getString(1)); friend.setJob(cursor.getString(2)); // Adding friend to list friendList.add(friend); } while (cursor.moveToNext()); } return friendList; }Over here, adding some necessary methods, we have full code for SQLite database file:
package info.devexchanges.androidsqlitedatabase; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import java.util.ArrayList; import java.util.List; public class DatabaseHelper extends SQLiteOpenHelper { private static final int DATABASE_VERSION = 1; private static final String DATABASE_NAME = "myFriendDB"; // Friend table name private static final String TABLE_FRIEND = "friend"; private static final String KEY_ID = "id"; private static final String KEY_NAME = "name"; private static final String KEY_JOB = "job"; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { String CREATE_FRIEND_TABLE = "CREATE TABLE " + TABLE_FRIEND + "(" + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT," + KEY_JOB + " TEXT" + ")"; db.execSQL(CREATE_FRIEND_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // Drop older table if existed db.execSQL("DROP TABLE IF EXISTS " + TABLE_FRIEND); // Create tables again onCreate(db); } // Adding a new record (friend) to table public void addNewFriend(Friend friend) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(KEY_NAME, friend.getName()); values.put(KEY_JOB, friend.getJob()); // inserting this record db.insert(TABLE_FRIEND, null, values); db.close(); // Closing database connection } // Getting All Friends in Table of Database public List<Friend> getAllFriends() { List<Friend> friendList = new ArrayList<>(); // select query String selectQuery = "SELECT * FROM " + TABLE_FRIEND; SQLiteDatabase db = this.getWritableDatabase(); Cursor cursor = db.rawQuery(selectQuery, null); // looping through all table records and adding to list if (cursor.moveToFirst()) { do { Friend friend = new Friend(); friend.setId(Integer.parseInt(cursor.getString(0))); friend.setName(cursor.getString(1)); friend.setJob(cursor.getString(2)); // Adding friend to list friendList.add(friend); } while (cursor.moveToNext()); } return friendList; } // Updating a record in database table public int updateFriend(Friend friend) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(KEY_NAME, friend.getName()); values.put(KEY_JOB, friend.getJob()); // updating row return db.update(TABLE_FRIEND, values, KEY_ID + " = ?", new String[]{String.valueOf(friend.getId())}); } // Deleting a record in database table public void deleteFriend(Friend friend) { SQLiteDatabase db = this.getWritableDatabase(); db.delete(TABLE_FRIEND, KEY_ID + " = ?", new String[]{String.valueOf(friend.getId())}); db.close(); } // getting number of records in table public int getContactsCount() { SQLiteDatabase db = this.getReadableDatabase(); Cursor dataCount = db.rawQuery("select " + KEY_ID + " from " + TABLE_FRIEND, null); int count = dataCount.getCount(); dataCount.close(); db.close(); return count; } }
Usage in Interface
ListView
. Further, I design a button in ActionBar
(through create options menu) to inserting a new record (see this post to learn about Menus
in android). Firstly, make it's layout which contains only a ListView
like this:
And this is completed programmatically code for the
Activity
. In this, the we locate the option menu in ActionBar
and handle it event (inserting a new record):package info.devexchanges.androidsqlitedatabase; import android.content.DialogInterface; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private ListView listView; private ListViewAdapter adapter; private DatabaseHelper databaseHelper; private List<Friend> friendList; private TextView title; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView) findViewById(R.id.list_view); title = (TextView)findViewById(R.id.total); databaseHelper = new DatabaseHelper(this); friendList = new ArrayList<>(); reloadingDatabase(); //loading table of DB to ListView } public void reloadingDatabase() { friendList = databaseHelper.getAllFriends(); if (friendList.size() == 0) { Toast.makeText(this, "No record found in database!", Toast.LENGTH_SHORT).show(); title.setVisibility(View.GONE); } adapter = new ListViewAdapter(this, R.layout.item_listview, friendList, databaseHelper); listView.setAdapter(adapter); title.setVisibility(View.VISIBLE); title.setText("Total records: " + databaseHelper.getContactsCount()); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.add) { addingNewFriendDialog(); return true; } return super.onOptionsItemSelected(item); } private void addingNewFriendDialog() { AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this); alertDialog.setTitle("Add a new Friend"); LinearLayout layout = new LinearLayout(this); layout.setPadding(10, 10, 10, 10); layout.setOrientation(LinearLayout.VERTICAL); final EditText nameBox = new EditText(this); nameBox.setHint("Name"); layout.addView(nameBox); final EditText jobBox = new EditText(this); jobBox.setHint("job"); layout.addView(jobBox); alertDialog.setView(layout); alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Friend friend = new Friend(getText(nameBox), getText(jobBox)); databaseHelper.addNewFriend(friend); reloadingDatabase(); //reload the db to view } }); alertDialog.setNegativeButton("Cancel", null); //show alert alertDialog.show(); } //get text available in TextView/EditText private String getText(TextView textView) { return textView.getText().toString().trim(); } }In each
ListView
row, we have a edit button (to update row information) and a delete button to remove a record from table. So, we custom an adapter as a subclass of ArrayAdapter
and handle multiple objects event (click) located on each row. We have this full code, more details, see my comments in it:
package info.devexchanges.androidsqlitedatabase; import android.app.Activity; import android.content.DialogInterface; import android.support.v7.app.AlertDialog; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import java.util.List; public class ListViewAdapter extends ArrayAdapter<Friend> { private MainActivity activity; private DatabaseHelper databaseHelper; private List<Friend> friendList; public ListViewAdapter(MainActivity context, int resource, List<Friend> objects, DatabaseHelper helper) { super(context, resource, objects); this.activity = context; this.databaseHelper = helper; this.friendList = objects; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); if (convertView == null) { convertView = inflater.inflate(R.layout.item_listview, parent, false); holder = new ViewHolder(convertView); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.name.setText(getItem(position).getName()); //Delete an item holder.btnDelete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { databaseHelper.deleteFriend(getItem(position)); //delete in db Toast.makeText(activity, "Deleted!", Toast.LENGTH_SHORT).show(); //reload the database to view activity.reloadingDatabase(); } }); //Edit/Update an item holder.btnEdit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { AlertDialog.Builder alertDialog = new AlertDialog.Builder(activity); alertDialog.setTitle("Update a Friend"); LinearLayout layout = new LinearLayout(activity); layout.setPadding(10, 10, 10, 10); layout.setOrientation(LinearLayout.VERTICAL); final EditText nameBox = new EditText(activity); nameBox.setHint("Name"); layout.addView(nameBox); final EditText jobBox = new EditText(activity); jobBox.setHint("job"); layout.addView(jobBox); nameBox.setText(getItem(position).getName()); jobBox.setText(getItem(position).getJob()); alertDialog.setView(layout); alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Friend friend = new Friend(nameBox.getText().toString(), jobBox.getText().toString()); friend.setId(getItem(position).getId()); databaseHelper.updateFriend(friend); //update to db Toast.makeText(activity, "Updated!", Toast.LENGTH_SHORT).show(); //reload the database to view activity.reloadingDatabase(); } }); alertDialog.setNegativeButton("Cancel", null); //show alert dialog alertDialog.show(); } }); //show details when each row item clicked convertView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { AlertDialog.Builder alertDialog = new AlertDialog.Builder(activity); alertDialog.setTitle("Friend "); LinearLayout layout = new LinearLayout(activity); layout.setPadding(10, 10, 10, 10); layout.setOrientation(LinearLayout.VERTICAL); TextView nameBox = new TextView(activity); layout.addView(nameBox); TextView jobBox = new TextView(activity); layout.addView(jobBox); nameBox.setText("Friend name: " + getItem(position).getName()); jobBox.setText("Friend job: " + getItem(position).getJob()); alertDialog.setView(layout); alertDialog.setNegativeButton("OK", null); //show alert alertDialog.show(); } }); return convertView; } private static class ViewHolder { private TextView name; private View btnDelete; private View btnEdit; public ViewHolder (View v) { name = (TextView)v.findViewById(R.id.item_name); btnDelete = v.findViewById(R.id.delete); btnEdit = v.findViewById(R.id.edit); } } }And layout (xml file) for each ListView item: Menu file use in main activity: Running project, we will have a list of records which populated from database table:
By clicking the "adding button (+)", an
AlertDialog
to inserting a new record will be shown:Clicking update icon at any row, another
AlertDialog
appeared to update item information:Note: In order to handle input action better, you should use a custom
Dialog
with layout instead of AlertDialog
.Conclusions
References:
- SQLite Android doc: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html- SQLite Android official guide: http://developer.android.com/training/basics/data-storage/databases.html
- Readers can read a good tut about database with multiple tables at AndroidHive.
- Another good tutorial from Guru99.