• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

《Andorid开源》greenDao 数据库orm框架

武飞扬头像
lmr廖
帮助1

  一

前言:以前没用框架写Andorid的Sqlite的时候就是用SQLiteDatabase ,SQLiteOpenHelper ,SQL语句等一些东西,特别在写SQL语句来进行

数据库操作的时候是一件很繁琐的事情,有时候没有错误提示的,很难找到错误的地方,即费力又花时间。

                现在使用greenDao就可以避免那些繁琐的SQL文了,极大的简化了对Sqlite的操作。

    greenDao官方网址是:http://greendao-orm.com/

    greenDao官方demo下载地址:GitHub - greenrobot/greenDAO: greenDAO is a light & fast ORM solution for Android that maps objects to SQLite databases.

官方Demo里共有六个工程目录,分别为:

(1).DaoCore:库目录,即jar文件greendao-1.3.0-beta-1.jar的代码;

(2).DaoExample:android范例工程;

(3).DaoExampleGenerator:DaoExample工程的DAO类构造器,java工程;

(4).DaoGenerator:DAO类构造器,java工程;

(5).DaoTest、PerformanceTestOrmLite:其他测试相关的工程

 二

    对greendDao进行一个简单的介绍:

         greenDao是一个用于帮助Android开发者操作SQLite的一个开源项目,SQLite是一个极其重要的嵌入关系型数据库,然而开发这个需要完成一些比较传统的工作,写sql和解析查询结果是一件很繁琐的任务。

greenDao将会为你工作:他讲java的Object和数据库的表进行了映射(常被称为ORM),这个方法可以让你用一些简单的面向对象API来完成存储,更新,删除和查询等,节约时间让你专注于实际比较重要的问题上

    greenDao主要的设计目的:

  • 最高性能(可能是最快的ORM为Andorid)
  • 简单易用的APIs
  • 高度优化Andorid
  • 最小的内存占用
  • 小的librry size,可以专注于实际问题

学新通

官方demo的介绍:

(一) DAO类构造(实体 数据库的一些初始化的操作代码)

首先要新建一个java工程( 这个工程就是以后用来生成数据库表和对应实体的工程了)来生成DAO类文件,这个工程需要导入greendao-generator-1.3.1和freemarker-2.3.22这两个jar包要下对,版本号不一定是要

我这个的。

  1.  
    01.package de.greenrobot.daogenerator.gentest;
  2.  
    02.import de.greenrobot.daogenerator.DaoGenerator;
  3.  
    03.import de.greenrobot.daogenerator.Entity;
  4.  
    04.import de.greenrobot.daogenerator.Property;
  5.  
    05.import de.greenrobot.daogenerator.Schema;
  6.  
    06.import de.greenrobot.daogenerator.ToMany;
  7.  
    07./**
  8.  
    08.* Generates entities and DAOs for the example project DaoExample.
  9.  
    09.*
  10.  
    10.* Run it as a Java application (not Android).
  11.  
    11.*
  12.  
    12.* @author Markus
  13.  
    13.*/
  14.  
    14.public class ExampleDaoGenerator
  15.  
    15.{
  16.  
    16.
  17.  
    17.public static void main(String[] args) throws Exception
  18.  
    18.{
  19.  
    19.Schema schema = new Schema(3, "de.greenrobot.daoexample");
  20.  
    20.
  21.  
    21.addNote(schema);
  22.  
    22.addCustomerOrder(schema);
  23.  
    23.
  24.  
    24.new DaoGenerator().generateAll(schema, "../DaoExample/src-gen");
  25.  
    25.}
  26.  
    26.
  27.  
    27.private static void addNote(Schema schema)
  28.  
    28.{
  29.  
    29.Entity note = schema.addEntity("Note");
  30.  
    30.note.addIdProperty();
  31.  
    31.note.addStringProperty("text").notNull();
  32.  
    32.note.addStringProperty("comment");
  33.  
    33.note.addDateProperty("date");
  34.  
    34.}
  35.  
    35.
  36.  
    36.private static void addCustomerOrder(Schema schema)
  37.  
    37.{
  38.  
    38.Entity customer = schema.addEntity("Customer");
  39.  
    39.customer.addIdProperty();
  40.  
    40.customer.addStringProperty("name").notNull();
  41.  
    41.
  42.  
    42.Entity order = schema.addEntity("Order");
  43.  
    43.order.setTableName("ORDERS");
  44.  
    44.order.addIdProperty();
  45.  
    45.Property orderDate = order.addDateProperty("date").getProperty();
  46.  
    46.Property customerId = order.addLongProperty("customerId").notNull().getProperty();
  47.  
    47.order.addToOne(customer, customerId);
  48.  
    48.
  49.  
    49.ToMany customerToOrders = customer.addToMany(order, customerId);
  50.  
    50.customerToOrders.setName("orders");
  51.  
    51.customerToOrders.orderAsc(orderDate);
  52.  
    52.}
  53.  
    53.
  54.  
    54.}
