zoukankan      html  css  js  c++  java
  • 《Andorid开源》greenDao 数据库orm框架

       一

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

    数据库操作的时候是一件很繁琐的事情,有时候没有错误提示的,很难找到错误的地方,即费力又花时间。
                    现在使用greenDao就可以避免那些繁琐的SQL文了,极大的简化了对Sqlite的操作。
        greenDao官方网址是:http://greendao-orm.com/
        greenDao官方demo下载地址:https://github.com/greenrobot/greenDAO

        官方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.1freemarker-2.3.22这两个jar包要下对,版本号不一定是要

    我这个的。

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

      new DaoGenerator().generateAll(schema, "../DaoExample/src-gen"); 指定生成的路径
      其中src-gen这个目录名需要在运行前手动创建,否则会报错。
      运行后出现以下的提示说明DAO文件自动生成成功了,刷新一下DaoExample项目即可看到
      运行后可以看到,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  
     18 
     19     public NoteDao(DaoConfig config) {
     20 
     21         super(config);
     22 
     23     }
     24 
     25    
     26 
     27     public NoteDao(DaoConfig config, DaoSession daoSession) {
     28 
     29         super(config, daoSession);
     30 
     31     }
     32 
     33     /** Creates the underlying database table. */
     34 
     35     public static void createTable(SQLiteDatabase db, boolean ifNotExists) {
     36 
     37         String constraint = ifNotExists? "IF NOT EXISTS ": "";
     38 
     39         db.execSQL("CREATE TABLE " + constraint + "'NOTE' (" + //
     40 
     41                 "'_id' INTEGER PRIMARY KEY ," + // 0: id
     42 
     43                 "'TEXT' TEXT NOT NULL ," + // 1: text
     44 
     45                 "'COMMENT' TEXT," + // 2: comment
     46 
     47                 "'DATE' INTEGER);"); // 3: date
     48 
     49     }
     50 
     51     /** Drops the underlying database table. */
     52 
     53     public static void dropTable(SQLiteDatabase db, boolean ifExists) {
     54 
     55         String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "'NOTE'";
     56 
     57         db.execSQL(sql);
     58 
     59     }
     60 
     61     /** @inheritdoc */
     62 
     63     @Override
     64 
     65     protected void bindValues(SQLiteStatement stmt, Note entity) {
     66 
     67         stmt.clearBindings();
     68 
     69  
     70 
     71         Long id = entity.getId();
     72 
     73         if (id != null) {
     74 
     75             stmt.bindLong(1, id);
     76 
     77         }
     78 
     79         stmt.bindString(2, entity.getText());
     80 
     81  
     82 
     83         String comment = entity.getComment();
     84 
     85         if (comment != null) {
     86 
     87             stmt.bindString(3, comment);
     88 
     89         }
     90 
     91  
     92 
     93         java.util.Date date = entity.getDate();
     94 
     95         if (date != null) {
     96 
     97             stmt.bindLong(4, date.getTime());
     98 
     99         }
    100 
    101     }
    102 
    103     /** @inheritdoc */
    104 
    105     @Override
    106 
    107     public Long readKey(Cursor cursor, int offset) {
    108 
    109         return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);
    110 
    111     }    
    112 
    113     /** @inheritdoc */
    114 
    115     @Override
    116 
    117     public Note readEntity(Cursor cursor, int offset) {
    118 
    119         Note entity = new Note( //
    120 
    121             cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id
    122 
    123             cursor.getString(offset + 1), // text
    124 
    125             cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2), // comment
    126 
    127             cursor.isNull(offset + 3) ? null : new java.util.Date(cursor.getLong(offset + 3)) // date
    128 
    129         );
    130 
    131         return entity;
    132 
    133     }
    134 
    135      
    136 
    137     /** @inheritdoc */
    138 
    139     @Override
    140 
    141     public void readEntity(Cursor cursor, Note entity, int offset) {
    142 
    143         entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));
    144 
    145         entity.setText(cursor.getString(offset + 1));
    146 
    147         entity.setComment(cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2));
    148 
    149         entity.setDate(cursor.isNull(offset + 3) ? null : new java.util.Date(cursor.getLong(offset + 3)));
    150 
    151 }
    152    
    153 
    154     /** @inheritdoc */
    155 
    156     @Override
    157 
    158     protected Long updateKeyAfterInsert(Note entity, long rowId) {
    159 
    160         entity.setId(rowId);
    161 
    162         return rowId;
    163 
    164     }
    165 
    166     /** @inheritdoc */
    167 
    168     @Override
    169 
    170     public Long getKey(Note entity) {
    171 
    172         if(entity != null) {
    173 
    174             return entity.getId();
    175 
    176         } else {
    177 
    178             return null;
    179 
    180         }
    181 
    182     }
    183 
    184     /** @inheritdoc */
    185 
    186     @Override    
    187 
    188     protected boolean isEntityUpdateable() {
    189 
    190         return true;
    191 
    192     }
    193 
    194 }

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

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

    1.创建一个实体类

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

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

    1 dao.setTableName("NoteList");

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

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

    1 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:获取某列对象

    1 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进行数据库的增删改查时及其方便,而且性能极佳。

  • 相关阅读:
    Postman几种常用方式
    PL/SQL 循环结构
    【oracle】解锁oracle用户,unlock
    四则运算题2
    有关Botton的用法(一)
    SQLiteOpenHelper的使用
    用Toast来增加调试效率的小技巧
    汇编语言-比较字符串
    正向代理和反向代理
    redis安装与配置
  • 原文地址:https://www.cnblogs.com/liangstudyhome/p/4345761.html
Copyright © 2011-2022 走看看