翻译 DBFlow Getting Started 入门指南

翻译 DBFlow Getting Started 入门指南

版权声明 2016 AlexZHOU

转载请注明本文出处

(翻译以个人理解为主,具体请看英文)

原文链接:https://github.com/Raizlabs/DBFlow/blob/master/usage/GettingStarted.md

In this section we run through how to build a simple database, table, and establish relationship between Model.

在本节中,我们将通过Model构建一个简单的数据库、表和建立关系。

The Ant Queen: We are curious in storing data about our ant colonies. We want to track and tag all ants for a specific colony as well as each queen Ant.

蚁后:我们好奇知道蚁群数据是怎么保存的。我们要跟踪和标记所有蚂蚁的特定群体以及每个蚁后。

We have this relationship:

我们得到这样的关系:

Colony (1..1) -> Queen (1...many)-> Ants

Setting Up DBFlow 设置DBFlow

To initialize DBFlow, place this code in a custom Application class (recommended):

初始化DBFlow,放置在这段代码在你自定义的 Application 类中(推荐):


public class ExampleApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        FlowManager.init(this);
    }

}

Never fear, this only initializes once and it will hold onto only the Application context even if initialized in another Context.

别担心,这只是初始化一次而且它会守住只有应用程序,甚至使用其他Context初始化它。

Lastly, add the definition to the manifest (with the name that you chose for your custom application):

最后,定义添加到清单(对应您的自定义应用程序的名称)


<application
  android:name="{packageName}.ExampleApplication"
  ...>
</application>

Defining our database 定义我们的数据库

In DBFlow, a @Database is a placeholder object that generate a subclass of BaseDatabaseDefinition, which connect all tables, ModelAdapter, Views, Queries, and more under a single object. All connections are done pre-compile time, so there’s no searching, reflection, or anything else that can slow down the runtime impact of your app.

在DBFlow,@Database是一个占位符,可以产生子类对象BaseDatabaseDefinition,他可以连接所有Tables,ModelAdapter,Views,Queries还有更多其下的对象。所有连接都在预编译的时候完成,所以没有搜索,反射,和任何其他能减慢您的应用的运行时间。

In this example, we need to define where we store our ant colony:

在这个例子中,我们需要定义我们要把蚁群保存到哪里(说白了就是定义数据库):


@Database(name = ColonyDatabase.NAME, version = ColonyDatabase.VERSION)
public class ColonyDatabase {

  public static final String NAME = "Colonies";

  public static final int VERSION = 1;
}

For best practices, we create the constants NAME and VERSION as public, so other components we define for DBFlow can reference it later (if needed).

最好的实现,我们创建public类型的常量NAMEVERSION ,其他组件定义数据库工作流可以参考它后(如果需要)。

Note: If you wish to use SQLCipher please read setup here

如果你希望使用SQLCipher,请阅读setup here

Creating our tables and establishing relationships 创建我们的表和建立关系

Now that we have a place to store our data for the ant colonies, we need to explicitly define how the underlying SQL data is stored and what we get is a Model that represents that underlying data.

现在,我们有地方去存储我们的蚁群数据了,我们需要明确定义 Model 来保存数据和展示数据。

The Queen Table 蚁后表

We will start and go top-down within the colony. There can be only one queen per colony. We define our database objects using the ORM (object-relational mapping) model. What we do is mark each field we want represented as a database column in a class that corresponds to an underlying database table.

我们将从上到下理解蚁群关系。只有一个蚁后在一个蚁群里面。我们使用ORM模式定义我们的数据库对象。我们将要做的是标志每一个字段在类中表现的数据表列并通知对应的数据库表。

In DBFlow, anything that represents an object that interacts with the database using ORM must implement Model. The reason for an interface vs. a baseclass ensures that other kinds of Model such as views/virtual tables can conform to the same protocol and not rely on one base class to rule them all. We extend BaseModel as a convenience for the standard table to Model class. Also, if not forced to at least an interface, this prevents passing in objects not meant for the methods they belong to.

