读《50 Android Hacks》笔记整理Hack 41~Hack 43

第十章 数据库进阶

Hack 41 使用ORMLite构建数据库

ORMLite是一种对象关系映射(Object-Relational Mapping,简称ORM)工具,也可用于读写数据。
应用程序中所有数据库操作都通过ORMLite完成,而不需要手动编写任何SQL语句。该方法可以通过减少创建数据库schema的代码数量来节省时间。

41.1 开始

使用ORMLite时,需要用到其release版本中的两个JAR包:core和android。本例使用的是4.41版。获取依赖包后,就可以开始创建数据库schema了。
使用ORMLite的第一步是实现应用程序中需要操作的java实体类。在这过程中需要注意:在类中包含注解(Annotation)以允许ORMLite创建所需的数据库表。在有复杂数据库的情况下,当从对象中访问数据库时,这些注解还可以为ORMLite提供任何操作的信息。注意,使用注解的方法只是指定ORMLite所生成的数据库schema的多种方式中的一种。
使用ORMLite最常用的两种注解是DatabaseTable和DatabaseField。这些注解可以分别用于类及其成员变量,并运行生成最终的数据库表。使用注解的Article类的简单实现如下:

@DatabaseTable
public class Article{
   
    @DatabaseField(generatedId = true)
    public int id;
    @DatabaseField
    public String title,text;
    @DatabaseField
    public Date publishedDate;
    public Article(){}//ORMLite需要用到无参构造方法
}

该类,只是全部实现代码的一部分,它会生成如下创建表的SQL语句:

CREATE TABLE 'article'
    ('title' VARCHAR,'publishedDate' VARCHAR,'text' VARCHAR,'id' INTEGER PRIMARY KEY AUTOINCREMENT);

注意id字段对应的注解,对于该注解我们指定了generatedId = true参数,该参数表示该字段是主键(primary key),并且由SQLite数据库自动指定。另外还要注意,默认情况下,ORMLite使用类名作为SQL表名,使用成员变量名作为表的列名。
最后,我们可以注意到ORMLite需要类中提供一个无参构造函数。当ORMLite需要创建Article类的实例时,比如在查询并返回文章列表的情况下,ORMLite会使用无参构造函数,并通过反射机制设置成员变量(ORMLite也可以使用setter方法设置成员变量)。

41.2 坚如磐石的数据库schema

在这里我们会演示下述内容:
1.自定义数据库表和表列的名字
2.处理类之间的关系
3.关系的参照完整性(API Level 8 及以上)
4.级联删除(API Level 8 及以上)
5.交叉引用的唯一性约束
当定义schema时,第一个建议是使用final变量定义数据库表名和列名。因为在实践中,当成员变量被重构或移除时,该方法可以简化代码的维护工作。
下面我们来定义Category类,代码如下:

//指定表名
@DatabaseTable(tableName = Category.TABLE_NAME)
public class Category{
   
    public static final String TABLE_NAME = "categories",ID_COLUMN = "_id",NAME_COLUMN = "name",PARENT_COLUMN = "parent";

    //在DatabaseField中指定列名
    @DatabaseField(generatedId = true,columnName = ID_COLUMN)
    private int id;
    //name成员不能为空
    @DatabaseField(canBeNull = false,columnName = NAME_COLUMN)
    private String name;
    //标记为外键
    @DatabaseField(foreign = true,columnName = PARENT_COLUMN)
    private Category parent;

    public Category(){}
}

我们在DatabaseTable注解里指定了数据库表名,在DatabaseField注解里指定了表的列名。我们可以在应用程序中的任何地方使用这些public变量用于查询。
parent的成员变量声明如下:

@DatabaseField(foreign = true,foreignAutoRefresh = true,columnName = PARENT_COLUMN,columnDefinition = "integer references"+TABLE_NAME+"("+ID_COLUMN+") on delete cascade")
private Category parent;

我们可以使用columnDefinition定义列来微调SQL语句。这里我们指定parent列有一个外键指向categories表(外键的值定义在该表中)。这表明parent列的值要么是空,要么存在于categories表的_id列中。我们还指定当parent指向的分类被删除时,parent的记录也会被删除,这就是级联删除。级联删除并不是数据库要求的,但为了演示,我们在代码中包含这部分内容。为Category类创建数据库表的SQL语句如下:

CREATE TABLE 'categories' ('parent' integer references categories(_id) on delete cascade,'name' VARCHAR NOT NULL,'_id' INTEGER PRIMARY KEY AUTOINCREMENT)

ArticleCategory类用于将articles表映射到categories表,我们会为其两个成员变量设置uniqueCombo = true,代码如下:

@DatabaseTable(tableName = ArticleCategory.TABLE_NAME)
public class ArticleCategory{
   
    //final变量用于表示表名和列名
    public static final String TABLE_NAME = "articlecategories",ARTICLE_ID_COLUMN = "article_id",CATEGORY_ID_COLUMN = "category_id";

    //使用columnDefinition元素
    @DatabaseField(foreign = true,canBeNull = false,uniqueCombo = true,columnName = ARTICLE_ID_COLUMN,columnDefinition = "integer references"+Article.TABLE_NAME+"("+Article.ID_COLUMN+") on delete cascade")
    private Article article;

    //设置foreign = true用于存储复杂对象
    @DatabaseField(foreign = true,canBeNull = false,uniqueCombo = true,columnName = CATEGORY_ID_COLUMN,columnDefinition="integer references"+Category.TABLE_NAME+"("+Category.ID_COLUMN+") on delete cascade")
    private Category category;
    public ArticleCategory(){}
}

最终创建表的SQL语句如下所示:

CREATE TABLE 'articlecategories'('article_id' integer references articles(_id) on delete cascade,'category_id' integer references categories(_id) on
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值