学新通

对上面的代码做一些解释:

Schema schema = new Schema(3"de.greenrobot.daoexample");   3 ---- 自己写的数据库版本号     de.greenrobot.daoexample --- 包的所在地址  这些都可以不改的

  addNote(schema) 方法执行后 就在 Android工程DaoExample中的src-gen文件中创建了一个Note实体,其中属性有text , comment , date 和NoteDao 其实就是对数据库的一些操作的

  addCustomerOrder(schema)作用和addNote(schema)类似,只不过是多了表之间的关系(一对一 和 一对多)

方法(建表 ,查询等)和sql文都在这里面。

  1.  
    new DaoGenerator().generateAll(schema, "../DaoExample/src-gen"); 指定生成的路径
  2.  
    其中src-gen这个目录名需要在运行前手动创建,否则会报错。
  3.  
    运行后出现以下的提示说明DAO文件自动生成成功了,刷新一下DaoExample项目即可看到
  4.  
    运行后可以看到,DaoExample项目src-gen下面自动生成了8个文件,3个实体对象,3个dao,1个DaoMaster,1个DaoSession.

  DaoExample基于greenDao的android工程,他需要导入greendao-1.3.0-beta-1.jar

以后想在创建表和实体,就可以直接在这个工程里面添加方法就行了,以前的方法不能修改***

Note就是一个实体,代码就不贴出来了

看看NoteDao的代码:

  1.  
    public class NoteDao extends AbstractDao<Note, Long> {
  2.  
     
  3.  
    public static final String TABLENAME = "NOTE";
  4.  
     
  5.  
    public static class Properties {
  6.  
     
  7.  
    public final static Property Id = new Property(0, Long.class, "id", true, "_id");
  8.  
     
  9.  
    public final static Property Text = new Property(1, String.class, "text", false, "TEXT");
  10.  
     
  11.  
    public final static Property Comment = new Property(2, String.class, "comment", false, "COMMENT");
  12.  
     
  13.  
    public final static Property Date = new Property(3, java.util.Date.class, "date", false, "DATE");
  14.  
     
  15.  
    };
  16.  
     
  17.  
    public NoteDao(DaoConfig config) {
  18.  
     
  19.  
    super(config);
  20.  
     
  21.  
    }
  22.  
     
  23.  
    public NoteDao(DaoConfig config, DaoSession daoSession) {
  24.  
     
  25.  
    super(config, daoSession);
  26.  
     
  27.  
    }
  28.  
     
  29.  
    /** Creates the underlying database table. */
  30.  
     
  31.  
    public static void createTable(SQLiteDatabase db, boolean ifNotExists) {
  32.  
     
  33.  
    String constraint = ifNotExists? "IF NOT EXISTS ": "";
  34.  
     
  35.  
    db.execSQL("CREATE TABLE " constraint "'NOTE' (" //
  36.  
     
  37.  
    "'_id' INTEGER PRIMARY KEY ," // 0: id
  38.  
     
  39.  
    "'TEXT' TEXT NOT NULL ," // 1: text
  40.  
     
  41.  
    "'COMMENT' TEXT," // 2: comment
  42.  
     
  43.  
    "'DATE' INTEGER);"); // 3: date
  44.  
     
  45.  
    }
  46.  
     
  47.  
    /** Drops the underlying database table. */
  48.  
     
  49.  
    public static void dropTable(SQLiteDatabase db, boolean ifExists) {
  50.  
     
  51.  
    String sql = "DROP TABLE " (ifExists ? "IF EXISTS " : "") "'NOTE'";
  52.  
     
  53.  
    db.execSQL(sql);
  54.  
     
  55.  
    }
  56.  
     
  57.  
    /** @inheritdoc */
  58.  
     
  59.  
    @Override
  60.  
     
  61.  
    protected void bindValues(SQLiteStatement stmt, Note entity) {
  62.  
     
  63.  
    stmt.clearBindings();
  64.  
     
  65.  
    Long id = entity.getId();
  66.  
     
  67.  
    if (id != null) {
  68.  
     
  69.  
    stmt.bindLong(1, id);
  70.  
     
  71.  
    }
  72.  
     
  73.  
    stmt.bindString(2, entity.getText());
  74.  
     
  75.  
    String comment = entity.getComment();
  76.  
     
  77.  
    if (comment != null) {
  78.  
     
  79.  
    stmt.bindString(3, comment);
  80.  
     
  81.  
    }
  82.  
     
  83.  
    java.util.Date date = entity.getDate();
  84.  
     
  85.  
    if (date != null) {
  86.  
     
  87.  
    stmt.bindLong(4, date.getTime());
  88.  
     
  89.  
    }
  90.  
     
  91.  
    }
  92.  
     
  93.  
    /** @inheritdoc */
  94.  
     
  95.  
    @Override
  96.  
     
  97.  
    public Long readKey(Cursor cursor, int offset) {
  98.  
     
  99.  
    return cursor.isNull(offset 0) ? null : cursor.getLong(offset 0);
  100.  
     
  101.  
    }
  102.  
     
  103.  
    /** @inheritdoc */
  104.  
     
  105.  
    @Override
  106.  
     
  107.  
    public Note readEntity(Cursor cursor, int offset) {
  108.  
     
  109.  
    Note entity = new Note( //
  110.  
     
  111.  
    cursor.isNull(offset 0) ? null : cursor.getLong(offset 0), // id
  112.  
     
  113.  
    cursor.getString(offset 1), // text
  114.  
     
  115.  
    cursor.isNull(offset 2) ? null : cursor.getString(offset 2), // comment
  116.  
     
  117.  
    cursor.isNull(offset 3) ? null : new java.util.Date(cursor.getLong(offset 3)) // date
  118.  
     
  119.  
    );
  120.  
     
  121.  
    return entity;
  122.  
     
  123.  
    }
  124.  
     
  125.  
    /** @inheritdoc */
  126.  
     
  127.  
    @Override
  128.  
     
  129.  
    public void readEntity(Cursor cursor, Note entity, int offset) {
  130.  
     
  131.  
    entity.setId(cursor.isNull(offset 0) ? null : cursor.getLong(offset 0));
  132.  
     
  133.  
    entity.setText(cursor.getString(offset 1));
  134.  
     
  135.  
    entity.setComment(cursor.isNull(offset 2) ? null : cursor.getString(offset 2));
  136.  
     
  137.  
    entity.setDate(cursor.isNull(offset 3) ? null : new java.util.Date(cursor.getLong(offset 3)));
  138.  
     
  139.  
    }
  140.  
     
  141.  
    /** @inheritdoc */
  142.  
     
  143.  
    @Override
  144.  
     
  145.  
    protected Long updateKeyAfterInsert(Note entity, long rowId) {
  146.  
     
  147.  
    entity.setId(rowId);
  148.  
     
  149.  
    return rowId;
  150.  
     
  151.  
    }
  152.  
     
  153.  
    /** @inheritdoc */
  154.  
     
  155.  
    @Override
  156.  
     
  157.  
    public Long getKey(Note entity) {
  158.  
     
  159.  
    if(entity != null) {
  160.  
     
  161.  
    return entity.getId();
  162.  
     
  163.  
    } else {
  164.  
     
  165.  
    return null;
  166.  
     
  167.  
    }
  168.  
     
  169.  
    }
  170.  
     
  171.  
    /** @inheritdoc */
  172.  
     
  173.  
    @Override
  174.  
     
  175.  
    protected boolean isEntityUpdateable() {
  176.  
     
  177.  
    return true;
  178.  
     
  179.  
    }
  180.  
     
  181.  
    }