在DBFlow中,任何要使用ORM实现数据库交互的都必须实现接口 Model 。基类统一接口的原因是要确定他们都是 Model ,像那些views/virtual tables 可以同意使用协议和没有依赖在一个子类上去规范他们。我们一般继承 BaseModel 作为一个便利的标准表和 Model 类。当然,如果不是强制的至少一个接口,这可以防止在对象中不属于他们的方法。

To properly define a table we must:

要正确定义一个表,我们必须:

  1. Mark the class with @Table annotation

  2. Point the table to the correct database, in this case ColonyDatabase

  3. Define at least one primary key

  4. The class and all of its database columns must be package private, public, or private (with corresponding getters and setters), so that the classes generated from DBFlow can access them.

(大意如下:)

  1. 使用 @Table 注释标记类

  2. 将表链接正确的数据库,例如ColonyDatabase

  3. 至少定义个一主键

  4. 类及其所有数据库中的列(model中的变量)必须用 public 或private,private的必须有(getter和setter方法)。这样从DBFlow生成的类可以访问它们。

The basic definition of Queen we can use is:

我们可以这样定义一个基础的 Queen 表:


@Table(database = ColonyDatabase.class)
public class Queen extends BaseModel {

  @PrimaryKey(autoincrement = true)
  long id;

  @Column
  String name;

}

So we have a queen ant definition, and now we need to define a Colony for the queen.

这样我们定义了一个蚁后,现在我们需要给蚁后定义一个 Colony

The Colony 蚁群

@ModelContainer // more on this later.
@Table(database = ColonyDatabase.class)
public class Colony extends BaseModel {

  @PrimaryKey(autoincrement = true)
  long id;

  @Column
  String name;

}

Now that we have a Queen and Colony table, we want to establish a 1-1 relationship. We want the database to care when data is removed, such as if a fire occurs and destroys the Colony. When the Colony is destroyed, we assume the Queen no longer exists, so we want to “kill” the Queen for that Colony so it no longer exists.

现在我们拥有一个有 QueenColony 的表,我们需要建立1-1的关系。我们想要数据知道当数据被删除,比如发生火灾 Colony 。当 Colony 被销毁时,我们的 Queen 也将消失,当然,我们杀死 Queen 的同时, Colony 也将不存在。

1-1 Relationships 关系

To establish the connection, we will define a Foreign Key that the child, Queen uses:

为了建立他们的关系,我们将会定义一个外键作为Child:


@ModelContainer
@Table(database = ColonyDatabase.class)
public class Queen extends BaseModel {

  //...previous code here

  @Column
  @ForeignKey(saveForeignKeyModel = false)
  Colony colony;

}

Defining the Foreign Key as a Model will automatically load the relationship when loading from the database using a query on the value of the reference in that column. For performance reasons we default saveForeignKeyModel=false to not save the parent Colony when the Queen object is saved.

Model 定义外键的时候,查询数据库的时候,该外键的值会被加载。处于性能原因,我们定义 saveForeignKeyModel=false 不保存 ColonyQueen 对象保存是时候。

If you wish to keep that pairing intact, set saveForeignKeyModel=true.

如果你想保持这种配对完好,设置 saveForeignKeyModel=true

As of 3.0, we no longer need to explicitly define the @ForeignKeyReference for each referenced column. DBFlow will add them automatically to the table definitions based on the @PrimaryKey of the referenced tables. They will appear in the format of {foreignKeyFieldName}_{referencedColumnName}.

在3.0的版本中,我们不再要求每个列需要声明 @ForeignKeyReference 。DBFlow会自动将它们添加到表定义中,基于引用表的@PrimaryKey。它们将出现在格式 {foreignKeyFieldName}_{referencedColumnName}

