【译】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 NOTE: This will create another DAO object internally so low memory devices NOTE: To protect against recursion, there are a couple of places were auto- NOTE: If you have an auto-refreshed field that is an object that also has an |
外键自动刷新(注意和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 In our example, the foreign fields in Question and Answer could be set to auto- |
最大外键刷新级别
这用来设置级别装配外键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 For example: |
String值(默认none),如果这个属性被设置为一个string值,用于在CREATE TABLE语句中定义这个列。
默认情况下,为了建立column,数据库类型被用来自动生成SQL语句。列名由ORMLite提供。 例如: @DatabaseField( columnDefinition= "LONGBLOB not null", |
foreignAutoCreate This only works if generatedId is also set to true. |
外键域自动生成
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,将order1.account传给内部的accountDao.create(). orderDao.create(order1); |
version 1. The current-value of the version field is read from the object NOTE: If you define a Date field to be a version then you can also use it as |
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) |
foreignColumnName |
外键列名 和这个表关联的外键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) |
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语句来查询这个类型。 //Image是个实现了Serialiazle接口的类 |
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 不同。 |