前言
在android开发中,数据需要本地存储,当需要进行一系列的操作时,当然是使用sqlite。标准做法是继承SQLiteOpenHelper,重写onCreate和onUpdate方法。存在比较大的问题是,sql语句需要自己写,比较复杂繁琐而且重复率高,于是找了一个orm框架在新写的app中进行试用。
准备
下载地址:http://ormlite.com/releases/
下载core和android两个jar包,并引入工程即可
开发
模型注解
首先定义一个最常见的人员模型
// tableName定义表名,缺省为类名
@DatabaseTable(tableName = "table_person")
public class Person{
@DatabaseField(generatedId = true)
private int id;
// columnName定义字段名,缺省为变量名
@DatabaseField(columnName = "first_name")
private String firtName;
@DatabaseField
private String lastName;
// 需要定义一个无参构造函数,ormlite用来查询时用反射构建对象
public Person() {
}
// other constructors...
// getters and setters...
}
@DatabaseField注解域说明如下:
官网原文
名称
数据类型
默认值
说明
columnName
String
字段名,缺省为变量名
dataType
String
设置DataType即字段类型,通常不用指定,对应到SQL type
defaultValue
String
空
默认值,默认为空
width
Integer
通常用在字符串域。默认是0,意思是默认长度。字符串默认255
canBeNull
Boolean
true
是否可空
id
Boolean
false
指定该域是否为id,一个类只能有一个域设置此
generatedId
Boolean
false
该域是否为自动生成id域,一个类一个类只能有一个域设置此
generatedIdSequence
String
指定序列。从1开始,每次自增1
foreign
Boolean
false
指定该域是否对应另一个类,另一个类必须有id域
useGetSet
Boolean
false
是否需要通过get和set方法访问,通过java反射访问
unknownEnumName
String
如果该域为java枚举类型,可以指定一个枚举值,当数据库行的值没有在枚举类型中时,则使用此值
throwIfNull
Boolean
false
当字段为空进行插入时,ORMLite会抛出异常
persisted
Boolean
true
设置为false时,不存入数据库
format
unique
Boolean
false
列唯一性
uniqueCombo
Boolean
false
联合列唯一性
index
Boolean
false
建立索引,索引名默认为列名加后缀_idx
uniqueIndex
Boolean
false
建立唯一索引,在此索引中的所有值都是唯一的
indexName
String
none
指定索引名,则不需要另外指定index布尔值。为了在一个索引中索引多个域,每个域需要有相同的indexName
uniqueIndexName
String
none
指定唯一索引名称,在此索引中的所有值都是唯一的
foreignAutoRefresh
Boolean
false
外键自动刷新
maxForeignAutoRefreshLevel
allowGeneratedIdInsert
Boolean
false
如果设置为true,当插入包含id域的对象时,不会自动生成id域覆盖
columnDefinition
foreignAutoCreate
version
Boolean
false
foreignColumnName
String
指定外键对象关联域
完成Helper
与原生的SQLiteOpenHelper相似,使用ORMLite需要继承OrmLiteSqliteOpenHelper,如下:
public class DBHelper extends OrmLiteSqliteOpenHelper {
private DBHelper(Context context) {
super(context, TABLE_NAME, null, VERSION);
}
// 创建表在这里就非常简单了,使用TableUtils的createTable方法即可,不需要写CREATE TABLE等等的sql语句。
@Override
public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
try {
TableUtils.createTable(connectionSource, Person.class);
} catch (SQLException e) {
e.printStackTrace();
}
}
// 重写onUpdate方法
@Override
public void onUpgrade(SQLiteDatabase database,
ConnectionSource connectionSource, int oldVersion, int newVersion) {
try {
// 删除旧表再新建表,也可以对表进行相应的更新操作
TableUtils.dropTable(connectionSource, Person.class, true);
onCreate(database, connectionSource);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
获取Dao
对于orm来说,dao是用于数据库操作的通常做法。在Helper中加入如下代码:
// 声明静态实例
private static DBHelper instance;
// 声明dao
private Dao personDao;
/** * 单例获取该Helper * *@param context *@return */
public static synchronized DBHelper getHelper(Context context) {
context = context.getApplicationContext();
if (instance == null) {
synchronized (DatabaseHelper.class) {
if (instance == null)
instance = new DatabaseHelper(context);
}
}
return instance;
}
// 获取某个dao,有多个表的情况,可能需要写多个获取dao的方法
public Dao getPersonDao() throws SQLException {
if (personDao == null) {
personDao = getDao(Person.class);
}
return personDao;
}
// 释放资源
@Override
public void close() {
super.close();
personDao = null;
}
// 另外也可以有通用方法
public synchronized Dao getDao(Class clazz) throws SQLException {
Dao dao = null;
String className = clazz.getSimpleName();
if (daos.containsKey(className)) {
dao = daos.get(className);
}
if (dao == null) {
dao = super.getDao(clazz);
daos.put(className, dao);
}
return dao;
}
单独创建dao类
public class PersonDao {
private Context context;
public PersonDao(Context context) {
this.context = context;
}
public void add(Person person) {
try {
DBHelper.getHelper(context).getPersonDao().create(person);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
使用
准备好后,使用起来也非常方便
// 获取helper
DBHelper helper = DBHelper.getHelper(getContext());
// 构造
Person xiaoming = new Person();
xiaoming.setFirstName("Ming");
xiaoming.setLastName("Xiao");
// 保存
helper.getPersonDao().create(xiaoming);