The Ant Table + 1-to-Many 蚂蚁表 + 一对多

Now that we have a Colony with a Queen that belongs to it, we need some ants to serve her!

现在我们有 ColonyQueen 隶属于它,现在我们需要蚂蚁来服务它。


@Table(database = ColonyDatabase.class)
public class Ant extends BaseModel {

  @PrimaryKey(autoincrement = true)
  long id;

  @Column
  String type;

  @Column
  boolean isMale;

  @ForeignKey(saveForeignKeyModel = false)
  ForeignKeyContainer<Queen> queenForeignKeyContainer;

  /**
  * Example of setting the model for the queen.
  */
  public void associateQueen(Queen queen) {
    queenForeignKeyContainer = FlowManager.getContainerAdapter(Queen.class).toForeignKeyContainer(queen);
  }
}

We have the type, which can be “worker”, “mater”, or “other”. Also if the ant is male or female.

我们需要有 type ,哪个可以当”worker”, “mater” 或者 “other” ,当然还有男女之分。

We use a ForeignKeyContainer in this instance, since we can have thousands of ants. For performance reasons this will “lazy-load” the relationship of the Queen and only run the query on the DB for the Queen when we call toModel(). With this said, in order to set the proper values on the ForeignKeyContainer you should call its generated method for converting itself into a ForeignKeyContainer via FlowManager.getContainerAdapter(Queen.class).toForeignKeyContainer(queen).

我使用 ForeignKeyContainer 在这个实例中,以为我们有成千上万的蚂蚁。处于性能考虑, Queen 将会延迟加载,只有当我们调用toModel() 去查询数据库的时候,数据库才会找出对应的 Queen 。与此说,为了在 ForeignKeyContainer 上设置适当的值,你应该通过调用其生成的方法 FlowManager.getContainerAdapter(Queen.class).toForeignKeyContainer(queen) 为自己转换成 ForeignKeyContainer

Since ModelContainer usage is not generated by default, we must add the @ModelContainer annotation to the Queen class in order to use for a ForeignKeyContainer.

由于 ModelContainer 在默认情况下不会使用,我们需要添加 @ModelContainer 注解在
Queen 类中才能使用 ForeignKeyContainer

Lastly, using @ForeignKeyContainer can prevent circular references. If both the Queen and Colony referenced each other by Model, we would run into a StackOverFlowError, since they both would try to load each other out of the database.

最后,使用 @ForeignKeyContainer 可以防止循环引用,如果 QueenColony 互相引用,我们会碰上的 StackOverflowError,因为他们都将尝试从数据库加载对方中。

Next, we establish the 1-to-many relationship by lazy-loading the ants, since we may have thousands, if not, millions stored:

接下来,我们延迟加载建立1对多的蚂蚁关系,当蚂蚁数量成千上万时,甚至是一百万计数:


@ModelContainer
@Table(database = ColonyDatabase.class)
public class Queen extends BaseModel {
  //...

  // needs to be accessible for DELETE
  List<Ant> ants;

  @OneToMany(methods = {OneToMany.Method.SAVE, OneToMany.Method.DELETE}, variableName = "ants")
  public List<Ant> getMyAnts() {
    if (ants == null || ants.isEmpty()) {
            ants = SQLite.select()
                    .from(Ant.class)
                    .where(Ant_Table.queenForeignKeyContainer_id.eq(id))
                    .queryList();
    }
    return ants;
  }
}

If you wish to lazy-load the relationship yourself, specify OneToMany.Method.DELETE and SAVE instead of ALL. If you wish not to save them whenever the Queen’s data changes, specify DELETE and LOAD only.

如果你想给自己懒加载,指定 OneToMany.Method.DELETESAVE,代替 ALL。如果每当 Queen 的数据变化时候,您不希望保存,那么只指定 DELETELOAD

(学习DBFlow的时候顺便坐了一下翻译,哪里写的不对的地方请指出)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值