【译】Android 数据库 ORMLite

  @DatabaseField

 

cloumnName:指定字段名,不指定则变量名作为字段名  canBeNull:是否可以为null  
dataType:指定字段的类型 defaultValue:指定默认值  width:指定长度
 id:指定字段为id generatedId:指定字段为自增长的id,不能id,generatedIdSequence通用 foreign 指定这个字段的对象是一个外键,外键值是这个对象的id
useGetSet:指定ormlite访问变量使用set,get方法默认使用的是反射机制直接访问变量 throwIfNull,如果空值抛出异常 persisted:指定是否持久化此变量,默认true
unique:字段值唯一 uniqueCombo整列的值唯一 index:索引
uniqueIndex 唯一索引 foreignAutoRefresh 外键值,自动刷新 foreignAutoCreate 外键不存在时是否自动添加到外间表中
foreignColumnName外键字段指定的外键表中的哪个字段    

 

 

ormLite 排序 条件查询

all = dao.queryBuilder().orderBy("Id", true)

.where().eq("Type", key)

.and().eq("owner", Pub.user.getAccount())

.and().eq("UserType", Pub.user.getUserType())

.query(); 

 

 

 

分页查询

select top 页大小 *
from table1
where id<=
      (select min (id) from
      (select top ((页码-1)*页大小) id from table1 order by id desc) as T
       )    
order by id desc

 

 

 

unique
Adds a constraint to the table so that this field that it has to be unique across
all rows in the table. For example, you might have an Account class which has a
generated account-id but you also want the email address to be unique across all
Accounts. If more than one field is marked as unique in a table, then each of the
fields by themselves must be unique. For example, if you have the firstName
and lastName fields, both with unique=true and you have "Bob", "Smith" in
the database, you cannot insert "Bob", "Jones" nor "Kevin", "Smith".
To have more than 1 field that are each unique in combination, see the
uniqueCombo setting. You can also use the uniqueIndexName to create an
index for this field.

Boolean型(默认false),唯一性。为table增加限制,使得这个field在table的所有行中,都唯一。

比如,你有一个Account类,有个自增的account-id列,但是你还向让所有Account的邮箱地址不重复。

如果table中,有不止一个field标记为unique,那么它们中的每一个必须都是unique的。比如,如果你

有firstName和lastName两个field,都是unique=true的。

你表中已经有了“Bob”,“Smith”。那你不能插入"Bob", "Jones" ,也不能插入 "Kevin", "Smith"(一列

相同也不行)。如果你想让不止一个field组合的结果是unique的,看uniqueCombo的设置。

也可以使用uniqueIndexName去为这个field建一个索引。

uniqueCombo
Adds a constraint to the table so that a combination of all fields that have
uniqueCombo set to true has to be unique across all rows in the table.
For example, if you have the firstName and lastName fields, both with
uniqueCombo=true, and you have "Bob", "Smith" in the database, you
cannot insert another "Bob", "Smith" but you can insert "Bob", "Jones" and
"Kevin", "Smith".

Boolean型(默认false),为table加限制,使得uniqueCombo=true的所有这些field组合起来的数据

在全表中是唯一的。

比如,如果你有firstName和lastName两个field,都是uniqueCombo=true的。

你表中已经有了“Bob”,“Smith”。那你不能插入“Bob”,“Smith”(两列都相同)。

但是可以插入"Bob", "Jones"和"Kevin", "Smith"(只有一列相同)。

 

index
Boolean value (default false) to have the database add an index for this field.
This will create an index with the name columnName with a " idx" suffix.
To specify a specific name of the index or to index multiple fields, use the
indexName field.

Boolean型(默认false),让数据库为这个field增加一个索引。这会生成一个“列名+idx后缀”

格式的索引。如果想有一个特殊的索引名,或者要为多列建索引。使用indexName。

uniqueIndex
Boolean value (default false) to have the database add a unique index for this
field. Same as index but this will ensure that all of the values in the index
are unique. If you just want to make sure of unique-ness then you can use the
unique field instead.

