Android數據庫ORMlite框架翻譯系列(第二章:part 1)


前言

由於第二章是整個文檔的核心,內容也很多,所以分次翻譯。下一章的內容會繼續本章接着翻譯。

-------------------------------------------------------------------------------------

 

2 如何使用

這一章進入到更多詳細地使用ORMLite的各種功能。

 

2.1 配置你的Class

為了配置你的class使其持久化,你需要做下面幾步:

①添加@DatabaseTable 注解到你每個需要持久化的類的頂部。你也可以用@Entity

②添加@DatabaseField 注解到你需要持久化的字段的上面。你也可以使用@Column和其他的。

③為每個class添加一個無參的構造器,並且構造器在包內是可見的。

 

2.1.1 添加ORMLite 注解

自從java5開始,注解是有效的特殊代碼標識,它提供meta信息包括類、方法或成員變量。把指定的類和成員變量存入數據庫,ORMLite既支持它自己的注解(@DatabaseTable和 @DatabaseField)也支持很多來自javax.persistence包中標准的注解。注解是配置你的class最簡單的方式,當然你也可以使用java代碼或者Spring xmlSpring是個框架,更多信息google一下)對class進行配置。

ORMLite注解,對每個你想要持久化到SQL數據庫的java類你都需要添加@DatabaseTable注解到public class 這一行的正上方。每個被這些注解標記過的class都將持久化到它自己的數據庫表中。例如:

@DatabaseTable(tableName = "accounts")

public class Account {

...

 

@DatabaseTable注解可以有個可選的tableName 參數,也就是這個類對於的表名。如果沒有特別指出,那么這個類名將默認作為表名。使用示例中的Account的對象都將會作為一條記錄持久化到數據庫名為account的表中。這將會在DaoManager實例化內部Dao的時候使用到。

除此之外,對於每個class你需要添加@DatabaseField注解到class的成員變量上,這個類是需要持久化到數據庫的。每個成員變量都將被作為數據庫中記錄的一個字段進行持久化。示例:

 

@DatabaseTable(tableName = "accounts")

public class Account {

@DatabaseField(id = true)

private String name;

@DatabaseField(canBeNull = false)

private String password;

...

 

name字段,它是一個字符串並且是數據庫中記錄的唯一標識(主鍵)。在上面的示例中,account表的每條記錄都有兩個字段:

password字段,它也是一個字符串,它不能為null

@DatabaseField注解可以用下面的一些成員:(對常用的字段進行翻譯,其他的參考原文)

常用的注解

成員名

數據類型

描述

columnName

String

數據庫的列名。如果你沒有設置這個成員名,會用標准的形式代替它。

dataType

 

字段的數據類型。通常情況下,數據類型是從java類的成員變量獲取的,並不需要進行特殊指出。它相當於是SQL的數據類型。

defaultValue

String

當我們在表中創建新的記錄時的一個字段的默認值。默認情況下是沒有這個值的。

width

Integer

字段的寬度,主要用於字符串字段。默認是0,意味着采用默認的數據類型和具體的數據庫的默認情況。對於字符串以為在255個字符即使有些數據庫並不支持。

canBeNull

Boolean

字段是否能被分配null值。默認是true。如果你設置成false,那么你每次在數據庫中插入數據是都必須為這個字段提供值。

id

Boolean

這個字段是否是id,默認是false。在一個class中只有一個成變量可以有這個值。id字段是一條記錄的唯一標識而且是必需的,只有generatedId和 generatedIdSequence其中之一。

generatedId

Boolean

字段是否自動增加。默認為false。類中的一個成員變量設置了這個值,它告訴數據庫每添加一條新記錄都自動增加id。當一個有generatedid的對象被創建時使用Dao.create()方法,數據庫將為記錄生成一個id,它會被返回並且被create方法設置進對象。

generatedIdSequence

String

序列編號的名字,這個值在生成的時候會被使用。和generatedId相似,但是你能夠指定使用的序列名稱。默認是沒有的。一個class中只有一個成員變量可以設置這個值。這僅僅在數據庫需要序列生成id時才需要它。如果你選擇使用generatedId代替它,那么代碼將自動增加序列名。

 

其他注解

foreign

throwIfNull

useGetSet

persisted

unknownEnumName

format

uniqueIndexName

allowGeneratedIdInsert

foreignAutoRefresh

columnDefinition

unique

uniqueIndex

uniqueCombo

indexName

index

uniqueIndexName

version

maxForeignAutoRefreshLevel

foreignColumnName

foreignAutoCreate

 

2.1.2 使用javax.persistence 注解

取代使用ORMLite注解,你可以使用來自javax.persistence包的更多的標准JPA注解。取代@DatabaseTable注解,你可以使用javax.persistence @Entity注解。示例:

@Entity(name = "accounts")

public class Account {

...

 

@Entity注解有個可選的name參數,它用於指定表名。如果沒有指定,類名將是默認的表名。

在每個成員變量中取代使用@DatabaseField注解,你可以用javax.persistence注解: @Column, @Id, @GeneratedValue, @OneToOne,@ManyToOne, @JoinColumn, and @Version. 示例:


下面這些javax.persistence注解和字段都支持:

注解

注解屬性

描述

@Entity

name

用於關聯的數據庫表的名字。如果沒有設置那么類名將被作為表名。

@Column

name

用作表字段的名字。如果沒有設置那么變量名將作為字段名。

length

數據庫表字段的長度。可能只有應用在字符串並且只被某些數據庫類型支持。默認是255

nullable

設置成true,那么這個字段允許插入null值。

unique

