译自 http://ormlite.com/javadoc/ormlite-core/doc-files/ormlite_toc.html#SEC_Contents
1 Getting Started
1.1 Downloading ORMLite Jar
Java使用core和jdbc
Android使用core和android
1.2 Configuring a Class
@DatabaseTable(tableName = “accounts”)
@DatabaseField(id = true) //主键
需要无参构造器
1.3 Configuring a DAO
简单的方法是用DaoManager类的createDao方法。
Dao<Account, String> accountDao =DaoManager.createDao(connectionSource, Account.class);
1.4 Code Example
http://ormlite.com/android/examples/
2 How to Use
2.1 Setting Up Your Classes
@DatabaseTable; @DatabaseField; 无参构造器。
2.1.1 Adding ORMLiteAnnotations
@DatabaseTable(tableName = “accounts”)
@DatabaseField(id = true) //主键
@DatabaseField(canBeNull = false) //不能为空
columnName, datatype, defaultValue, width,generatedId, generatedIdSequence, foreign, useGetSet, format, unique, index….
2.1.2 Using javax.persistence Annotations
也可以用JPA annotations。
2.1.3 Adding a No-Argument-Constructor
2.2 Persisted Data Types
2.3 Connection Sources
Android用户见第四章。
需要配置JDBC的DataSource和ORMLite的ConnectionSource。ConnectionSource是连接数据库的工厂。
// single connection source example for a database URI
ConnectionSource connectionSource =
new JdbcConnectionSource("jdbc:h2:mem:account");
略
2.4 Setting Up the DAOs
每个DAO对应一个持久化类。DAO需要两个参数:持久化类和主键类。若没有主键,可以传入Object或void。
Dao<Account, String> accountDao =
DaoManager.createDao(connectionSource,Account.class);
Dao<Order, Integer> orderDao =
DaoManager.createDao(connectionSource,Order.class);
注意:应该用DaoManager.createDao()创建,这样DAO会被重用。
如果需要更好的类层次或为DAO添加额外的方法,你需要考虑定义一个继承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基类。
/** JDBC implementation of the AccountDao interface. */
public class AccountDaoImpl extendsBaseDaoImpl<Account, String>
implements AccountDao {
//this constructor must be defined
public AccountDaoImpl(ConnectionSource connectionSource)
throws SQLException {
super(connectionSource, Account.class);
}
}
还需要@DatabaseTable(daoClass = AccountDaoImpl.class)
2.5 Supported Databases
2.6 Trying It All Together
2.7 Table and Schema creation
2.7.1 TableUtils Class
TableUtils类提供了很多静态方法,帮助创建和删除表。
createTable(ConnectionSource, Class)
dropTable(ConnectionSource, Class)
clearTable(Connection, Class) //可能很慢,建议删除重建
2.7.2 TableCreator Class
用于Spring
2.8 Identity Columns
用于DAO操作query-by-id,delete, refresh, update一个特定的行。
2.8.1 Fields With id
2.8.2 Fields With generatedId
可以设置一个long或integer属性为generatedId。这个属性的值你能否更改依赖于数据库类型。
2.8.3 Fields With generatedIdSequence
2.9 DAO Usage
添加新的行
Account account = new Account();
account.name = "Jim Coakley";
accountDao.create(account);
根据id属性查找
Account account = accountDao.queryForId(name);
if (account == null) {
account not found handling …
}
更新某个对象的行,这需要id属性
account.password = "_secret";
accountDao.update(account);
刷新对象,如果数据库已经变化
accountDao.refresh(account);
删除对象delete
遍历所有的行
// page through all of the accounts in the database
for (Account account : accountDao) {
System.out.println(account.getName());
}
注意,必须遍历完所有的行,不能提前return,否则可能内存泄露。
2.10 Indexing Fields
ORMLite提供有限的索引支持。首先要指出id属性已经是索引,所以不能再额外声明为索引。创建非独特的索引,帮助优化查询,也可以显著改进中大型表的查询时间。
public class Account {
@DatabaseField(id = true)
private String name;
//this indexes the city field so queries on city
//will go faster for large tables
@DatabaseField(index = true)
private String city;
…
}
上例创建了一个account_city_idx索引,如果想用不同的名字可以indexName = “othername”。
如果你通常city和state属性一起查询,你可能像在两个属性创建同一个索引。
@DatabaseField(indexName ="account_citystate_idx")
private String city;
@DatabaseField(indexName ="account_citystate_idx")
private String state;
这有同时对city和state的查询才被优化。
如果需要独特的索引,uniqueIndex = true。
2.11 Issuing Raw SQL Statements
2.12 Foreign Object Fields
2.13 Foreign Collections
2.14 DAO Enabled Objects
account.setDao(accountDao);
account.create();
3 Custom Statement Builder
对于自定义的查询,queryBuilder()方法返回QueryBuilder对象来构建自定义查询。
3.1 Query Builder basics
首先,用Java常量设置属性名是一个好的规范,这样就可以用于查询(即使属性名和行名相同)。
@DatabaseTable(tableName = "accounts")
public class Account {
public static final String PASSWORD_FIELD_NAME = "password";
…
@DatabaseField(canBeNull = false, columnName = PASSWORD_FIELD_NAME)
private String password;
…
// get our query builder from the DAO
QueryBuilder<Account, String>queryBuilder =
accountDao.queryBuilder();
// the 'password' field must be equal to"qwerty"
queryBuilder.where().eq(Account.PASSWORD_FIELD_NAME,"qwerty");
// prepare our sql statement
PreparedQuery<Account> preparedQuery =queryBuilder.prepare();
// query for all accounts that have"qwerty" as a password
List<Account>accountList = accountDao.query(preparedQuery);
或
// query for all accounts that have that password
List<Account> accountList =
accountDao.query(
accountDao.queryBuilder().where()
.eq(Account.PASSWORD_FIELD_NAME, "qwerty")
.prepare());
或
// query for all accounts that have that password
List<Account> accountList =
accountDao.queryBuilder().where()
.eq(Account.PASSWORD_FIELD_NAME, "qwerty")
.query();
3.2 Building Queries
4 Using With Android
4.1 Android Basics
由于安卓系统没有对JDBC的官方支持,ORMLite直接调用安卓的数据库API访问SQLite。
4.1.1
需要创建自己的database helper类,继承OrmLiteSqliteOpenHelper类并重写一些方法。它并且提供了DAO类。
onCreate(…)方法在app安装时创建数据库,onUpgrade处理当升级app版本时表的更新。
4.1.2
helper可以被所有的activity和线程重用。如果你建立了对同样数据库的两个连接,可能发生意外。我们建议使用OpenHelperManager监控helper的使用。
4.1.3
简单使用OpenHelperManager的方法是让所有activity都继承OrmLiteBaseActivity,也有OrmLiteBaseListActivity和OrmLiteBaseService。这些类提供了helper属性和getHelper()方法,并在onCreate()方法中自动创建helper。
4.1.4
如果不想继承那些类,你需要模仿它们的功能。在代码开始处调用OpenHelperManager.getHelper(Contextcontext ,Class openHelperClass)方法,保存对helper的引用,不再需要时调用OpenHelperManager.release()。
privateDatabaseHelper databaseHelper = null;
@Override
protected void onDestroy(){
super.onDestroy();
if (databaseHelper != null) {
OpenHelperManager.releaseHelper();
databaseHelper = null;
}
}
private DBHelpergetHelper() {
if (databaseHelper == null) {
databaseHelper =
OpenHelperManager.getHelper(this,DatabaseHelper.class);
}
return databaseHelper;
}
4.1.5
如果你使用了OrmLiteBaseActivity这些类,OpenHelperManager会通过反射找到helper。另一个连接helper的方法是在strings.xml文件中设置键值对<open_helper_classname,helper类全名>。也可以在静态代码块中用OpenHelperManager.setOpenHelperClass(Class)设置。
4.1.6
使用Android原生的SQLite数据库类型,SqliteAdnroidDatabaseType。
4.1.7
WARNING:如果在OpenHelperManager.getHelper()之前或release()之后访问数据库,会报异常。
4.2 Using Table Config File
我们曾经执着于解决建立DAO的问题,当时认为是由于ORMLite对象带宽。虽然做了一些改进和DAO的缓存,但创建DAO还是会花费很久并且产生太多GC。最后发现罪魁祸首是Android OS,特别是Method.equals()。因为annotation使用了这个方法,查找annotation的值代价很大,经常造成数以千计对象的GC。Android方面已经知道了这个问题并在改善中,但我们不知道这个问题最终何时会被解决。
对于这个问题,我们做了一些变动。第一,我们用一些reflection hack进行一次短期运行。用这种机制的Annotation比原生Android快了20倍。
只用少部分工作,你可以从应用中移除所有的annotation并且使创建DAO非常快。 ORMLite支持从configuration文件夹在数据配置。当DAO创建好,会用到这些配置,从而完全摆脱对于annotation方法的依赖。
4.2.1
OrmLiteConfigUtil类将ormlite_config.txt配置文件写在res/raw/ormlite_config.txt中。你需要在项目的DatabaseHelper类旁继承这个类。
public class DatabaseConfigUtil extends OrmLiteConfigUtil {
public static void main(String[] args) throws Exception {
writeConfigFile("ormlite_config.txt");
}
}
4.2.2
每当数据类发生改变都需要在本地JRE运行这个工具类。
4.2.3
默认下这个工具会在当前路径找有@DatabaseTable的.java文件。你也可以列出这些类。
public class DatabaseConfigUtil extends OrmLiteConfigUtil {
private static final Class<?>[] classes = new Class[] {
SimpleData.class,
};
public static void main(String[] args) throws Exception {
writeConfigFile("ormlite_config.txt", classes);
}
}
4.2.4
工具运行完毕后会在raw文件夹下创建ormlite_config.txt文件,运行前这个文件夹必须存在。
4.2.5
当你在资源文件中创建配置文件后,Android的build插件会把它加入R文件。
4.2.6
你的DatabaseHelper类应在构造器中增加配置文件的id。
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION,
R.raw.ormlite_config);
}
注意:也可以用文件名或File类作为参数。
4.2.7
运行。
4.3 Android Logging
4.4 Runtime Versus SQL Exceptions
默认情况,对于JDBC和SQL调用,大多数DAO方法需要写抛出SQLException。但在安卓中,大部分异常都继承RuntimeException,所以写很多被忽略的try代码块不合适。因此我们引入了RuntimeExceptionDao,封装了所有DAO的调用,将SQL异常重抛为运行时异常。
Dao<Account, String> dao =
DaoManager.createDao(connectionSource, Account.class);
RuntimeExceptionDao<Account, String> accountDao =
new RuntimeExceptionDao<Account, String>(dao);
或者
RuntimeExceptionDao<Account, String> accountDao =
RuntimeExceptionDao.createDao(connectionSource, Account.class);
4.5 Upgrading Your Schema
当你更新应用,你可能对表做出变化。在onUpgrade方法中你可以改变你的表。
SQLite中,你只能重命名表或增加行。你不能重命名或移除列或改变约束。记住SQLite是无类型的所以不需要改变列的类型。