ORMLite笔记

译自 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是无类型的所以不需要改变列的类型。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值