Boolean型(默认false),让数据库为这个field增加一个索引。uniqueIndex作用和index相同,

但是会保证index列的所有值都是unique的。

如果你仅想保证unique,没想建立索引。那你可以使用unique代替。

indexName
String value (default none) to have the database add an index for this field
with this name. You do not need to specify the index boolean as well. To index
multiple fields together in one index, each of the fields should have the same
indexName value.

String值(默认none),让数据库为这个field增加一个以这个String值命名的索引。你不需要

再去指定index的值。如果想为多个field一起建立一个索引,每个field的indexName需要设置

为相同String值。

uniqueIndexName
String value (default none) to have the database add a unique index for this field
with this name. Same as index but this will ensure that all of the values in the
index are unique. For example, this means that you can insert ("pittsburgh",
"pa") and ("harrisburg", "pa") and ("pittsburgh", "tx") but not another
("pittsburgh", "pa").

String值(默认none),让数据库为这个field增加一个以这个String值命名的索引。

uniqueIndexName作用和index相同,但是会保证index列的所有值都是unique的。

例如,这意味着你可以插入("pittsburgh","pa") 和 ("harrisburg", "pa") 和 ("pittsburgh", "tx") 。

但是不能再插入一个("pittsburgh", "pa").

foreignAutoRefresh

Set this to be true (default false) to have a foreign field automagically refreshed

when an object is queried. The default is to just have the ID field in the object

retrieved and for the caller to call refresh on the correct DAO. If this is set to
true then, when the object is queried, a separate database call will be made to
load of the fields of the foreign object via an internal DAO. NOTE: this will
not automagically create the foreign object if you create an object that has this
field set.

NOTE: This will create another DAO object internally so low memory devices
may want to call refresh by hand.

NOTE: To protect against recursion, there are a couple of places were auto-
refreshing has been limited. If you are auto-refreshing a class that itself has
field with foreignAutoRefresh set to true or if you are auto-refreshing a class
with a foreign collection, in both cases the resulting field will be set to null and
not auto-refreshed. You can always call refresh on the field directly if you need
it.

NOTE: If you have an auto-refreshed field that is an object that also has an
auto-refreshed field, you may want to tune the maxForeignAutoRefreshLevel
value. See below.

外键自动刷新(注意和foreignAutoCreate区分)当设置成true时(默认false),你查询query

一个object时,它里边的外键field,也会自动刷新出值。默认(false)只会检索出一个ID field,

供调用者再去使用正确的DAO调用一次refresh。

当设置为true,当object被query的时候,会建立一个独立的数据库查询,通过一个内部的DAO,

来加载object中的外键object。

注:这个foreignAutoRefresh用来查询,不是用来create。所以虽然foreightAutoRefresh=true,

你create 一个object的时候,也不会自动create它里边的外键object。

注:自动刷新会建立另一个内部的DAO object,所以低内存的设备需要手动刷新。

注:为了避免递归,有一些情况下自动刷新是被限制的。如果 “你通过objectA去自动刷新一个

objectB,这时候发现B中还有一个设置为foreignAutoRefresh=true的field 关联到objectC” 或者

“有个外键集合”。这两种情况这个外键field都会被设置为null,而且不被自动刷新。如果你需要,

你总是可以在这个field上直接调用refresh。

注:如果你有一个自动刷新的field,它本身还包含自动刷新的filed。

这时候你可以调整maxForeignAutoRefreshLevel(最大自动刷新级别)的值。如下。

maxForeignAutoRefreshLevel
This can be used to set the maximum number of levels to configure foreign
objects. For example, if you have a Question which has an foreign field of
the best Answer, and the Answer has an foreign field to the corresponding
question, then the configuration back and forth can get large. This is especially
a problem with auto-refreshed fields when you lookup the Question it could
cause an infinite loop. By default, ORMLite only goes through 2 levels but you
can decrease it to 1 (0 is not valid) or increase it. The higher the number the
more database transactions happen when you load in your Question.

