Android ORM 框架之 ActiveAndroid应用基础
Posted Iaouei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android ORM 框架之 ActiveAndroid应用基础相关的知识,希望对你有一定的参考价值。
ActiveAndroid作为轻量级的ORM框架,在快速开发中,使用很简单,满足大部分对数据库操作不复杂的应用。
一,配置
添加依赖
build.gradle中添加:
repositories
mavenCentral()
maven url "https://oss.sonatype.org/content/repositories/snapshots/"
compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'
项目配置
1>Application类配置:
<manifest ...>
<application android:name="com.activeandroid.app.Application" ...>
...
</application>
</manifest>
注意:应用程序的名称指向ActiveAndroid应用程序类。如果使用自定义的应用程序类,要继承com.activeandroid.app.Application而不是android.app.Application:
public class MyApplication extends com.activeandroid.app.Application ...
但是,如果已经有了继承其他Application类的类,需要在应用程序初始化类ActiveAndroid(如果调试中需要重置框架,调用ActiveAndroid.dispose();后初始化):
public class MyApplication extends SomeLibraryApplication
@Override
public void onCreate()
super.onCreate();
ActiveAndroid.initialize(this);
2>配置数据库名和版本名:
<manifest ...>
<application...>
...
<meta-data android:name="AA_DB_NAME" android:value="Pickrand.db" />
<meta-data android:name="AA_DB_VERSION" android:value="5" />
</application>
</manifest>
如果想动态的创建数据库,可以这样配置:
public class MyApplication extends SomeLibraryApplication
@Override
public void onCreate()
super.onCreate();
Configuration dbConfiguration = new Configuration.Builder(this).setDatabaseName("xxx.db").create();
ActiveAndroid.initialize(dbConfiguration);
二,创建表
创建表需要新建实体类继承Model,添加类注解@Table(name = “表名”),类成员添加@Column注解标识表里的列。 ActiveAndroid自动为表添加自增的id主键。ActiveAndroid使用标准构造函数实例化对象,如果定义有自己的构造函数,还必须定义一个无参构造函数。
如下,创建一个表Items,表中添加两列(自动添加id列),一个为String类型的Name列,一个为实体Category列:
@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;
@Table(name = "Categories")
public class Category extends Model
@Column(name = "Name")
public String name;
...
如果Category 和 Item是一对多的关系,可以在Category类中添加一个helper 方法:
@Table(name = "Categories")
public class Category extends Model
...
// helper方法, 不要影响外键创建.
public List<Item> items()
return getMany(Item.class, "Category");
指定某个列可以被索引,在其注解中添加:index = true。
@Column(name = "Name", index = true)
public String name;
其他属性可以查询依赖包中com.activeandroid.annotation.Column。
ActiveAndroid会搜索所有的文件查找Model的子类,如果项目中有很多依赖,这个过程会花费很长时间。为了加快应用的启动速度,我们可以在清单文件中明确的指出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
ID
三,数据处理
增
保存一条新的数据,需要创建一个activeandroid.Model对象,为其成员指定值,然后其save()方法。save()执行保存和更新数据。
Category restaurants = new Category();
restaurants.name = "Restaurants";
restaurants.save();
插入一条item数据,并为其指定一个category
Item item = new Item();
item.category = restaurants;
item.name = "Outback Steakhouse";
item.save();
如果插入多条数据,需要重复创建activeandroid.Model对象,然后重复执行相关操作。
删
要删除单条记录只需要调用delete()方法。在下面的例子中,我们将通过id加载一个对象,并将其删除:
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.query()方法查询数据。
获取一条随机的数据:
public static Item getRandom()
return new Select().from(Item.class).orderBy("RANDOM()").executeSingle();
ActiveAndroid构建查询就像建立一个正常的SQL语句,创建一个新的Select对象,调用并传入item类。然后,我们调用排序依据方法,传递“随机”。要执行可以调用execute(查询),或者executeSingle()。等还有一些其他指令。
从指定的category随机获取一个item:
public static Item getRandom(Category category)
return new Select()
.from(Item.class)
.where("Category = ?", category.getId())
.orderBy("RANDOM()")
.executeSingle();
获取所有item,并按name排列:
public static List<Item> getAll(Category category)
return new Select()
.from(Item.class)
.where("Category = ?", category.getId())
.orderBy("Name ASC")
.execute();
事务
当一次执行多条数据时,还可以使用事务处理,会较于上面方法有很大加速。
一次插入多条数据:
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();
在查询Category数据时,因为每个对象中包括了一个List对象,所以,我们需要在查询出Category对象后,在把关联的List表查询一遍:
ActiveAndroid.beginTransaction();
try
List<Category> category = new Select().from(Category.class).limit(20).execute();
if (category != null)
int len = category.size();
for (int i = 0; i < len; i++)
category.get(i).items();
ActiveAndroid.setTransactionSuccessful();
finally
ActiveAndroid.endTransaction();
四,类型序列
ActiveAndroid默认处理多种类型。如果需要处理自定义数据类型,继承TypeSerializer,重写其方法。比如我们要将Date类型转换为long类型保存,读取的时候又直接得到Date类型:
public final class UtilDateSerializer extends TypeSerializer
/**
*返回序列的类
*/
public Class<?> getDeserializedType()
return Date.class;
/**
*返回存储到数据库中的类型
*/
public Class<?> getSerializedType()
return long.class;
/**
*将我们所使用的数据类型转换为ActiveAndroid存储的数据类型
*/
public Long serialize(Object data)
if (data == null)
return null;
return ((Date) data).getTime();
/**
*使存储的数据转换成使用的数据类型
*/
public Date deserialize(Object data)
if (data == null)
return null;
return new Date((Long) data);
然后注册自定义的序列化类型,在AndroidManifest.xml声明它们:
<meta-data android:name="AA_SERIALIZERS"
android:value="my.package.CustomTypeSerializer,my.package.AnotherCustomeTypeSerializer" />
ActiveAndroid自带的TypeSerializer:
五,使用content provider
1>在AndroidManifest.xml声明:
<application ...>
<provider android:authorities="com.example" android:exported="false" android:name="com.activeandroid.content.ContentProvider" />
...
</application>
2>在表注解中添加id列:
@Table(name = "Items", id = BaseColumns._ID)
public class Item extends Model ...
3>使用:
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);
);
六,数据库升级
当App更新数据库变化,需要增加数据库的版本号,需要使用配置文件,并且改变AA_DB_VERSION meta-data。如果你想改变数据库中现有的表(比如,添加一列或重命名表),要使用命名为< NewVersion >.sql的sql脚本,放进assets/migrations中,NewVersion是版本号。如果它的文件名比以前的数据库版本高,ActiveAndroid会执行它。
例如 向 Items表中添加 color列:
1>AA_DB_VERSION 增加为 2 ,并提供一个名为2.sql的脚本:
ALTER TABLE Items ADD COLUMN color INTEGER;
2>增加实体类color。
七,导入提供有的数据库
1>将数据库放进assets包中:
/myapp/src/main/assets/prepop.db
2>manifest.xml中设置AA_DB_NAME:
<meta-data android:name="AA_DB_NAME" android:value="prepop.db" />
3>创建android_metadata表:
CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US')
INSERT INTO "android_metadata" VALUES ('en_US')
4>如果表model没有定义id列,主键重命名为默认值id,而不是_id。如果数据是被建议主键列为_id的使用,比如ListView,可以在@Table注解中添加id = “_id”:
@Table(name = "Items", id = "_id")
public class Item extends Model
以上是关于Android ORM 框架之 ActiveAndroid应用基础的主要内容,如果未能解决你的问题,请参考以下文章
Android ORM 框架之 ActiveAndroid应用基础
Android ORM 框架之 Android中ORMLite应用基础
Android ORM 框架之 Android中ORMLite应用基础
Android ORM 框架之 ActiveAndroid应用基础