学新通

从代码中可以看到,就和以前直接操作sqlite是想类似的。

一些常用方法进行介绍( 摘至网络):

1.创建一个实体类

 Entity note = schema.addEntity("Note");

默认表名就是类名,也可以自定义表名

 dao.setTableName("NoteList");

greenDAO会自动根据实体类属性创建表字段,并赋予默认值。例如在数据库方面的表名和列名都来源于实体类名和属性名。默认的数据库名称是大写 使用下划线分隔单词,而不是在Java中使用的驼峰式大小写风格。例如,一个名为“CREATIONDATE”属性将成为一个数据库列 “CREATION_DATE”。

设置一个自增长ID列为主键:

dao.addIdProperty().primaryKey().autoincrement();

设置其他各种类型的属性:

  1.  
    dao.addIntProperty("cityId");
  2.  
    dao.addStringProperty("infoType").notNull();//null字段
  3.  
    dao.addDoubleProperty("Id");

在生成的实体类中,int类型为自动转为long类型。

如果在编译过程中出现以下错误,那么有可能是主键的类型错误所致:

1.java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

在使用greenDAO时,一个实体类只能对应一个表,目前没法做到一个表对应多个实体类,或者多个表共用一种对象类型。后续的升级也不会针对这一点进行扩展。

(二)表的增删改查

增删改查相当方便,完全的面向对象,不需要涉及到任何的sql语言。

1.查询

范例1:查询某个表是否包含某个id:

  1.  
    public boolean isSaved(int ID)
  2.  
    {
  3.  
    QueryBuilder<SaveList> qb = saveListDao.queryBuilder();
  4.  
    qb.where(Properties.Id.eq(ID));
  5.  
    qb.buildCount().count();
  6.  
    return qb.buildCount().count() > 0 ? true : false;
  7.  
    }