In our example, the foreign fields in Question and Answer could be set to auto-
refresh. If this is true then with the maxForeignAutoRefreshLevel set to 1,
when you query for a Question, the Answer field will be auto-refreshed, but
the Question field on the answer will only have its id field set. It will not be
auto-refreshed.

最大外键刷新级别

这用来设置级别装配外键object。例如,如果你有一个Question表,有个外键field

保存最佳Answer,而且这个Answer有个外键关联到有关的问题,那么这个

向前向后可能会变的很大,这是个有关自动刷新field的特殊问题,当你查询Question

的时候,可能导致一个无限的循环。默认情况下ORMLite只允许向下查找两层,

但是你可以将它减为1(0是不合法的)或者增加它。当你加载Question的时候,

这个值越大产生的数据库事务处理越多。

在我们的例子中,Question和Answer 中的外键field可以被设置为自动刷新。

如果这个假设成立,并且maxForeignAutoRefreshLevel设置为1,当你查询

一个Question时,Answer field会被自动刷新。但是answer中的Question域

的数据不会被自动刷新,只包含id域。

allowGeneratedIdInsert
If this is set to true (default is false) then inserting an object with the ID field
already set will not override it with a generated-id. This is useful when you have
a table where you are inserting items that sometimes have IDs and sometimes
need them generated. This only works if the database supports this behavior
and if generatedId is also true for the field.

Boolean值(默认false),如果被设置为true,那么插入一个已经有ID field已经有值的

object时,这个值不会被自动生成的id覆盖。

这在“向一个表中插入一些item,它们有时候有ID,有时候没有、需要自动生成"的时候很有用。

仅适用于:数据库支持这种行为,并且此field的generatedid=true。

columnDefinition

If this is set with a string then it will be used to define the column in the CREATE

TABLE statement. By default the database type is used to auto-generate the SQL
necessary to create the column. The column name is provided by ORMLite.

For example:
@DatabaseField(columnDefinition = "LONGBLOB not null",
dataType = DataType.BYTE_ARRAY)
public byte[] bigBunchOfBytes;

String值(默认none),如果这个属性被设置为一个string值,用于在CREATE TABLE语句中定义这个列。

默认情况下,为了建立column,数据库类型被用来自动生成SQL语句。列名由ORMLite提供。

例如:

@DatabaseField( columnDefinition= "LONGBLOB not null",
dataType = DataType.BYTE_ARRAY)
public byte[] bigBunchOfBytes;

foreignAutoCreate
Set this to be true (default false) to have the foreign field automatically created
using an internal DAO if its ID field is not set (null or 0). So when you call
dao.create() on the parent object, any foreign field that has this set to true
will possibly generate an additional create call via an internal DAO. By default
you have to create the object using its DAO directly.

This only works if generatedId is also set to true.
// the account field in Order has foreignAutoCreate=true
Order order1 = new Order();
// account1 has not been created in the db yet, id field is null
order1.account = account1;
// this will create order1 in the order table _and_
// pass order1.account to the internal accountDao.create().
orderDao.create(order1);

外键域自动生成

Boolean值(默认false),设置为true时,当一个外键域的ID域没有被设置(还是null或0),

会被一个内部的DAO自动create。

所以当你在父object上调用dao.create(),所有foreignAutoCreate设置为true的

外键field可能会通过一个内部DAO产生一个额外的create调用。默认情况下你

需要直接使用一个object的DAO来生成它。只有在generatedId=true的情况适用

//Order中的account域 具有 foreignAutoCreate=true的属性
Order order1 = new Order();
//account1还没在db中被create(只被new过了),id 域为null
order1.account = account1;

//这会在order表中新建order1,将order1.account传给内部的accountDao.create().

orderDao.create(order1);

version
Set this to true (default false) to have this field be a version for the row. A
version field adds restrictions when an object is updated to the datbase that
protects against data corruption when multiple entities are updating the row
at the same time. This is very useful in distributed database scenarios if (for
example) a utility process is updating an Account and you don’t want to protect
against overwriting a user update from the web-server.

