GreenDAO系列之(1)入门
来源:互联网 发布:深圳阿里云幕布拍照 编辑:程序博客网 时间:2024/06/06 05:14
关于greenDao
简介
greenDAO 是一个开源的ORM数据库框架。它帮助开发者从日常的数据库的读写sql语句中解放出来,开发者只需要关注具体的Java对象,就能够进行数据库的访问操作。
greenDao features
1.强大的性能,可能是ORM数据库中性能最好的。官方把greenDao和OrmLite、ActiveAndroid做的性能对比,数据如下:
2. 易于使用的API
3. 低内存消耗
4. 包size比较小,如果不包含加密,大概proguard后的包size为8k。
5. 支持数据库加密: 支持SQLCipher。SQLCipher对个人开发者来说倒不错,不过对于公司来说吸引力不大。
greenDao 核心类说明
如上图所示,greenDao有几个核心类:
1. DaoMaster : db的管理类,是db的总入口,总管的角色,管理着database创建、更新以及数据库中有哪些表之类。每一个db对应一个DaoMaster。
2. DaoSession : 会话, 管理指定的schema的所有dao,另外DaoSession也支持数据缓存,可以指定dao是否使用缓存。
3. xxxDao : 某个table的操作对象
4. Entity : 通俗易懂,不解释了
greenDao工程说明
greenDao 的github包含两个公共组件 :
1. DaoCore :greenDao的核心框架,我们一般说的greenDao就是指这个
2. DaoGenerator :通俗易懂,就是xxxDao的生成器,帮助开发者生成xxxDAO对象,开发者只需要定义自己的Entity,通过DaoGenrator就能够生成对应的xxxDao对象。
新手接入
> 这里演示一个学生的例子
1.创建自己的Android Project,前戏就不贴了
2.导入greenDao
buildscript { repositories { mavenCentral() } dependencies { classpath 'org.greenrobot:greendao-gradle-plugin:3.2.1' }}apply plugin: 'org.greenrobot.greendao'dependencies { compile 'org.greenrobot:greendao:3.2.0'}
3.编写Entity
我们定义一个Student class:
@Entitypublic class Student { @Id private String mId; private String mName; private int mGender;}
@Entity和@Id是greenDao的标签,分别用来表示这是个Entity以及Entity的主键,greenDao Generator会根据这些标签自动生成DaoMaster、DaoSession、StudentDao。 具体的标签的使用方法可以查看官方文档。
4、点击Run, 最后生成的代码如下(部分加了注释):
DaoMaster.java
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT./** * Master of DAO (schema version 1): knows all DAOs. */public class DaoMaster extends AbstractDaoMaster { public static final int SCHEMA_VERSION = 1; /** Creates underlying database table using DAOs. */ public static void createAllTables(Database db, boolean ifNotExists) { StudentDao.createTable(db, ifNotExists); } /** Drops underlying database table using DAOs. */ public static void dropAllTables(Database db, boolean ifExists) { StudentDao.dropTable(db, ifExists); } /** * WARNING: Drops all table on Upgrade! Use only during development. * Convenience method using a {@link DevOpenHelper}. */ public static DaoSession newDevSession(Context context, String name) { Database db = new DevOpenHelper(context, name).getWritableDb(); DaoMaster daoMaster = new DaoMaster(db); return daoMaster.newSession(); } public DaoMaster(SQLiteDatabase db) { this(new StandardDatabase(db)); } public DaoMaster(Database db) { super(db, SCHEMA_VERSION); registerDaoClass(StudentDao.class); } public DaoSession newSession() { return new DaoSession(db, IdentityScopeType.Session, daoConfigMap); } public DaoSession newSession(IdentityScopeType type) { return new DaoSession(db, type, daoConfigMap); } /** * Calls {@link #createAllTables(Database, boolean)} in {@link #onCreate(Database)} - */ public static abstract class OpenHelper extends DatabaseOpenHelper { public OpenHelper(Context context, String name) { super(context, name, SCHEMA_VERSION); } public OpenHelper(Context context, String name, CursorFactory factory) { super(context, name, factory, SCHEMA_VERSION); } @Override public void onCreate(Database db) { Log.i("greenDAO", "Creating tables for schema version " + SCHEMA_VERSION); //创建数据库 createAllTables(db, false); } } /** WARNING: Drops all table on Upgrade! Use only during development. */ public static class DevOpenHelper extends OpenHelper { public DevOpenHelper(Context context, String name) { super(context, name); } public DevOpenHelper(Context context, String name, CursorFactory factory) { super(context, name, factory); } @Override public void onUpgrade(Database db, int oldVersion, int newVersion) { Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables"); //数据库升级。。。非常霸道,直接清除表后重建,我们实际项目中肯定不会这么使用的 dropAllTables(db, true); onCreate(db); } }}
DaoSession.java :
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT./** * {@inheritDoc} * * @see org.greenrobot.greendao.AbstractDaoSession */public class DaoSession extends AbstractDaoSession { private final DaoConfig studentDaoConfig; private final StudentDao studentDao; public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig> daoConfigMap) { super(db); studentDaoConfig = daoConfigMap.get(StudentDao.class).clone(); //设置缓存类型 studentDaoConfig.initIdentityScope(type); studentDao = new StudentDao(studentDaoConfig, this); registerDao(Student.class, studentDao); } //清除缓存 public void clear() { studentDaoConfig.clearIdentityScope(); } public StudentDao getStudentDao() { return studentDao; }}
StudentDao.java
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT./** * DAO for table "STUDENT".*/public class StudentDao extends AbstractDao<Student, String> { public static final String TABLENAME = "STUDENT"; /** * 定义Studnet表的Column */ public static class Properties { public final static Property MId = new Property(0, String.class, "mId", true, "M_ID"); public final static Property MName = new Property(1, String.class, "mName", false, "M_NAME"); public final static Property MGender = new Property(2, int.class, "mGender", false, "M_GENDER"); } public StudentDao(DaoConfig config) { super(config); } public StudentDao(DaoConfig config, DaoSession daoSession) { super(config, daoSession); } /** 创建Student表,这种创建方法有点太low了居然i无法做到自动创建 */ public static void createTable(Database db, boolean ifNotExists) { String constraint = ifNotExists? "IF NOT EXISTS ": ""; db.execSQL("CREATE TABLE " + constraint + "\"STUDENT\" (" + // "\"M_ID\" TEXT PRIMARY KEY NOT NULL ," + // 0: mId "\"M_NAME\" TEXT," + // 1: mName "\"M_GENDER\" INTEGER NOT NULL );"); // 2: mGender } /** Drops the underlying database table. */ public static void dropTable(Database db, boolean ifExists) { String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\"STUDENT\""; db.execSQL(sql); } /** * 插入语句时绑定的数据,这种写法有点坑,万一MId为空时,生成的语句就有w */ @Override protected final void bindValues(DatabaseStatement stmt, Student entity) { stmt.clearBindings(); String mId = entity.getMId(); if (mId != null) { stmt.bindString(1, mId); } String mName = entity.getMName(); if (mName != null) { stmt.bindString(2, mName); } stmt.bindLong(3, entity.getMGender()); } @Override protected final void bindValues(SQLiteStatement stmt, Student entity) { stmt.clearBindings(); String mId = entity.getMId(); if (mId != null) { stmt.bindString(1, mId); } String mName = entity.getMName(); if (mName != null) { stmt.bindString(2, mName); } stmt.bindLong(3, entity.getMGender()); } @Override public String readKey(Cursor cursor, int offset) { return cursor.isNull(offset + 0) ? null : cursor.getString(offset + 0); } /** * 从sql读取数据,生成student对象 */ @Override public Student readEntity(Cursor cursor, int offset) { Student entity = new Student( // cursor.isNull(offset + 0) ? null : cursor.getString(offset + 0), // mId cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1), // mName cursor.getInt(offset + 2) // mGender ); return entity; } @Override public void readEntity(Cursor cursor, Student entity, int offset) { entity.setMId(cursor.isNull(offset + 0) ? null : cursor.getString(offset + 0)); entity.setMName(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1)); entity.setMGender(cursor.getInt(offset + 2)); } @Override protected final String updateKeyAfterInsert(Student entity, long rowId) { return entity.getMId(); } @Override public String getKey(Student entity) { if(entity != null) { return entity.getMId(); } else { return null; } } @Override public boolean hasKey(Student entity) { return entity.getMId() != null; } @Override protected final boolean isEntityUpdateable() { return true; }}
5.使用
- 初始化数据库
DevOpenHelper helper = new DevOpenHelper(this, "students");Database db = helper.getWritableDb();mDaoSession = new DaoMaster(db).newSession();mStudentDao = mDaoSession.getStudentDao();
- 添加
Student student = new Student();student.setMId(String.valueOf(System.currentTimeMillis()));student.setMName("name"+System.currentTimeMillis());student.setMGender((int) (System.currentTimeMillis()%2));mStudentDao.insert(student);
- 删除
final Student deleteStudent = mStudentDao.queryBuilder().orderDesc(StudentDao.Properties.MId).limit(1).unique();mStudentDao.delete(deleteStudent);
小结
从上面的demo,可以看到访问数据库的过程变得非常的简单。开发者只需要定义自己的entity,greenDao Generator就能自动生成对应的类文件。整个使用过程非常简单,但是,一般说到但是,就是来讲它的坏话了。。。我们也看到greenDao有如下几个问题:
greenDao Generator仍然有点笨,生成的代码真心是笨(如:要是我们的变量是以m开头,则会生成 getM,setM方法。),还需要我们进一步加工,才能变成比较美观的代码。
greenDao的DaoMaster在数据库的创建以及更新上都使用了指定sql语句的方法,比较笨拙,虽然网上有一个叫做MigrationHelper的解决方案,但仍不够友好。后续再给大家介绍一下我们使用的方法。
xxxDao的Property支持的属性有限
如:Property.java
public final int ordinal;public final java.lang.Class<?> type;public final java.lang.String name;public final boolean primaryKey;public final java.lang.String columnName;
不支持default、is null、unique 等属性
Reference: https://github.com/greenrobot/greenDAO
- GreenDAO系列之(1)入门
- greenDAO系列1--概要
- GreenDao系列之(2)设计及机制介绍
- Android ORM系列之GreenDao最佳实践
- GreenDao入门
- GreenDao笔记(1)—Hello GreenDao
- Android之GreenDao问题(1)
- GreenDao官方文档翻译之(一)开始使用GreenDao
- GreenDao详解(二)之在项目中配置GreenDao
- Android ORM系列之GreenDao关联关系映射
- Android ORM系列之GreenDao关联关系映射
- 拆轮子系列之理解GreenDao框架源码
- 【Android】ORM数据库框架之GreenDao快速入门与使用
- greenDAO系列5--查询
- greenDAO系列6--会话
- greenDAO系列7--关系
- 精通数据库系列之入门-基础篇(1)
- Android greenDAO入门
- 分段线性变换与直方图均衡化
- mysql入门(一)
- python pandas 对series和dataframe的重置索引reindex
- hadoop磁盘写入流程
- Mysql利用存储过程获取结果集
- GreenDAO系列之(1)入门
- BZOJ 3230 后缀数组+ST
- eclipse 安装 SpringSource Tool Suite(STS)插件
- 利用tomcat发布WEB项目到内网和外网的方法
- 分页综合应用(分页下拉、当前页、上一页、下一页)
- Prim算法另一种形式
- IO流_复制图片的4种方式案例
- python3.5安装Twisted
- 【CodeForces734E】【缩点】Anton and Tree 题解