范例2:获取整个表的数据集合,一句代码就搞定!

  1.  
    public List<PhotoGalleryDB> getPhotoGallery()
  2.  
    {
  3.  
    return photoGalleryDao.loadAll();// 获取图片相册
  4.  
    }

范例3:通过一个字段值查找对应的另一个字段值(为简便直接使用下面方法,也许有更简单的方法,尚未尝试)

01.

  1.  
    /** 通过图片id查找其目录id */
  2.  
    public int getTypeId(int picId)
  3.  
    {
  4.  
    QueryBuilder<PhotoGalleryDB> qb = photoGalleryDao.queryBuilder();
  5.  
    qb.where(Properties.Id.eq(picId));
  6.  
    if (qb.list().size() > 0)
  7.  
    {
  8.  
    return qb.list().get(0).getTypeId();
  9.  
    }
  10.  
    else
  11.  
    {
  12.  
    return -1;
  13.  
    }
  14.  
    }

范例4:查找所有第一姓名是“Joe”并且以lastname排序。

  1.  
    List joes = userDao.queryBuilder()
  2.  
    where(Properties.FirstName.eq("Joe"))
  3.  
    orderAsc(Properties.LastName)
  4.  
    list();

范例5:多重条件查询

(1)获取id为cityId并且infotype为HBContant.CITYINFO_SL的数据集合:                

  1.  
    public List<CityInfoDB> getSupportingList(int cityId)
  2.  
    {
  3.  
    QueryBuilder<CityInfoDB> qb = cityInfoDao.queryBuilder();
  4.  
    qb.where(qb.and(Properties.CityId.eq(cityId),Properties.InfoType.eq(HBContant.CITYINFO_SL)));
  5.  
    qb.orderAsc(Properties.Id);// 排序依据
  6.  
    return qb.list();
  7.  
    }

(2)获取firstname为“Joe”并且出生于1970年10月以后的所有user集合:

  1.  
    QueryBuilder qb = userDao.queryBuilder();
  2.  
    qb.where(Properties.FirstName.eq("Joe"),
  3.  
    qb.or(Properties.YearOfBirth.gt(1970),
  4.  
    qb.and(Properties.YearOfBirth.eq(1970), Properties.MonthOfBirth.ge(10))));
  5.  
    List youngJoes = qb.list();

范例6:获取某列对象

 picJsonDao.loadByRowId(picId);

2.增添/插入、修改

插入数据更加简单,也是只要一句代码便能搞定!

  1.  
    public void addToPhotoTable(Photo p)
  2.  
    {
  3.  
    photoDao.insert(p);
  4.  
    }

插入时需要new一个新的对象,范例如下:

  1.  
    DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "notes-db", null);
  2.  
    db = helper.getWritableDatabase();
  3.  
    daoMaster = new DaoMaster(db);
  4.  
    daoSession = daoMaster.newSession();
  5.  
    noteDao = daoSession.getNoteDao();
  6.  
    Note note = new Note(null, noteText, comment, new Date());
  7.  
    noteDao.insert(note);

修改更新:

1.photoDao.insertOrReplace(photo);

2.photoDao.insertInTx(photo);

这里可定有疑问的:例如update table SET age =20 WHERE name = "张三" 这样一个语句在greenDao中怎么执行的,

始终记住一句话,greenDao 对对象的增,删,改,查 就是对数据库的增,删,改,查

  1.  
    String updateName = content.getText().toString().trim();
  2.  
    QueryBuilder qb2 = studentDao.queryBuilder();
  3.  
    qb2.where(Properties.Name.eq("张三"));
  4.  
    List<Student> update = qb2.list();
  5.  
    String newName = content.getText().toString().trim();
  6.  
    for (Student student222 : update) {
  7.  
    student222.setAge(20);
  8.  
    studentDao.insertOrReplaceInTx(student222);
  9.  
    }

被查询出的对象被修改后,在替换原来自己的对象就可以了

3.删除:

(1)清空表格数据

  1.  
    /** 清空相册图片列表的数据 */
  2.  
    public void clearPhoto()
  3.  
    {
  4.  
    photoDao.deleteAll();
  5.  
    }

(2)删除某个对象

  1.  
    public void deleteCityInfo(int cityId)
  2.  
    {
  3.  
    QueryBuilder<DBCityInfo> qb = cityInfoDao.queryBuilder();
  4.  
    DeleteQuery<DBCityInfo> bd = qb.where(Properties.CityId.eq(cityId)).buildDelete();
  5.  
    bd.executeDeleteWithoutDetachingEntities();
  6.  
    }

参考:https://github.com/greenrobot/greenDAO/issues/34

   http://my.oschina.net/cheneywangc/blog/196354

由上可见,使用greenDAO进行数据库的增删改查时及其方便,而且性能极佳。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfhfkac
系列文章
更多 icon
同类精品
更多 icon
继续加载