标签:
进入正题
* 快速入门
* 创建你的数据库模型
* 保存数据到数据库
* 查询数据库
* 类型序列化
* 使用content provider
* 模型迁移
* 预设数据库
让我们一起来进入ActiveAndroid的世界。首先你要做的就是下载ActiveAndroid库,又或者是最新的稳定版ActiveAndroid jar文件。如果你下载的是库(其实就是一个工程),你必须得先编译成jar文件再使用。
现在你已经有了ActiveAndroid的库,你可以把它添加到你的工程build path了。如果你使用的是eclipse:
1. 如果还没有工程先创建一个Android工程
2. 把ActiveAndroid.jar复制到工程的libs目录下
3. 右键点击工程然后选择Build Path -> Configure Build Path…
4. 点击Add Ecternal Jars…,选中ActiveAndroid jar并确定
如果你使用的是AndroidStudio:
1. 创建一个工程(已经有了就不用再创建了)
2. 复制jar文件到libs目录下
3. 右键点击jar文件,选择Add as a Library…
首先从Git上克隆源码并且安装到你本地仓库
注意:需要使用Maven3.1.1以及以上的版本
1. git clone https://github.com/pardom/ActiveAndroid.git
2. cd ActiveAndroid
3. mvn clean install
工程创建成功后,添加依赖到pom.xml中
<dependency>
<groupId>com.activeandroid</groupId>
<artifactId>activeandroid</artifactId>
<version>(insert latest version)</version>
</dependency>
修改工程build.gradle,包含以下内容:
repositories {
mavenCentral()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/"
}
}
compile ‘com.michaelpardo:activeandroid:3.1.0-SNAPSHOT‘
现在你已经将ActiveAndroid添加到工程了,你可以两步配置开始使用。首先需要添加一些全局设置。ActiveAndroid会在AndroidManifest.xml文件中查找这些设置。打开AndroidManifest.xml添加配置。
配置好的AndroidManifest.xml应该是这个样子的
<manifest ...>
<application android:name="com.activeandroid.app.Application" ...>
...
<meta-data android:name="AA_DB_NAME" android:value="Pickrand.db" />
<meta-data android:name="AA_DB_VERSION" android:value="5" />
</application>
</manifest>
需要注意的是app的名字应该引用ActiveAndroid的Application类。ActiveAndroid工作必须设置这一步。如果你已经引用了一个自定义的Application类,只需要让该类成为com.activeandroid.Application类的子类即可。
如果你正在使用自定义的Application类,只需要继承把继承android.app.Application类换成继承com.activeandroid.Application就可以了。(这是原作者的话,感觉废话真多)
public class MyApplication extends com.activeandroid.app.Application { ...
但是如果你已经继承了其他库的Application类,在Application类中做简单的初始化就可以。调用ActiveAndroid.dispose();
public class MyApplication extends SomeLibraryApplication {
@Override
public void onCreate() {
super.onCreate();
ActiveAndroid.initialize(this);
}
}
如果你想动态创建一个数据库,可以使用Configuration类。
public class MyApplication extends SomeLibraryApplication {
@Override
public void onCreate() {
super.onCreate();
Configuration dbConfiguration = new Configuration.Builder(this).setDatabaseName("xxx.db").create();
ActiveAndroid.initialize(dbConfiguration);
}
}
在我们的例子中有两张表:Category和Item。
第二步你将会创建这些表的类,这同样很简单。
我们在下面设置数据库模型的小节中再详细介绍这个,下面是我们的类:
@Table(name = "Categories")
public class Category extends Model {
@Column(name = "Name")
public String name;
}
@Table(name = "Items")
public class Item extends Model {
@Column(name = "Name")
public String name;
@Column(name = "Category")
public Category category;
}
创建数据库非常简单,只需要用你希望的表明作为类名创建类即可,需要给表的每一列对应的类成员加上注解。
有两个重点:一是你的类必须继承Model类,类成员必须使用@Column
来进行注解。
需要注意的是ActiveAndroid为表创建了id字段,该字段是自动递增的主键。
ActiveAndroid使用了标准的构造器(指的是无参数的默认构造器)实例化对象,如果你定义了自己的构造器你必须另外定义一个无参数的构造器。
@Table(name = "Items")
public class Item extends Model {
// If name is omitted, then the field name is used.
@Column(name = "Name")
public String name;
@Column(name = "Category")
public Category category;
public Item() {
super();
}
public Item(String name, Category category) {
super();
this.name = name;
this.category = category;
}
}
在上面的小节中我们使用了Categories和Items的例子,Items属于Categories而Categories有很多Items。我们怎么在ActiveAndroid中表达这两者的关系呢?
在Item类中我们可以直接通过创建一个Category类成员来表现两者之间的关系。
@Table(name = "Items")
public class Item extends Model {
@Column(name = "Name")
public String name;
@Column(name = "Category")
public Category category;
}
同样的道理,Category类可以指示多个Items的关系。我们使用一个辅助方法来完成。
@Table(name = "Categories")
public class Category extends Model {
@Column(name = "Name")
public String name;
// This method is optional, does not affect the foreign key creation.
public List<Item> items() {
return getMany(Item.class, "Category");
}
}
你可以通过在列定义的注解中加上index = true
来给指定的列设置索引。
@Column(name = "Name", index = true)
public String name;
@Column(name = "Category", index = true)
public String category;
ActiveAndroid会查找所有的文件来找出Model类,这个过程会非常缓慢,特别是当工程有很多依赖的时候。为了加快这个过程,在AndroidManifest文件中显式指定Model类。
<meta-data android:name="AA_MODELS"
android:value="com.myapp.model.Item, com.myapp.model.Category" />
不要使用以下的词来命名表和列:
ABORT DEFAULT INNER REGEXP
ACTION DEFERRABLE INSERT REINDEX
ADD DEFERRED INSTEAD RELEASE
AFTER DELETE INTERSECT RENAME
ALL DESC INTO REPLACE
ALTER DETACH IS RESTRICT
ANALYZE DISTINCT ISNULL RIGHT
AND DROP JOIN ROLLBACK
AS EACH KEY ROW
ASC ELSE LEFT SAVEPOINT
ATTACH END LIKE SELECT
AUTOINCREMENT ESCAPE LIMIT SET
BEFORE EXCEPT MATCH TABLE
BEGIN EXCLUSIVE NATURAL TEMP
BETWEEN EXISTS NO TEMPORARY
BY EXPLAIN NOT THEN
CASCADE FAIL NOTNULL TO
CASE FOR NULL TRANSACTION
CAST FOREIGN OF TRIGGER
CHECK FROM OFFSET UNION
COLLATE FULL ON UNIQUE
COLUMN GLOB OR UPDATE
COMMIT GROUP ORDER USING
CONFLICT HAVING OUTER VACUUM
CONSTRAINT IF PLAN VALUES
CREATE IGNORE PRAGMA VIEW
CROSS IMMEDIATE PRIMARY VIRTUAL
CURRENT_DATE IN QUERY WHEN
CURRENT_TIME INDEX RAISE WHERE
CURRENT_TIMESTAMP INDEXED RECURSIVE WITH
DATABASE INITIALLY REFERENCES WITHOUT
(其实就是一大波SQL里的关键字)
如果你发现还有其他的,请告诉我。
现在你已经做好了数据库模型,然后我们来看一下怎么把记录保存到数据库。
为了保存一条新的记录,只需要创建activeandroid.Model
类的一个实例,给其中的字段赋上值,然后调用.save()
方法。save方法用于插入和更新记录。
下面是一个例子
Category restaurants = new Category();
restaurants.name = "Restaurants";
restaurants.save();
Item item = new Item();
item.category = restaurants;
item.name = "Outback Steakhouse";
item.save();
添加一些items
item = new Item();
item.category = restaurants;
item.name = "Red Robin";
item.save();
item = new Item();
item.category = restaurants;
item.name = "Olive Garden";
item.save();
为了同时插入多条记录,你可以使用事务。在事务之间做插入操作可以提升速度。下面是一个例子:
ActiveAndroid.beginTransaction();
try {
for (int i = 0; i < 100; i++) {
Item item = new Item();
item.name = "Example " + i;
item.save();
}
ActiveAndroid.setTransactionSuccessful();
}
finally {
ActiveAndroid.endTransaction();
}
在事务之中执行大约耗时40毫秒,如果不写在事务之间耗时大约4秒。
怎么删除记录呢?删除一条记录只需要调用delete()
方法。下面的例子我们通过Id来load一个Item对象并且删除它。
Item item = Item.load(Item.class, 1);
item.delete();
或者你可以静态地删除
Item.delete(Item.class, 1);
你还可以构建查询语法来删除
new Delete().from(Item.class).where("Id = ?", 1).execute();
在ActiveAndroid中所有的查询操作都通过构建查询的语句或者调用Model.method
。
这是目前我们完成了的:
@Table(name = "Items")
public class Item extends Model {
@Column(name = "Name")
public String name;
@Column(name = "Category")
public Category category;
}
我们希望随机得到一条记录,增加一个方式来实现这个功能。
public static Item getRandom() {
return new Select()
.orderBy("RANDOM()")
.executeSingle();
}
在ActiveAndroid中创建一个查询类似于创建一条普通的SQL语句。我们创建一个新的select对象,在Item类中完成查询的功能。调用orderBy来做随机。调用execute()
方法来执行查询,或者像下面的例子使用executeSingle()
。
如果我们只是想从一个确定的category中查询,我么只需给方法的参数传入值就可以了。方法如下:
public static Item getRandom(Category category) {
return new Select()
.from(Item.class)
.where("Category = ?", category.getId())
.orderBy("RANDOM()")
.executeSingle();
}
下面是通过一个category来获取所有items,按照name属性排序。
public static List<Item> getAll(Category category) {
return new Select()
.from(Item.class)
.where("Category = ?", category.getId())
.orderBy("Name ASC")
.execute();
}
ActiveAndroid可以处理默认的数据类型,如果需要处理自定义类型,可以使用TypeSerializer类来做到。最好的学习方法就是通过例子,下面以Date类型举例。
当我们创建一个TypeSerializer类型时我们必须想办法把自定义的类型转换为基本数据类型让ActiveAndroid来处理。Date类型可以转换为Long型,这样我们就可以使用了。
下面是例子。
final public class UtilDateSerializer extends TypeSerializer {
@Override
public Class<?> getDeserializedType() {
return Date.class;
}
@Override
public Class<?> getSerializedType() {
return Long.class;
}
@Override
public Long serialize(Object data) {
if (data == null) {
return null;
}
return ((Date) data).getTime();
}
@Override
public Date deserialize(Object data) {
if (data == null) {
return null;
}
return new Date((Long) data);
}
}
第一个方法getDeserializedType返回我们进行序列化的的class,对于Date类型我们就返回Date.class。
第二个方法返回相反的类型,也就是我们希望把Date类型保存时所用的类型(这里就是Long型)。我们使用枚举类型来代替字符串类型。下面是这个方法的枚举类。(这一句翻译得可能不准确,因为我也不知道下面的枚举类有什么作用,看懂的童鞋请告诉我)
public enum SQLiteType {
INTEGER, REAL, TEXT, BLOB
}
再下一个方法就是把我们自定义的类型转换为ActiveAndroid可以保存的类型,这里使用了getTime()
方法返回了一个Long型对象。
最后一个方法是把保存在数据库的数据转换为自定义类型,Date类型可以使用Long型来构对象,所以我们使用一个Long来生成一个Date对象。
最后在AndroidManifest.xml中注册我们自定义的类型。
<meta-data
android:name="AA_SERIALIZERS"
android:value="my.package.CustomTypeSerializer,my.package.AnotherCustomeTypeSerializer" />
注意:你必须先写明指定列作为id列详见https://github.com/pardom/ActiveAndroid/pull/132才能使用
mySpinner.setAdapter(new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_expandable_list_item_1,
null,
new String[] { "MyProperty" },
new int[] { android.R.id.text1 },
0));
getActivity().getSupportLoaderManager().initLoader(0, null, new LoaderCallbacks<Cursor>() {
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle cursor) {
return new CursorLoader(getActivity(),
ContentProvider.createUri(MyEntityClass.class, null),null, null, null, null);
}
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {
((SimpleCursorAdapter)mySpinner.getAdapter()).swapCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
((SimpleCursorAdapter)mySpinner.getAdapter()).swapCursor(null);
}
});
还需要在AndroidManifest.xml中注册
<application ...>
<provider android:authorities="com.example" android:exported="false" android:name="com.activeandroid.content.ContentProvider" />
...
</application>
当数据库版本通过Configuration或者AA_DB_VERSION来设计时,如果添加了新的类,ActiveAndroid会自动把对应的表添加到数据库中。如果你想修改已经存在的表(比如添加一列或者重命名表名),都可以通过<NewVersion>.sql
脚本来完成。新的版本号就是AndroidManifest.xml中的AA_DB_VERSION的值,脚本文件需要存放于assets/migrations
如果脚本的文件名比旧的数据库版本号大ActiveAndroid会执行该脚本,小于或等于即不会执行。
比如给Items
表添加一个color
列,需要把AA_DB_VERSION修改为2并且添加2.sql,该脚本文件如下:
ALTER TABLE Items ADD COLUMN color INTEGER;
更多关于ALTER TABLE
的用法可以参考SQLite docs
可以按照以下步骤来使用已经填充好数据的数据库:
1. 在assets
目录下放置SQLite数据库文件,比如:
/myapp/src/main/assets/prepop.db
2. 确保在manifest文件中设置了AA_DB_NAME
,例如:
<meta-data android:name="AA_DB_NAME" android:value="prepop.db" />
这样当你安装好应用程序prepop.db
就会复制到/data/data/myapp/databases
目录下了
注意:这样会存在两个数据库,一份打包到APK中,另一份在/data/data/myapp/databases
中
为了确保这一点,请注意以下两点:
1. 设置android_metadata
CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT ‘en_US‘)
INSERT INTO "android_metadata" VALUES (‘en_US‘)
id
列,确保主键被命名为Id
而不是Android数据库默认的_id
。但是,如果你的数据库是放到ListView中显示的,建议把主键列设为_id
。可以在@Table
注解中写上id = "_id"
:@Table(name = "Items", id = "_id")
public class Item extends Model {
以上就是ActiveAndroid的使用方法,这里只是给出了一些最常见的用法,本人的英语水平也有限,有翻译得不准或者不好的地方请告诉我。当然,如果你的英语水平足够好,我还是希望你能看原文:我是Github项目地址,我是文档地址。
标签:
原文地址:http://blog.csdn.net/spareyaya/article/details/51714873