1. The current-value of the version field is read from the object
2. The update statement is augmented with a "WHERE version = current-
value"
3. The new-value being updated in the database is changed by ORMLite to
be the current-value + 1 or the current java.util.Date
4. If the row has been updated by another entity then the update will not
change the database since the current-value will not match the version
column in the database and 0 rows changed will be returned by the update
method
5. However, if the current-value does match the version field in the database
then the row will be updated, the object’s version field will be set by
ORMLite to the new-value, 1 will be returned from update
Only the following field types are appropriate for version fields: short,
integer, long, and Date fields. Date can also be stored as a string (dataType
= DataType.DATE_STRING) or long (dataType = DataType.DATE_LONG).

NOTE: If you define a Date field to be a version then you can also use it as
a modification time on the row. When the object is created in the database,
the version field will be automatically inserted with the current Date. When
the object is updated, the version field will be updated with the current Date.
Something like the following works well (the dataType=... is optional):
@DatabaseField(version = true, dataType = DataType.DATE_LONG)
private Date lastModified;

Boolean值(默认false),设置为true时,让这个field成为这行的version(版本标识)。

当一个object被更新到一个数据库中,但是这个数据库为防止多个实体同时更新这一行

造成数据冲突、加了保护。这时候,一个version域就被用来增加更新的限制。

这在分布式数据库方案中很有用。如果(例如)一个实体程序在更新一个Account,

你又不想手动去防止覆盖掉一个来自web-server端的用户更新。

1 version域的current-value从object中进行读取

2 更新语句有条件为“WHERE version = current-value"

3 被数据库更新的新的值,被ORMLite改成current-value+1 或者当前系统时间java.util.Date

4 如果这行被另一个实体更新,那么不会对数据库造成修改。因为corrent-value和数据库中的

version不相符,更新方法会返回“0行被修改”的结果。但是,如果current-value和数据库中

version域的值相符,这行会被更新。version域会被ORMLite更改为一个新的值。update会返回1。

只有以下类型的列适合作为version列:short,integer,long和Date。

Date也可以被存储为一个string (dataType= DataType.DATE_STRING) 或者long (dataType =

DataType.DATE_LONG).

注:当你定义一个Date field作为version时,你也可以把它看作这一行的修改时间。

当这个object在数据库中被新建,version域会被自动插入成为当前Date。

当object被更新,version又被更新为当前Date。

以下的情况是允许的(dataType=xxx,是可选的)

@DatabaseField(version = true, dataType = DataType.DATE_LONG)
private Date lastModified;

foreignColumnName
Name of the foreign object’s field that is tied to this table. This does not need to
be specified if you are using the ID of the foreign object which is recommended.
For example, if you have an Order object with a foreign Account then you may
want to key off of the Account name instead of the ID.
NOTE: Setting this implies foreignAutoRefresh is also set to true because
there is no way to refresh the object since the id field is not stored in the
database. So when this is set, the field will be automatically refreshed in another
database query.

外键列名

和这个表关联的外键object的域的名字。也就是 外键字段指定外键表中的哪个字段。

如果你像推荐的做法那样,默认使用外键object的ID作为外键key。则这个属性不需要设置。

例如,当你有个Order object有个外键Account,你也许想用Account name作为外键key

代替ID。

注:设置这个值,隐含着foreignAutoRefresh也被设置为true。 因为id 域没有存储在数据库中

,所以你没办法手动更新外键object。

当这个属性设置为true。这个域在一个数据库查询中会被自动刷新。

 

unique                  

index          

uniqueIndex = unique + index   

indexName = index + "自定义索引名"   

uniqueIndexName = unique + index + "自定义索引名"

值唯一不重复

索引

值唯一的索引

具有自定义名的索引

具有自定义名的索引,值唯一

 

 

 

 

 

 2.1.2

