ORMLite是常用的一个ORM框架,她不止可以用在Android的sqlite数据库,也可以使用她操作其他常见的数据库。这儿是根据官方文档抽取来的android用法。

一,添加依赖

导入ormlite-core.jar和ormlite-android.jar:下载jar
或者build.gradle中添加:

    compile 'com.j256.ormlite:ormlite-android:5.0'    compile 'com.j256.ormlite:ormlite-core:5.0'

二,创建Bean类

1>类使用@DatabaseTable注解,标识一个表。
2>成员变量使用 @DatabaseField 注解,表示表中的列。
3>相关属性设置可以查询其依赖包中的DatabaseTable和Column注解类。持久化的数据类型可以查阅ORMLite官方文档或库源码。
4>添加一个无参的构造函数。当执行查询返回结果时,ORMLite会使用Java反射构造函数创建对象。

@DatabaseTable(tableName = "accounts")public class Account {    //generatedId = true表示id主键自动生成    @DatabaseField(generatedId = true)      private int id;    //id = true表示这个列可以通过ID方法执行查询,更新,删除    @DatabaseField(id = true)    private String name;    //canBeNull = false表示不可以为空    @DatabaseField(canBeNull = false)    private String password;    public Account() {        // ORMLite 需要一个无参构造器     }    public Account(String name, String password) {        this.name = name;        this.password = password;    }    public int getId()      {          return id;      }      public void setId(int id)      {          this.id = id;      }     public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }}

三,创建数据库

1>继承OrmLiteSqliteOpenHelper 创建database helper;
2>在onCreate方法中调用TableUtils.createTable创建表,onUpgrade方法执行数据库更新。TableUtils类提供了一些创建和删除表的静态方法,参考源代码。

public class DatabaseHelper extends OrmLiteSqliteOpenHelper {    private static final String TABLE_NAME = "sqlite.db";    public DatabaseHelper(Context context) {        super(context, TABLE_NAME, null, 2);    }    @Override    public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {        try {            TableUtils.createTable(connectionSource, Bean.class);        } catch (java.sql.SQLException e) {            e.printStackTrace();        }    }    @Override    public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {    }}

四,创建DAO

在数据访问对象(Data Access Objects (DAO))类中隔离数据库操作,提供创建,删除,更新,等等操作。每个表都对应一个DAO,每个DAO有两个参数:使用DAO持久化数据的实体类和用来标示指定表中行的ID列,如果类中没设置ID列,可以把对象或null作为第二个参数。例如,在上面Account类中,“name”成员是ID列(id = true),所以ID列是字符串。
创建DAO的最简单的方法是调用DaoManager.createDao(),这样如果它们被内部ORMLite功能需要,可以重复使用,而不是重新创建(创建DAO很消耗资源,应该尽可能重复利用):

DaoString> accountDao =DaoManager.createDao(connectionSource, Account.class);Dao<Order, Integer> orderDao =DaoManager.createDao(connectionSource, Order.class);

使用这种方式需要ConnectionSource参数,和实体类的Class对象,ConnectionSource参数可以通过OrmLiteSqliteOpenHelper的getConnectionSource()方法获得:

ConnectionSource connectionSource = OrmLiteSqliteOpenHelper.getConnectionSource();

如果想要一个更好的类层次结构,或者在DAO中需要添加较多的方法,可以定义一个接口,继承Dao接口,接口不是必须的,但这样做可以减少耦合:

/** Account DAO ,具有字符串id (Account.name) */public interface AccountDao extends Dao<Account, String> {    // 添加 DAO的方法}

然后实现类继承BaseDaoImpl并实现上面定义的接口:

/** 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类的,需要到相应的实体类@DatabaseTable注解中添加daoClass参数:

@DatabaseTable(daoClass = AccountDaoImpl.class)public class Account {   …}

也可以在DatabaseHelper中调用OrmLiteSqliteOpenHelper.getDao创建:

    private Dao accountDao;      public Dao getAccountDao() throws SQLException      {          if (AccountDao == null)          {              AccountDao = getDao(Account.class);          }          return accountDao;      }  

五,运行时与SQL异常

默认情况下,大多数的DAO方法都会抛出SQLException,大部分的异常继承RuntimeException,所以会需要大量的try … catch语句,出于这个原因,RuntimeExceptionDao包装了调用DAO方法会出现的运行时异常SQL exceptions:

DaoString> dao = DaoManager.createDao(connectionSource, Account.class);RuntimeExceptionDaoString> accountDao = new RuntimeExceptionDaoString>(dao);

或者直接使用其createDao方法:

RuntimeExceptionDaoString> accountDao =RuntimeExceptionDao.createDao(connectionSource, Account.class);

在DatabaseHelper中可以调用OrmLiteSqliteOpenHelper.getRuntimeExceptionDao。

六,使用DAO

插入新的行到数据库:

Account account = new Account();account.name = "Jim Coakley";accountDao.create(account);

如果对象具有注解声明的id参数,那么我们就可以使用其ID在数据库中查找此对象:

Account account = accountDao.queryForId(name);if (account == null) {  account not found handling … }

如果改变对象的成员属性,必须调用update()将改变更新到数据库中:

account.password = "_secret";accountDao.update(account);

刷新对象

如果数据空正使用的某个对象被其他实体改变,需要刷新这个对象,保证这个对象是实时的:

accountDao.refresh(account);

删除对象对应的数据库中的行,一旦对象已经从数据库中删除,您可以继续使用在内存中的该对象,但任何更新或刷新会失效:

accountDao.delete(account);

迭代

该DAO本身也是一个迭代器,因此可以直接遍历数据库数据中表的行:

// page through all of the accounts in the databasefor (Account account : accountDao) {    System.out.println(account.getName());}

这种方式必须遍历数据库中表的所有行,然后才会关闭潜在的sql对象。 如果没有通过循环遍历所有的行,
ORMLite并不会关闭sql对象,数据库的连接会被弱化并且只有GC回收才会被关闭,这样会导致程序Bug,所以最好使用
try…finally迭代器。以下for循环,是一个非常糟糕的代码:

for (Account account : accountDao) {    if (account.getName().equals("Bob Smith")) {        // you can't return, break, or throw from here        return account;    }}

也可以选择直接使用迭代器,因为for循环式并不总是最佳的。这样允许使用try…finally,达到一种更优化的代码:

 CloseableIterator iterator = accountDao.closeableIterator();      try {         while (iterator.hasNext()) {            Account account = iterator.next();            System.out.println(account.getName());         }      } finally {         // close it at the end to close underlying SQL statement         iterator.close();          }

或者使用迭代包装器,for循环之后仍然可以关闭:

 CloseableWrappedIterable wrappedIterable =       accountDao.getWrappedIterable();       try {          for (Account account : wrappedIterable) {              …          }       } finally {          wrappedIterable.close();   }

七,使用OpenHelperManager

DatabaseHelper可能在App或多个Activity的线程中被多次实例化使用,如果同时有多个对象,可能会出现过时的数据和意外的结果。所以建议使用OpenHelperManager管理DatabaseHelper的使用:

private DatabaseHelper databaseHelper = null;private void releaseHelper() {    if (databaseHelper != null) {        OpenHelperManager.releaseHelper();        databaseHelper = null;    }}private DatabaseHelper getHelper() {    if (databaseHelper == null) {        databaseHelper =            OpenHelperManager.getHelper(this, DatabaseHelper.class);    }    return databaseHelper;}

还可以让Activity继承OrmLiteBaseActivity,OrmLiteBaseActivity对OpenHelperManager的使用做了进一步封装,还有OrmLiteBaseListActivity, OrmLiteBaseService, OrmLiteBaseTabActivity等,不过一般不这么做。但是可以在使用OpenHelperManager的时候拿来参考。
然后通过databaseHelper操作数据库:

    Dao accountDao = getHelper().getAccountDao();    Account account = new Account ();    account.setName("one");    account.setPassword("123");    accountDao.create(account);

八,ORMLite外键

ORMLite支持外键的概念,既一个对象的一个或者多个属性保存在相同数据库中其他表中。比如数据库中有一个Order对象,每个Order对象都对应一个Account对象,然后就说Order(是一个表)对象的Account(也是一个表)成员有外键属性。id成员在表创建的时候会生成”account_id”列:

@DatabaseTable(tableName = "orders")public class Order {    @DatabaseField(generatedId = true)    private int id;    @DatabaseField(canBeNull = false, foreign = true)    private Account account;    …}

当创建有外键属性成员的对象(Order)时,外键对象(Account)不会被自动创建(Account表不会自动创建)。如果外键对象(Account对象)在数据库中有generated id(Order对象有 id成员),应该在创建引用这个对象(Order对象有Account成员)的对象(Order对象)之前创建外键对象(Account表):

Account account = new Account("Jim Coakley");accountDao.create(account);// 这时会创建一个account对象,并且设置generated ids// 现在用order设置account,创建并插入account表Order order = new Order("Jim Sanders", 12.34);order.setAccount(account);…orderDao.create(order);

某些情况下如果希望外键自建,可以在外键(account)的注解中设置foreignAutoCreate参数。
当你查询一个Order时,会获得一个account对象,这个对象只有id属性被设定了值,其他属性都是默认值(null, 0, false, etc.)。如果需要使用这个account对象的其他值,则必须调用accountDao类的refresh方法获得这个Account对象的属性:

Order order = orderDao.queryForId(orderId);System.out.println("Account-id on the order should be set: " +   order.account.id);// 此时 order.account.name为nullSystem.out.println("But other fields on the account should not be set: "   + order.account.name);// 用AccountDao刷新一下accountaccountDao.refresh(order.getAccount());System.out.println("Now the account fields will be set: " +   order.account.name);

也可以在注解中添加foreignAutoRefresh参数值设置自动刷新外键对象的数据。
有不同的方式查询外键的参数值,比如查询匹配某个account的所有Order,通过ID参数的成员和account的name查询:

// query for all orders that match a certain accountList results =  orderDao.queryBuilder().where().    eq("account_id", account.getName()).query();

也可以让ORMLite从该account中自动提取id获得:

// ORMLite will extract and use the id field internallyList results =  orderDao.queryBuilder().where().    eq("account_id", account).query();

九,外键集合

上面说了Account是Order的外键,如果一个Account对象对应多个Order对象,则可以将其以成员的形式通过 @ForeignCollectionField注解以以下形式添加到Account中去:

public class Account {    …    @ForeignCollectionField(eager = false)    ForeignCollection orders;    …}

成员类型只可以使用ForeignCollection< T> 或 Collection< T>。注解参数可以查阅库中的ForeignCollectionField类。
当改变了Collection中的order时,需要调用update在数据库中更新它:

for (Order order : account.orders()) {   // 如果改变了order的某些成员   order.setAmount(123);   // 必须在数据库中更新account   account.orders.update(order);}

十,事务

当对数据库有较多的执行动作时,用事务处理比较好,图个方便,下段代码摘自ormlite的事务使用

private boolean doBatchInTransaction(final List list, final int batchType) {        boolean doBatch = false;        ConnectionSource connectionSource = ormLiteDao.getConnectionSource();        TransactionManager transactionManager = new TransactionManager(connectionSource);        Callable callable = new Callable() {            @Override            public Boolean call() throws Exception {                return doBatch(list, batchType);            }        };        try {            doBatch = transactionManager.callInTransaction(callable);        } catch (SQLException e) {            LogUtil.e(e);        }        return doBatch;    }    private boolean doBatch(List list, int batchType) {        int result = 0;        try {            for (T t : list) {                switch (batchType) {                    case DaoOperation.INSERT:                        result += ormLiteDao.create(t);                        break;                    case DaoOperation.DELETE:                        result += ormLiteDao.delete(t);                        break;                    case DaoOperation.UPDATE:                        result += updateIfValueNotNull(t);                        break;                    default:                        LogUtil.w("no this type.");                        break;                }            }        } catch (SQLException e) {            LogUtil.e(e);        }        return result == list.size();    }

十一,更新数据库

更新app时,可能会修改现有的数据库,这时就需要在 创建的DatabaseHelper的onUpgrade方法中进行一些工作了。比如在表中增加一列,可以在onUpgrade方法中这么做:

Dao dao = getHelper().getAccountDao();// 在表account中增加 "age" 列dao.executeRaw("ALTER TABLE `account` ADD COLUMN age INTEGER;");

所有能做的就是重新命名表名和添加新列,不要重命名或删除列或更改列的属性。
最常用的,是根据版本条件更改数据库:

if (oldVersion < 2) {  // we added the age column in version 2  dao.executeRaw("ALTER TABLE `account` ADD COLUMN age INTEGER;");}if (oldVersion < 3) {  // we added the weight column in version 3  dao.executeRaw("ALTER TABLE `account` ADD COLUMN weight INTEGER;");}

或者:

dao.executeRaw(    "ALTER TABLE `account` ADD COLUMN hasDog BOOLEAN DEFAULT 0;");dao.updateRaw("UPDATE `account` SET hasDog = 1 WHERE dogCount > 0;");

这儿用到了数据库语句,可以查阅sqlite官方文档。

更多请参考 ORMLite官方文档 ,

更多相关文章

  1. Android Hawk数据库 github开源项目
  2. Android中数据库升级
  3. android直接读取数据库文件
  4. android 加密数据库
  5. android 数据库
  6. Android SQLite数据库实例
  7. android之SQlite创建数据库操作
  8. android连接mysql数据库

随机推荐

  1. 重画Progressbar的进度
  2. android中各种height和width总结
  3. android关于AndroidManifest.xml详细分析
  4. Android(安卓)底部弹出Activity
  5. Android(安卓)在部分华为手机上出现乱码
  6. android 8.1Settings添加设置项
  7. android项目集成 flutter
  8. 解决android http请求带中文参数会乱码(u
  9. Android(安卓)修改actionbar标题的颜色和
  10. Android开源代码汇总