 添加一個約束,它在表中必須是唯一的。

@GeneratedValue

 

用於定義一個自動增長的id值,它只能用於添加到@Id注解。

 

@OneToOne 

 

成員變量使用這些注解后會被認為是外鍵字段。 ORMLite沒有實現多個或一個關系,它也不能使用任何注解成員。它只能使用這些注解的兩者之一來表明它是一個外鍵。

@ManyToOne

 

@JoinColumn

name

設置成員變量的列名(字段名)。

nullable

設置成true,那么這個字段允許插入null值。

@Version

 

使用它將會把short, integer, long,  Date這些類型的成員轉化成版本成員。

如果@Column注解在成員變量上用了一個未知的類型,那么它將被認為是序列化類型字段並且這個對象需要實現java.io.Serializable

 

2.1.3 添加無參構造器

在你給class添加了注解字段后,你也需要添加一個無參的包內可見的構造器。當一個對象在查詢中被返回時,ORMLite使用java反射機制構造一個對象並且構造器需要被調用。所以你最終的示例擁有注解和構造器的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

}

...

}

 

2.2 持久化數據類型 

下面這些java類型能夠被ORMLite持久化到數據庫。數據庫具體編碼幫助SQL類型和數據庫具體持有類型的相互轉化。

(具體的類型相互轉化在此就不作介紹了,參見原文)。

 

2.3 連接源

注意:關於連接源,android用戶應該參見手冊中Android詳細文檔。

為了使用數據庫和DAO對象,你需要配置JDBC調用數據源和ORMLite調用連接源。連接源是連接物理SQL數據庫的一個工廠。這里是創建簡單、單連接的代碼示例:

// single connection source example for a database URI

ConnectionSource connectionSource =

new JdbcConnectionSource("jdbc:h2:mem:account");

 

這包中也包括了類JdbcPooledConnectionSource ,它是一個相對簡單的連接池的實現。一個數據庫連接已經釋放而成為關閉,之后向他們添加內部列表他們都會拒絕。只有在沒有休眠的可用的連接時,新的連接才需要創建。JdbcPooledConnectionSource也是同步的並且可以用於多線程中。在連接關閉前它可以設置空閑連接的最大數和存活的最長時間。

// pooled connection source

JdbcPooledConnectionSource connectionSource =

new JdbcPooledConnectionSource("jdbc:h2:mem:account");

// only keep the connections open for 5 minutes

connectionSource.setMaxConnectionAgeMillis(5 * 60 * 1000);

 


JdbcPooledConnectionSource也有一個一直存活的線程,它偶爾ping一下池中空閑的每個連接,目的是為了確認他們是有效的,關閉的那個就不再有效。在你從池中取得連接之前你也可以測試連接是否有效。

// change the check-every milliseconds from 30 seconds to 60

connectionSource.setCheckConnectionsEveryMillis(60 * 1000);

// for extra protection, enable the testing of connections

// right before they are handed to the user

connectionSource.setTestBeforeGet(true);

 


有很多其他額外的數據,他們能夠被使用,包括很多更強大甚至高性能的池連接管理器。你可以用你自己直接封裝的DataSourceConnectionSource類來例舉說明。

// basic Apache data source

BasicDataSource dataSource = new BasicDataSource();

String databaseUrl = "jdbc:h2:mem:account";

dataSource.setUrl(databaseUrl);

// we wrap it in the DataSourceConnectionSource

ConnectionSource connectionSource =

new DataSourceConnectionSource(dataSource, databaseUrl);

 


當你用ConnectionSource時,你想調用close()方法來關閉一些底層的連接。推薦像下面這樣的模式。

JdbcConnectionSource connectionSource =

new JdbcPooledConnectionSource("jdbc:h2:mem:account");

try {

// work with the data-source and DAOs

...

} finally {

connectionSource.close();

}

 


很不幸,DataSource接口沒有關閉方法,所以你使用DataSourceConnectionSource你必須關閉底層數據源,通過操作DataSourceConnectionSource上的close()方法。

 

2.4 配置DAOs

一旦在你的類中有注解並且定義了你的ConnectionSource,你就需要創建一個DAOData Access Object),它是一個擁有數據庫操作句柄的單一持久化類。每個DAO都有兩個泛型參數:①我們用DAO持久化的類,②id字段,它用於確定數據庫具體的記錄。如果你的類沒有ID字段,你可以放入Object或者Void作為第二個參數。例如,在上面的Account類,成員變量nameID字段,所以ID類是String

