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
Can't Run Junit 4 Test Case in Eclipse Android Project
How to Have the Code Pause for a Couple of Seconds in Android
Using Asynctask with Passing a Value
How to Change the Edittext Text Without Triggering the Text Watcher
Xmpp with Java Asmack Library Supporting X-Facebook-Platform
How to Check If Class Exists Somewhere in Package
How to Programmatically Add Views and Constraints to a Constraintlayout
How to Instantiate an Abstract Class Directly
How to Override the Cipherlist Sent to the Server by Android When Using Httpsurlconnection
What Is the Use of Memoryfile in Android
Java Apns Certificate Error with "Derinputstream.Getlength(): Lengthtag=109, Too Big."
How to Get Ruby Generated Hmac for Sha256 That Is Url Safe to Match Java
Java Equivalent to JavaScript's Encodeuricomponent That Produces Identical Output
Why Is Double.Min_Value in Not Negative
How to Set -Source 1.7 in Android Studio and Gradle
Why Comparing Integer with Int Can Throw Nullpointerexception in Java
How to Remove Specific Permission When Build Android App with Gradle