ORMLite javax.persistence
@DatabaseTable(tableName = "accounts") @Entity(name = "accounts")

@DatabaseField

(name、length、unique)

(canBeNull)

@Column

{name、length、unique}

{nullable}

(id=true or generatedId=true) @Id  @GeneratedValue

ORMLite没有实现多个或一个关系,它也不能使用任何注解成员。

它只能使用这些注解的两者之一来表明它是一个外键。

@OneToOne or @ManyToOne

成员变量使用这些注解后会被认为是外键字段。 

(version=true) @Version
  @JoinColumn
   

 

 

 

 

 

 

 

 

 

 

 

 

2.1.3 增加一个无参构造函数

需要添加一个具有至少包内的可见性的无参构造函数。当一个object通过一个query返回,

ORMLite使用Java反射构造这个object,需要调用一个构造函数。

最后一个Account的例子看起来是这样的:
@DatabaseTable(tableName = "accounts")
public class Account {
@DatabaseField(id = true)
private String name;
@DatabaseField(canBeNull = false)
private String password;
  Account() {
    // all persisted classes must define a no-arg constructor
    // with at least package visibility
  }
  ...
}

 

  DataType SQL  
String DataType.STRING VARCHAR  
String DataType.LONG_STRING LONGVARCHAR  

String

DataType.STRING_BYTES

VARBINARY

String类型被持久化为byte数组 byte[](SQL类型VARBINARY)。

许多数据库是Unicode编码适配的 (MySQL/Postgres),有些不是(SQLite)。

为了存储有重音号或者其他特殊字符的string,你不得不使用这种类型将它们编码成byte数组。

Unicode 字符集默认被用于string 和 bytes的相互转化。你可以使用DatabaseField中的format域

指定一个定制字符集,替代这个域。对这种类型的比较和排序,可能不会成功(和数据库类型有关)。

boolean or Boolean

DataType.BOOLEAN

or

DataType.BOOLEAN_OBJ

BOOLEAN  

java.util.Date 

DataType.DATE

TIMESTAMP

这个类型自动使用一个内部的?参数,因为它的string格式在匹配数据库格式时不可靠。

注:这和DataType.SQL_DATE 指代的java.sql.Date 不一样。

注:某些数据库只提供秒second。所以millisecond会等于0。

java.util.Date  DataType.DATE_LONG  

可以使用DataType.DATE_LONG替代,那样日期的millisecond值将会被存储为LONG类型。

注:这和DataType.SQL_DATE 指代的java.sql.Date 不一样。

注:某些数据库只提供秒second。所以millisecond会等于0。

java.util.Date  DataType.DATE_STRING  

时间会被存储为 yyyy-MM-dd HH:mm:ss.SSSSSS 格式的字符串。

注:这和DataType.SQL_DATE 指代的java.sql.Date 不一样。

注:某些数据库只提供秒second。所以millisecond会等于0。

注:由于和SimpleDateFormat相关的转化(reentrant)事件,每次一个DATE_STRING

日期被转换出/转换进 数据库。都有本地线程用来访问formatter。

formatter 是JAVA中用来格式化输出的类。

byte or Byte 

DataType.BYTE

or

DataType.BYTE_OBJ)

TINYINT   
byte array DataType.BYTE_ARRAY VARBINARY 这和将一个object序列化为byte[]的DataType.SERIALIZABLE不同。

注:为了反向兼容,类型为byte[]的域必须被指定为DataType.BYTE_ARRAY 或者

DataType.SERIALIZABLE,不会被自动检测。

@DatabaseField(dataType = DataType.BYTE_ARRAY)
byte[] imageBytes;

char or Character

DataType.CHAR

or

DataType.CHAR_OBJ

 CHAR  如果你在使用Derby,你需要考虑使用String来替代,因为Derby不允许字符field的比较。
short or Short

DataType.SHORT

or

DataType.SHORT_OBJ 

SMALLINT   
int or Integer

DataType.INTEGER

or

DataType.INTEGER_OBJ