創建DAO最簡單的方式是使用DaoManager類的靜態方法createDao。示例:

Dao<Account, String> accountDao =

DaoManager.createDao(connectionSource, Account.class);

Dao<Order, Integer> orderDao =

DaoManager.createDao(connectionSource, Order.class);

 


注意:你需要使用DaoManager.createDao()方法創建你自己的DAO類,所以如果內置ORMLite功能是需要他們,他們可以被再次利用並且不能再次生成。創建DAO會有昂貴的操作代價並且很多設備有資源限制(比如移動設備應用),盡可能重復使用DAO 

如果你想更好的類層次的機構或者你需要添加附加的方法套你的DAOs中,你應該考慮定義一個接口,它繼承自Dao接口。這個接口不是必需的,但是他說一種好的模式,這樣你的代碼在關聯JDBC持久化的時候會更少。接下來是一個相當於本手冊前面章節Account類的DAO接口的示例:

/** Account DAO which has a String id (Account.name) */

public interface AccountDao extends Dao<Account, String> {

// empty wrapper, you can add additional DAO methods here

}

 

然后在實現中,你需要擴展BaseDaoImpl基類。這里是個實現你的DAO接口的示例。

/** JDBC implementation of the AccountDao interface. */

public class AccountDaoImpl extends BaseDaoImpl<Account, String>

implements AccountDao {

public AccountDaoImpl(ConnectionSource connectionSource)

throws SQLException {

super(connectionSource, Account.class);

}

}

 


那就是你需要定義你的DAO類。如果有特殊的操作需要並且Dao基類沒有提供的方法,你可以自由添加更多方法到你的DAO接口和添加到你的實現中。

注意:如果你正在使用一個定制的DAO,然后確保添加daoClass參數到你自己定制的DAO類的@DatabaseTable注解。這會被DaoManager用於內部實例化DAO

 

2.5 支持的數據庫

ORMLite支持下面的數據庫。這些數據庫中的某些數據庫有具體需要遵守的文檔。(下面給出支持的數據庫,具體文檔參見官方文檔)

支持的數據庫

MySQL

H2

Android SQLite

HSQLDB

Netezza

DB2

Postgres

SQLite

Microsoft SQL Server

Derby

ODBC

Oracle

 

2.6 整合

這樣你有一個注解對象被持久化,添加一個無參構造器,創建你的ConnectionSource並且定義你的DAO類。你已經開始持久化和查詢你的數據庫對象了。你需要下載並且添加H2 jar文件到你的classPath中,如果你想讓這個示例跑起來的話。下面是整合的代碼:

// h2 by default but change to match your database

String databaseUrl = "jdbc:h2:mem:account";

JdbcConnectionSource connectionSource =

new JdbcConnectionSource(databaseUrl);

// instantiate the dao with the connection source

AccountDaoImpl accountDao = new AccountDaoImpl(connectionSource);

// if you need to create the 'accounts' table make this call

TableUtils.createTable(connectionSource, Account.class);

// create an instance of Account

Account account = new Account("Jim Coakley");

// persist the account object to the database

accountDao.create(account);

...

// destroy the data source which should close underlying connections

connectionSource.destroy();

 


PS: 第二章還在翻譯中... 文中有不妥之處希望讀者提出,轉載請注明出處。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM