(翻译)又一个Android Sqlite库: Cupboard
Tags: android
原文: https://guides.codepath.com/android/Easier-SQL-with-Cupboard
简介
Cupboard可以用来在应用中管理sqlite.作者是 Hugo Visser. 这里是作者对于Cupboard的一些说明.这是一个轻量级的易于使用的库,它专为Android平台设计,不像ORMlite那样臃肿.
使用Android自身提供的SQLiteOpenHelper 也能达到目的,但是往往要写很多重复性的代码.
与大多数ORM库相似,Cupboard将java类与数据库的表映射在一起,同时java类中的属性对应数据库表的列字段.
开始使用
可以下载jar包: https://search.maven.org/remote_content?g=nl.qbusict&a=cupboard&v=LATEST
也可以使用Maven:
<dependency> <groupId>nl.qbusictgroupId> <artifactId>cupboardartifactId> <version>(insert latest version)version>dependency>
也可以使用Gradle:
compile 'nl.qbusict:cupboard:(insert latest version)'
配置
需要自定义一个SQLiteOpenHelper.(在接下来的例子中,将会使用一个名为”Bunny”的POJO类,意思是兔子)
import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;import static nl.qbusict.cupboard.CupboardFactory.cupboard;public class PracticeDatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "cupboardTest.db";//文件名 private static final int DATABASE_VERSION = 1;//版本号 public PracticeDatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } static { // 注册model cupboard().register(Bunny.class); } @Override public void onCreate(SQLiteDatabase db) { // 建表 cupboard().withDatabase(db).createTables(); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 升级表 // Note that existing columns will not be converted cupboard().withDatabase(db).upgradeTables(); }}
然后可以这样使用:
PracticeDatabaseHelper dbHelper = new PracticeDatabaseHelper(this);db = dbHelper.getWritableDatabase();
如何定义Model
定义Model
使用cupboard时,每一个POJO类都必须包含一个Long类型的名为”_id”的变量.
public class Bunny { public Long _id; // for cupboard public String name; // 兔子的名字 public Integer cuteValue ; // 兔子的可爱程度 public Bunny() { this.name = "noName"; this.cuteValue = 0; } public Bunny(String name, Integer cuteValue) { this.name = name; this.cuteValue = cuteValue; }}
注意:在这些类中,类名将成为创建的数据库表的名字,变量的名字将成为列字段的名字.所以命名时注意要遵守SQLite里的命名规范.
然后需要在之前自定义的DatabaseHelper里进行注册.注册方法是创建一个static的代码块.
static { cupboard().register(Bunny.class); }
使用注解配置字段名
cupboard支持 @Column() 和 @Ignore() 注解.
@Column()可以指定一个名字作为要创建的列字段的名字.
@Ignore()可以忽略一个变量,即不参与创建数据库表.
例如:
public class Bunny { public Long _id; // for cupboard public String name; // bunny name @Column("cute_value") public Integer cuteValue; // bunny cuteness @Ignore public Boolean isAwake; ...
增删改查
创建记录
// 在数据库中新增一只兔子Bunny bunny = ...long id = cupboard().withDatabase(db).put(bunny);
如果bunny对象设置了”_id”变量的值,那么将会update指定的行.
如果”_id”变量为null,那么将会在数据库表中创建新的一行数据.
两种情况下,put()函数都会返回对应的数据行的_id的值.
查询
Bunny bunny = cupboard().withDatabase(db).get(Bunny.class, 12L);
意思是查询”_id值为12”的Bunny对象.如果结果不存在,get()将会返回null.
更复杂的用法:
//查询第一个Bunny对象Bunny bunny = cupboard().withDatabase(db).query(Bunny.class).get();// 获得查询结果的Cursor对象Cursor bunnies = cupboard().withDatabase(db).query(Bunny.class).getCursor();try { // 遍历产寻结果 QueryResultIterable itr = cupboard().withDatabase(db).query(Bunny.class).iterate(); for (Bunny bunny : itr) { // do something with bunny }} finally { // 关闭cursor itr.close();}// 查询第一个名字为Max的Bunny对象Bunny bunny = cupboard().withDatabase(db).query(Bunny.class).withSelection( "name = ?", "Max").get();
修改记录
只需先查询出一条数据,然后修改一些变量的值,然后使用put方法即可更新数据:
cupboard().withDatabase(db).put(b);
批量地对查询结果进行修改:
//假设需求是将名字为"max"的Bunny的名字改成"Max"ContentValues values = new ContentValues(1);values.put("name", "Max")// 批量地对查询结果进行修改cupboard().withDatabase(db).update(Book.class, values, "name = ?", "max");
删除记录
// 删除"_id = 12"的记录cupboard().withDatabase(db).delete(Bunny.class, 12L);// 传入java对象进行删除cupboard().withDatabase(db).delete(bunny);// 传入查询条件进行删除,例如删除所有名字为"Max"的Bunny的记录cupboard().withDatabase(db).delete(Bunny.class, "name = ?", "Max");
升级数据库
假设想要给某个已经存在的model增加一个属性,或者想要增加一个新的model.cupboard提供的数据库升级方案如下:
1.给model增加属性
public class Bunny { public Long _id; // for cupboard public String name; // bunny name public String furColor; // 新增字段,意思是兔毛的颜色 public Integer cuteValue ; // bunny cuteness...
2.修改AndroidManifest.xml中的数据库的version.通常是加1.
public class PracticeDatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "cupboardTest.db"; private static final int DATABASE_VERSION = 2; ...
3.在onUpgrade函数里写升级逻辑.你必须考虑到所有的可能性.例如从1升级到3,从2升级到3等等.
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 这行代码会尝试创建新的列或新的表 cupboard().withDatabase(db).upgradeTables(); // 有可能需要给一些新增的列设置默认值 if (newVersion == 2) { ContentValues cv = new ContentValues(); cv.put("furColor", "black"); cupboard().withDatabase(db).update(Bunny.class, cv); }}
例子工程
例子见: https://github.com/koalahamlet/cupboardTestApp/tree/master/app/src/main . 包含了一些基本的增删改查和升级数据库的例子.
常见问题
Cupboard怎么处理重复ID的情况?例如,数据库里存放的是twitter上的用户,每个用户的id都是唯一的,我想确保数据库里没有重复的twitter用户的id.有没有办法指定某一列是主键?
你可以启用@Index和 @CompositeIndex这两个注解,方法是:
Cupboard cupboard = new CupboardBuilder().useAnnotations().build();
这两个注解的相关介绍见: https://bitbucket.org/qbusict/cupboard/wiki/existingData
如何定义某一列的数据类型(int或text)? Cupboard 会自动判断所需的数据类型吗?
字段的类型是由model类的属性的类型自动判断得出的.
如何存储日期格式的数据?
Cupboard中的日期被存储为Long类型.
long time = Calendar.getInstance().getTimeInMillis();
获取时可以按照自己的需求去格式化.(使用SimpleDateFormat,例如”yyyy-MM-dd’T’HH:mm:ss.SSS’Z’”)
如何表示1对1的关联关系?
Cupboard不是一个真正的ORM库,它不处理关联关系,否则就会让事情变得很复杂.如果你需要类似级联删除的功能,可以手动实现.
如果删除表中的所有数据?
public static void clearAllBunnyData(db) { db.execSQL("DELETE FROM " + Bunny.class.getSimpleName());}
资料
- Cupboard bitbucket
- Cupboard Getting Started
- Cupboard working with annotations and existing data
- Cupboard working with databases
- Cupboard talk
更多相关文章
- [Android Pro] 完美Android Cursor使用例子(Android数据库操作)
- Android联系人数据库全
- Android和Java本地数据库新选择
- 在Android中查看和管理sqlite数据库
- Android联系人数据库全解析(1)
- [转」android中的数据库操作
- android中的数据库操作ZZ
- 系出名门Android(9) - 数据库支持(SQLite),
- android数据库