INTEGER  
long or Long

DataType.LONG

or

DataType.LONG_OBJ

BIGINT  
float or Float DataType.FLOAT or DataType.FLOAT_OBJ FLOAT  
double or Double DataType.DOUBLE or DataType.DOUBLE_OBJ  DOUBLE

 

Serializable DataType.SERIALIZABLE VARBINARY

这是个特殊类型:将一个object 序列化为一系列byte,反向时进行反序列化。

这个field必须是个实现了java.io.Serializable接口的object。根据数据库类型的不同,

可能对可存储的object大小 有限制。

它和直接存储byte数据的DataType.BYTE_ARRAY不同。

一些数据库有些限制,不允许这个列作为id列。另有些数据库不允许对此类型的列进行查询。

如果你的数据库允许,你可能还需要使用Selet语句来查询这个类型。
为使用这个类型,必须显示指定DataType.SERIALIZABLE,而不会被自动检测。

//Image是个实现了Serialiazle接口的类
@DatabaseField(dataType = DataType.SERIALIZABLE)
Image image;

enum or Enum  DataType.ENUM_STRING  

VARCHAR

持久化默认作为枚举值的string名。

Persisted by default as the enumerated value’s string name as a VARCHAR type.

这个String name是默认的(比起ENUM_INTEGER更为推荐),因为它允许

你在list的任意位置添加另外的enum,不必担心之后必须转化数据。

你也可以指定@DatabaseField 中的unknownEnumName。作为在数据库中

找到一个不确定的enum值时,为它设置的名称。

enum or Enum DataType.ENUM_INTEGER  

此情况,枚举值的序会被存为INTEGER类型。

名字(ENUM_STRING)是默认设置(且被推荐),这允许你在list的任意位置

添加另外的enum,不必担心之后必须转化数据。如果你在list中插入(删除)一

个被存为数字的enum,旧的数据在反持久化的时候会不正确。

你也可以指定@DatabaseField 中的unknownEnumName。作为在数据库中

找到一个不确定的enum值时,为它设置的名称。

java.util.UUID DataType.UUID   VARCHAR。

存入使用uuid.toString(),取出使用UUID.fromString(String)。

你也可以将它标记为generated-id。这样不管什么时候插入,在这个

field上将调用java.util.UUID.randomUUID() 。

java.math.BigInteger DataType.BIG_INTEGER  

VARCHAR

它使用bigInteger.toString()来保存,使用string的构造方法来转化回来。

java.math.BigDecimal DataType.BIG_DECIMAL  

VARCHAR

它使用bigDecimal.toString()来保存,使用string的构造方法来转化回来。

java.math.BigDecimal DataType.BIG_DECIMAL_NUMERIC  

java.math.BigDecimal会被保存为NUMERIC格式

只有部分数据库支持,伴有各种默认精度的设置。

Android需要使用默认的DataType.BIG_DECIMAL

DateTime DataType.DATE_TIME    将Joda DateTIme作为long epoch millis 存储到数据库中。

这个保持器使用反射机制,来避免再加一个Joda jar包。

如果你想原生地使用这个类,你可以自定义一个数据保持器。

Epoch指的是一个特定的时间:1970-01-01 00:00:00 UTC。

UNIX时间戳:Unix时间戳(英文为Unix time, POSIX time 或 Unix timestamp)
是从Epoch(1970年1月1日00:00:00 UTC)开始所经过的秒数,不考虑闰秒。
一个小时表示为UNIX时间戳格式为:3600秒;
一天表示为UNIX时间戳为86400秒,闰秒不计算。
java.sql.Date DataType.SQL_DATE TIMESTAMP 和DataType.DATE指代的 java.util.Date 不同。
java.sql.Timestamp DataType.TIME_STAMP TIMESTAMP 和DataType.DATE指代的 java.util.Date 不同。

 

 

 

 

 

posted @ 2015-03-27 18:28  马小豆包  阅读(1979)  评论(0编辑  收藏  举报