上一篇说了智能厨房重构-Retrofit和RxJava进行网络请求,这一篇来记录一下使用ActiveAndroid关系型数据库进行本地对象的保存。
该项目的github地址:https://github.com/pardom/ActiveAndroid
首先配置,我们需要在gradle中添加
repositories {
mavenCentral()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'
把环境配置好了之后,接下来
...>
"com.activeandroid.app.Application" ...>
...
"AA_DB_NAME" android:value="Pickrand.db" />
"AA_DB_VERSION" android:value="5" />
applicaton 标签表明我们需要使用activeandroid的application,但是假如我们自己已经定义了application,我们就需要在里面初始化
public class MyApplication extends SomeLibraryApplication {
@Override
public void onCreate() {
super.onCreate();
ActiveAndroid.initialize(this);
}
@Override
public void onTerminate() {
super.onTerminate();
ActiveAndroid.dispose();
}
}
AA_DB_NAME 表示数据库的名称
AA_DB_VERSION 表示数据当前的版本号
这样我们配置工作就结束了。
@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类。
@Table(name = “Categories”) 代表关系表的名字
@Column(name = “Name”) 代表关系表中的列名
从上面还可以看出支持一个表中引用另一个表的对象。
Category restaurants = new Category();
restaurants.name = "Restaurants";
restaurants.save();
Item item = new Item();
item.category = restaurants;
item.name = "Outback Steakhouse";
item.save();
简直简单到没朋友,定义好对象后,最后加一个sava就可以了。
使用事务批量增加数据
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();
}
作者说使用事务花费40ms,不使用花费4s,所以说大量数据的增加一定要用这个啊。
调用delete()方法就可以删除一条记录,下面的例子中,通过id加载一个Item对象,并且删除他。
Item item = Item.load(Item.class, 1);
item.delete();
new Delete().from(Item.class).where("Id = ?", 1).execute();
new Update(Person.class).set("age=?," + "name=?", age, name).execute();
如果你想要在你的数据表中随机获取一个对象的话
public static Item getRandom() {
return new Select().from(Item.class).orderBy("RANDOM()").executeSingle();
}
按照Category查询一条
public static Item getRandom(Category category) {
return new Select()
.from(Item.class)
.where("Category = ?", category.getId())
.orderBy("RANDOM()")
.executeSingle();
}
查询所有
public static List- getAll(Category category) {
return new Select()
.from(Item.class)
.where("Category = ?", category.getId())
.orderBy("Name ASC")
.execute();
}
还是先说一下需求:再点击下图的星星之后,这个美食就被我们收藏到本地。
所以首先就是定义表了。下面是我定义的三张表
(1) 美食介绍表
/**
* 作者:GXL on 2016/8/3 0003
* 博客: http://blog.csdn.net/u014316462
* 作用:美食教学的对象类
*/
@Table(name = "FoodDetailTeachItem")
public class FoodDetailTeachItem extends Model {
public String getFoodId() {
return foodId;
}
public void setFoodId(String foodId) {
this.foodId = foodId;
}
@Column(name="foodId")
String foodId;
@Column(name = "FoodTitle")
public String FoodTitle; //美食名称
@Column(name = "FoodIntroduction")
public String FoodIntroduction; //美食介绍
@Column(name = "FoodImage")
public String FoodImage; //美食图片
@Column(name = "WriteName")
public String WriteName; //作者名
@Column(name = "WritePhoto")
public String WritePhoto; //作者头像
@Column(name = "WriteDate")
public String WriteDate; //创作时间
public List AccessoriesList; //做菜辅料
public List StepList; //做菜步骤
}
我们定义的表名为FoodDetailTeachItem,里面的列有foodId(用来唯一标记该美食),FoodTitle,FoodIntroduction,FoodImage,WriteName,WritePhoto,WriteDate。
现在有一个问题:就是一个FoodDetailTeachItem和FoodAccessories、FoodTeachStep存在一对多的关系,
因为Activeandroid中处理一对多,需要做一下特殊处理。我们先把所有的表看完,最后说明一下。
(2) 美食材料表
/**
* 作者:GXL on 2016/8/3 0003
* 博客: http://blog.csdn.net/u014316462
* 作用:美食教学的辅料对象
*/
@Table(name="FoodAccessories")
public class FoodAccessories extends Model {
public String getFoodId() {
return foodId;
}
public void setFoodId(String foodId) {
this.foodId = foodId;
}
@Column(name="foodId")
String foodId;
@Column(name="name")
String name;
@Column(name="number")
String number;
}
这张表名为FoodAccessories,里面的列有foodId为美食唯一标识,name,number。
(3) 美食做法表
**
* 作者:GXL on 2016/8/3 0003
* 博客: http://blog.csdn.net/u014316462
* 作用:美食教学的步骤类
*/
@Table(name = "FoodTeachStep")
public class FoodTeachStep extends Model {
@Column(name = "foodId")
String foodId;
@Column(name = "num")
public String num;
@Column(name = "imagelink")
public String imagelink;
@Column(name = "teachtext")
public String teachtext;
}
这张表名为FoodTeachStep,里面的列有foodId为美食唯一标识,num,imagelink,teachtext。
好,表定义好了,说一下他们三者的关联:FoodDetailTeachItem和FoodAccessories、FoodTeachStep存在一对多的关系,就是一个FoodDetailTeachItem对应着多个FoodAccessories和FoodTeachStep。所以,我用了一个foodId作为主键,将他们连接在一起,就是一个美食,他们三者的foodId是相同的。
/**
* 从数据库中获取教学步骤
*/
public List getTeachStepFromSQL() {
return new Select().from(FoodTeachStep.class).where("foodId=?", foodId).execute();
}
/**
* 从数据库中获取美食材料
*/
public List getFoodAccessoriesFromSQL() {
return new Select().from(FoodAccessories.class).where("foodId=?", foodId).execute();
}
FoodDetailTeachItem获取教学步骤和美食材料只要调用上面的方法即可。
表定义好了,就来试一试增删改查把!
定义的Model类接口
/**
* 作者:GXL on 2016/8/3 0003
* 博客: http://blog.csdn.net/u014316462
* 作用:收藏美食接口
*/
public interface FoodLoveModelImpl {
//查询所有
List onQuery();
//增
void onInsert(FoodDetailTeachItem item);
//删
void onDelete(FoodDetailTeachItem item);
//查询是否存在
boolean onQuery(FoodDetailTeachItem item);
}
Model类的实现。
/**
* 作者:GXL on 2016/8/3 0003
* 博客: http://blog.csdn.net/u014316462
* 作用:收藏美食的实现
*/
public class FoodLoveModel implements FoodLoveModelImpl {
@Override
public List onQuery() {
return new Select().from(FoodDetailTeachItem.class).execute();
}
@Override
public void onInsert(FoodDetailTeachItem item) {
String foodId = StringUtils.BuildOrderNum();
item.setFoodId(foodId);
item.save();
List AccessoriesList = item.getAccessoriesList();
ActiveAndroid.beginTransaction();
try {
for (FoodAccessories accessoriesItem : AccessoriesList
) {
accessoriesItem.setFoodId(foodId);
accessoriesItem.save();
}
ActiveAndroid.setTransactionSuccessful();
} finally {
ActiveAndroid.endTransaction();
}
List teachStepList = item.getStepList();
ActiveAndroid.beginTransaction();
try {
for (FoodTeachStep teachStepItem : teachStepList
) {
teachStepItem.setFoodId(foodId);
teachStepItem.save();
}
ActiveAndroid.setTransactionSuccessful();
} finally {
ActiveAndroid.endTransaction();
}
}
@Override
public void onDelete(FoodDetailTeachItem item) {
FoodDetailTeachItem sqlItem = new Select().from(FoodDetailTeachItem.class).where("FoodTitle=?", item.FoodTitle).where("FoodImage=?", item.getFoodImage()).executeSingle();
String foodId = sqlItem.getFoodId();
sqlItem.delete();
new Delete().from(FoodAccessories.class).where("foodId=?", foodId).execute();
new Delete().from(FoodTeachStep.class).where("foodId=?", foodId).execute();
}
@Override
public boolean onQuery(FoodDetailTeachItem item) {
FoodDetailTeachItem sqlItem = new Select().from(FoodDetailTeachItem.class).where("FoodTitle=?", item.FoodTitle).where("FoodImage=?", item.getFoodImage()).executeSingle();
if (sqlItem != null)
return true;
return false;
}
}
所有的东西都准备好了,看一下我们的用法:
if (mFoodLoveModel.onQuery(item)) {
favorite.setBackgroundResource(R.drawable.gray_star_enabled);
}
进来的时候先查询一下当前的是否已经存在,存在变成红心。
@OnClick({R.id.back, R.id.favorite})
public void onClick(View view) {
switch (view.getId()) {
case R.id.back:
finish();
break;
case R.id.favorite:
if (mItem != null) {
if (mFoodLoveModel.onQuery(mItem)) {
favorite.setBackgroundResource(R.drawable.star);
mFoodLoveModel.onDelete(mItem);
ToastUtils.showShort(FoodTeachActivity.this, "取消成功");
} else {
favorite.setBackgroundResource(R.drawable.gray_star_enabled);
mFoodLoveModel.onInsert(mItem);
ToastUtils.showShort(FoodTeachActivity.this, "收藏成功");
}
}
break;
}
}
点击收藏,判断已经存在,就取消收藏,没存在就变成收藏。
看一下效果演示,哈哈,这一章就差不多结束了。快开始你自己的ActiveAndroid的旅程吧!
项目代码地址:https://github.com/gxl1240779189/ReIntelligentKitchen,如果你觉得不错,可以star一下,感谢您的支持。下一篇讲解用Bmob后端云实现朋友圈功能。