您的位置:首页 > 其它

翻译 DBFlow Getting Started 入门指南

2016-04-11 11:19 435 查看

翻译 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类型的常量
NAME
VERSION
,其他组件定义数据库工作流可以参考它后(如果需要)。

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:

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

Mark the class with
@Table
annotation

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


Define at least one primary key

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.

(大意如下:)

使用
@Table
注释标记类

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

至少定义个一主键

类及其所有数据库中的列(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.

现在我们拥有一个有
Queen
Colony
的表,我们需要建立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
不保存
Colony
Queen
对象保存是时候。

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!

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

@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
可以防止循环引用,如果
Queen
Colony
互相引用,我们会碰上的
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.DELETE
SAVE
,代替
ALL
。如果每当
Queen
的数据变化时候,您不希望保存,那么只指定
DELETE
LOAD


(学习DBFlow的时候顺便坐了一下翻译,哪里写的不对的地方请指出)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: