Android ORM数据库框架之-greenDao(四)
来源:互联网 发布:新大洋知豆 编辑:程序博客网 时间:2024/09/21 06:37
本篇是greenDao的最后一篇,这一篇带大家看下greenDao的源码。
- dao的初始化过程
这一过程非常的复杂,容易绕晕,那么我就来带大家梳理一下。首先看看我们初始化dao的方法。
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this,"persons-db",null); db = helper.getWritableDatabase(); Log.e("tag","this is db version ->"+db.getVersion()); // 该数据库连接属于DaoMaster,所以多个Session指的是想用的数据库连接 daoMaster = new DaoMaster(db); daoSession =daoMaster.newSession(); return daoSession.getPersonDao();
我在这里返回的是PersionDao。首先看下helper的初始化 过程。
public DevOpenHelper(Context context, String name, CursorFactory factory) { super(context, name, factory); }
调用父类的构造方法。
public static abstract class OpenHelper extends SQLiteOpenHelper { public OpenHelper(Context context, String name, CursorFactory factory) { super(context, name, factory, SCHEMA_VERSION); } @Override public void onCreate(SQLiteDatabase db) { Log.i("greenDAO", "Creating tables for schema version " + SCHEMA_VERSION); createAllTables(db, false); } }
在父类中完成数据表的创建。
public static void createAllTables(SQLiteDatabase db, boolean ifNotExists) { PersonDao.createTable(db, ifNotExists); PeopleDao.createTable(db, ifNotExists); IdCardDao.createTable(db, ifNotExists); OrderDao.createTable(db, ifNotExists); CourseDao.createTable(db, ifNotExists); }
public static void createTable(SQLiteDatabase db, boolean ifNotExists) { String constraint = ifNotExists? "IF NOT EXISTS ": ""; db.execSQL("CREATE TABLE " + constraint + "\"PERSON\" (" + // "\"_id\" INTEGER PRIMARY KEY ," + // 0: id "\"NAME\" TEXT NOT NULL ," + // 1: name "\"AGE\" INTEGER NOT NULL ," + // 2: age "\"CARD\" TEXT);"); // 3: card }
这么一来,表的创建过程就理清楚了。接下来看DaoMaster的初始化。
public DaoMaster(SQLiteDatabase db) { super(db, SCHEMA_VERSION); registerDaoClass(PersonDao.class); registerDaoClass(PeopleDao.class); registerDaoClass(IdCardDao.class); registerDaoClass(OrderDao.class); registerDaoClass(CourseDao.class); }
显示调用父类的构造方法,接着registDaoClass()
public AbstractDaoMaster(SQLiteDatabase db, int schemaVersion) { this.db = db; this.schemaVersion = schemaVersion; daoConfigMap = new HashMap<Class<? extends AbstractDao<?, ?>>, DaoConfig>(); } protected void registerDaoClass(Class<? extends AbstractDao<?, ?>> daoClass) { DaoConfig daoConfig = new DaoConfig(db, daoClass); daoConfigMap.put(daoClass, daoConfig); }
看到,上面的一句很关键。new DaoConfig();
public DaoConfig(SQLiteDatabase db, Class<? extends AbstractDao<?, ?>> daoClass) { this.db = db; try { this.tablename = (String) daoClass.getField("TABLENAME").get(null); Property[] properties = reflectProperties(daoClass); this.properties = properties; allColumns = new String[properties.length]; List<String> pkColumnList = new ArrayList<String>(); List<String> nonPkColumnList = new ArrayList<String>(); Property lastPkProperty = null; for (int i = 0; i < properties.length; i++) { Property property = properties[i]; String name = property.columnName; allColumns[i] = name; if (property.primaryKey) { pkColumnList.add(name); lastPkProperty = property; } else { nonPkColumnList.add(name); } } String[] nonPkColumnsArray = new String[nonPkColumnList.size()]; nonPkColumns = nonPkColumnList.toArray(nonPkColumnsArray); String[] pkColumnsArray = new String[pkColumnList.size()]; pkColumns = pkColumnList.toArray(pkColumnsArray); pkProperty = pkColumns.length == 1 ? lastPkProperty : null; statements = new TableStatements(db, tablename, allColumns, pkColumns); if (pkProperty != null) { Class<?> type = pkProperty.type; keyIsNumeric = type.equals(long.class) || type.equals(Long.class) || type.equals(int.class) || type.equals(Integer.class) || type.equals(short.class) || type.equals(Short.class) || type.equals(byte.class) || type.equals(Byte.class); } else { keyIsNumeric = false; } } catch (Exception e) { throw new DaoException("Could not init DAOConfig", e); } }
这个方法就是完成DaoConfig的配置的,通过反射机制,获取到我们的Dao类,比如说PersonClass,具体的代码大家去看,就是通过反射,很好理解。注意statements是TableStatements类型的。
继续,newSession();
public DaoSession newSession() { return new DaoSession(db, IdentityScopeType.Session, daoConfigMap); }
public DaoSession(SQLiteDatabase db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig> daoConfigMap) { super(db); personDaoConfig = daoConfigMap.get(PersonDao.class).clone(); personDaoConfig.initIdentityScope(type); peopleDaoConfig = daoConfigMap.get(PeopleDao.class).clone(); peopleDaoConfig.initIdentityScope(type); idCardDaoConfig = daoConfigMap.get(IdCardDao.class).clone(); idCardDaoConfig.initIdentityScope(type); orderDaoConfig = daoConfigMap.get(OrderDao.class).clone(); orderDaoConfig.initIdentityScope(type); courseDaoConfig = daoConfigMap.get(CourseDao.class).clone(); courseDaoConfig.initIdentityScope(type); personDao = new PersonDao(personDaoConfig, this); peopleDao = new PeopleDao(peopleDaoConfig, this); idCardDao = new IdCardDao(idCardDaoConfig, this); orderDao = new OrderDao(orderDaoConfig, this); courseDao = new CourseDao(courseDaoConfig, this); registerDao(Person.class, personDao); registerDao(People.class, peopleDao); registerDao(IdCard.class, idCardDao); registerDao(Order.class, orderDao); registerDao(Course.class, courseDao); }
public void initIdentityScope(IdentityScopeType type) { if (type == IdentityScopeType.None) { identityScope = null; } else if (type == IdentityScopeType.Session) { if (keyIsNumeric) { identityScope = new IdentityScopeLong(); } else { identityScope = new IdentityScopeObject(); } } else { throw new IllegalArgumentException("Unsupported type: " + type); } }
这个函数就是判断,类型范围的。一般我们不需要管。看到在DaoSession的构造函数中,根据在DaoMaster初始化的config,经过范围类型判断,在DaoSession中也初始化了。至此,初始化过程完毕。
- CURD过程 我们以insert为例
dao.insert(person);
dao对象是我们初始化后得到的,person是一个Person实体对象。
public long insert(T entity) { return executeInsert(entity, statements.getInsertStatement()); }
上面的一段代码是AbstractDao类,这是一个抽象类,我们的Persondao就是继承的他。
statements.getInsertStatement()
通过statments对象实例获取SQLiteStatement对象,在(TableStatements类中)
public SQLiteStatement getInsertStatement() { if (insertStatement == null) { String sql = SqlUtils.createSqlInsert("INSERT INTO ", tablename, allColumns); insertStatement = db.compileStatement(sql); } return insertStatement; }
这样我们就获取到了一个SQLiteStatement对象。继续,看插入数据的过程。
private long executeInsert(T entity, SQLiteStatement stmt) { long rowId; if (db.isDbLockedByCurrentThread()) { synchronized (stmt) { bindValues(stmt, entity); rowId = stmt.executeInsert(); } } else { // Do TX to acquire a connection before locking the stmt to avoid deadlocks db.beginTransaction(); try { synchronized (stmt) { bindValues(stmt, entity); rowId = stmt.executeInsert(); } db.setTransactionSuccessful(); } finally { db.endTransaction(); } } updateKeyAfterInsertAndAttach(entity, rowId, true); return rowId; }
看到上面会判断是否在当前线程,不在的话会开启事务。总之,还是很安全的。就这么多吧,更多的源码还是大家自己看吧。真的感觉这个牛,坐等更新+上数据库更新
0 0
- Android ORM数据库框架之-greenDao(四)
- Android开发数据库之第三方ORM框架(GreenDao)
- Android ORM数据库框架之-greenDao(一)
- Android ORM数据库框架之-greenDao(二)
- Android ORM数据库框架之-greenDao(三)
- android数据库ORM框架GreenDao
- Android数据库ORM框架-greenDAO
- Android ORM 框架之 greenDAO
- Android ORM 框架之 greenDAO
- Android ORM 框架之 greenDAO
- Android ORM 框架之 greenDAO
- Android ORM 框架之 greenDAO
- Android ORM框架之GreenDAO
- Android ORM框架之greenDAO
- Android ORM 框架之 greenDAO
- Android下Sqlite数据库ORM框架之GreenDao详解
- Android下Sqlite数据库ORM框架之GreenDao详解
- Android 数据库ORM开源框架之greenDAO
- 中断与异常详解(一)
- 利用运行循环解决NSURLConnection多线程下载的问题(只需要了解)
- Supporting Multiple Screens
- • UFLDL教程练习(exercise)答案(1)
- pjsip项目概要及c语言面向对象方法实现
- Android ORM数据库框架之-greenDao(四)
- git相关操作(简单篇)
- spring web mvc 详解
- 安卓源码--添加root权限
- Ubuntu 出现 grub rescue> 修复
- 刚刚从微博转到博客,筛选一下不是随手记录的东西转过来,这是一个tableviewcontroller的发现
- [Android]自定义一个可以展开显示更多的文本布局
- C语言整理-10
- 3-5年的PHPer常见的面试题