What Is the Use of Basecolumns in Android

What is the use of BaseColumns in Android

This is a simple interface which adds two fields :

public interface BaseColumns
{
/**
* The unique ID for a row.
* <P>Type: INTEGER (long)</P>
*/
public static final String _ID = "_id";

/**
* The count of rows in a directory.
* <P>Type: INTEGER</P>
*/
public static final String _COUNT = "_count";
}

Internally sqlite databases used in Android, comes with an _id column that autoincrements and can function as a primary key. This also maps well with the ContentProviders

What is the use of BaseColumns's _ID primary key in Android

The main use for BaseColumns._ID is that Android's CursorAdapter will look for that column name in the cursor you give it. There may be other classes that do the same, but I can't think of any off the top of my head. If you aren't using CursorAdapter, then there's really nothing binding you to using _id as a column name in your table and you can name the column however you like.

it automatically create an autoincremented primary key for me called _ID

There is nothing automatic about it based on what you've shown so far. You will only have such a column if you executed SQL like this:

CREATE TABLE tableName (_id INTEGER PRIMARY KEY AUTOINCREMENT, ...);

You can just as easily leave it out or give a different name to the primary key. Furthermore, there is nothing that requires your primary key to be auto-incremented; as long as the values are unique, it satisfies the primary key requirement. In other words, this is fine too:

CREATE TABLE tableName (_id INTEGER PRIMARY KEY, ...);

In case I need my own primary key, let's say, _MyID, I guess the primary key will be formed by _ID and my own (_MyID), right?

Not quite. You would have to do something like this:

CREATE TABLE tableName (_id INTEGER, _myId INTEGER, ..., PRIMARY KEY(_id, myId));

This creates a composite key, but note that neither of the two columns are themselves declared as primary key. Honestly though, if you don't need such an arrangement, then stick to one primary key.

One last thing:

If you are planning to use CursorAdapter, you might want to name the column _id for convenience, but even then you don't have to. All that matters is the cursor has a column by that name. The actual column in the table can have a different name, you just have to alias it at query time so that it has the proper name in the cursor:

SELECT _myId as _id, ... FROM ...;

Android - BaseColumns and _id

You must create it "manually". Android won't do that for you.

For example, during table creation, you issue:

CREATE TABLE messages (_id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, message TEXT);

See? The _id column is explicitly named and added.

Or, following the convention of DB-helper classes you'll come up with something like that:

db.execSQL("CREATE TABLE " + TABLE_MESSAGES + " ("
+ BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_TIMESTAMP + " INTEGER,"
+ COLUMN_MESSAGE + " TEXT"
+ ");");

where the TABLE_* and COLUMN_* are constant fields of DB-helper, e.g.:

public static final String TABLE_MESSAGES = "messages";
public static final String COLUMN_TIMESTAMP = "timestamp";
public static final String COLUMN_MESSAGE = "message";

How to use _COUNT in BaseColumns

In the database, there is nothing special about either _id or _count.

Your queries return an _id or _count column when the table is defined to have such a column, or when the query explicitly computes it.

Many objects of the Android framework expect a cursor to have a unique _id column, so many tables define it.

In most places, the _count is not expected to be present, so it is usually not implemented. And if it is actually needed, it can simply be computed with a subquery, like this:

SELECT _id,
[other fields],
(SELECT COUNT(*) FROM MyTable) AS _count
FROM MyTable
WHERE ...

If you want to find out the size of your own table, you are not required to use the _count name; you can execute a query like SELECT COUNT(*) FROM subjects, or, even simpler, use a helper function that does this for you.

BaseColumns interface of a ContentProvider, what to put in it?

The BaseColumns is an interface that just provides two fields _ID and COUNT. It's generally implemented because the _ID(_id) field at least is required by different widgets(like ListView) to be present in the Cursor used by their adapters.

You can implement/extend that interface to have that field adding whatever you want besides that(keeping it relevant to the class).

what are the best things to put inside of a BaseColumns interface?

You don't put anything in the BaseColumns, you extend/implement it to use its fields. Whatever you see there besides that comes from the developers that wrote the LentItems interface or the Note class.

Cannot access to BaseColumns provides _ID property in Kotlin

You can only access it using BaseColumns._ID since it's a Java interface defining a constant.

On Kotlin, a companion object is an actual object with inheritance, whereas in java a class with static methods does not really behave like an object.

For instance, if you had BaseColumns as a kotlin class instead of a java interface, you could have done something like:

open class KBaseColumns  {
val _ID = "_id"
}

class UserContract private constructor(){
class UserEntry private constructor(): BaseColumns {
companion object : KBaseColumns() {
val TABLE_NAME = "users"
val COLUMN_DISPLAY_NAME = "display_name"
val COLUMN_EMAIL = "email"
}
}
}

object Example {
fun someMethod() {
val id = UserContract.UserEntry._ID
}
}

Where _ID is accessible in this case because the companion object is actually a subclass of KBaseColumns

use of BaseColumns or not with ContentProvider?

The point of implementing BaseColumns is the same as the point of reusing any code whatsoever; you don't have to reuse code, you can re-implement it again, the question is: what for?

Now, in the case of BaseColumns this does not stand out so much because, obviously, all they provide is a constant for two columns (_ID and _COUNT), so you don't save that much time implementing BaseColumns instead of just adding these two constants yourself. But why not use it if you can?

tl;dr: You don't have to use BaseColumns if you don't want to, all it does is save you from typing a few lines of code. On the other hand: since it does save you from typing them, why not use it?

How can (or should) I map `BaseColumns._ID` to `ROWID`, `_ROWID_`, or `OID`?

An alias is just another name to a column, it won't duplicate any data.

This means that creating an "_id" column with INTEGER PRIMARY KEY in Sqlite will not duplicate any data, as this will be "mapped" to rowid (i.e., will be an alias).

There is at least one difference between the "_id" alias and a regular alias (as pointed out by CL., quoting Sqlite documentation): "The VACUUM command may change the ROWIDs of entries in any tables that do not have an explicit INTEGER PRIMARY KEY.". So creating an "_id" column with INTEGER PRIMARY KEY will prevent this column from being changed with a VACUUM command.



Related Topics



Leave a reply



Submit