版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/Achilles_Lee/article/details/78327849
引入
数据库的操作几乎在所有的安卓项目中都需要用到,目前市场主流的框架也有很多。这篇文章中介绍到的就是比较简单的一种基于运行时注解实现的数据库增删改差操作。
* 项目代码地址:https://github.com/BravoLee/AndroidDb
- 先介绍一下主要的类
- IBaseDao 定义数据库操作的接口,里面有数据库增删改查的接口方法。
- BaseDao是一个抽象类,他实现了IBaseDao的增删改查方法。
- UserDao继承BaseDao,他的作用除了提供数据库创建的语句之外,也给功能的扩展预留的控件。
- User是一个Bean类,一个Bean对应一个BeanDao。Bean中定义了这个表需要那些数据。Bean中的类和变量都需要加上注解。
- BaseDaoFactory是一个工厂方法类,他是用于构建UserDao的。在构建时,他除了构建UserDao对象外,他的getDataHelper方法也做了表的检查和创建工作。
代码部分
下面主要是表的创建部分
- 在MainActivity的oncreate中初始化UserDao
userDao = BaseDaoFactory.getInstance().getDataHelper(UserDao.class, User.class);
- BaseDaoFactory的getInstance方法就是获取一个单例,那么getDataHelper是做了什么呢?
public synchronized <M extends BaseDao<T>, T> M getDataHelper(Class<M> clazz, Class<T> entityClass) {
BaseDao baseDao = null;
try {
baseDao = clazz.newInstance();
baseDao.init(entityClass,sqLiteDatabase);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return (M)baseDao;
}
- 对比上面传入的参数,可以看出是利用反射创建了一个UserDao对象,并调用了他的init方法,init方法传入的参数sqliteDatabase实在factory构造的时候创建的。这里指定了创建表的路径。
private BaseDaoFactory() {
sqliteDataBasePath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/dbTest.db";
sqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(sqliteDataBasePath, null);
}
- 那么init方法做了什么呢?
/**
* 持有数据库操作类的引用
*/
private SQLiteDatabase database;
/**
* 表名
*/
private String tableName;
private HashMap<String, Field> cacheMap;
public synchronized boolean init(Class<T> clazz, SQLiteDatabase sqLiteDatabase) {
if (!isInit) {
this.entityClass = clazz;
database = sqLiteDatabase;
//获取表名,如果Bean类上加了注解,则用注解的值,如果没有,则用类名做表名。
if (entityClass.getAnnotation(DbTable.class) == null) {
tableName = entityClass.getSimpleName();
} else {
tableName = entityClass.getAnnotation(DbTable.class).value();
}
if (!database.isOpen()) {
return false;
}
String sql;
if (!TextUtils.isEmpty(sql = createTable())) {
//创建表
database.execSQL(sql);
}
cacheMap = new HashMap<>();
initHasMap();
isInit = true;
}
return isInit;
}
//将列名和对应的类的成员变量用key-value形式存起来,方便后面查询时返回对象。
private void initHasMap() {
String sql = "select * from " + this.tableName + " limit 1 , 0";
Cursor cursor = null;
try {
cursor = database.rawQuery(sql, null);
String[] columnNames = cursor.getColumnNames();
Field[] columnFields = entityClass.getFields();
for (Field field : columnFields) {
field.setAccessible(true);
}
for (String columnName : columnNames) {
Field columnField = null;
for (Field field : columnFields) {
String fieldName = field.getAnnotation(DbFlied.class).value();
if (fieldName == null) {
fieldName = field.getName();
}
if (columnName.equals(fieldName)) {
columnField = field;
break;
}
}
if (columnField != null) {
cacheMap.put(columnName, columnField);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
cursor.close();
}
}