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

news2024/9/23 11:46:13

  一

前言:以前没用框架写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包要下对,版本号不一定是要

我这个的。

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的代码:

 public class NoteDao extends AbstractDao<Note, Long> {
 
     public static final String TABLENAME = "NOTE";
 
     public static class Properties {
 
         public final static Property Id = new Property(0, Long.class, "id", true, "_id");
 
         public final static Property Text = new Property(1, String.class, "text", false, "TEXT");
 
         public final static Property Comment = new Property(2, String.class, "comment", false, "COMMENT");
 
         public final static Property Date = new Property(3, java.util.Date.class, "date", false, "DATE");
 
     };
 
     public NoteDao(DaoConfig config) {
 
         super(config);
 
     }
 
     public NoteDao(DaoConfig config, DaoSession daoSession) {
 
         super(config, daoSession);
 
     }
 
     /** Creates the underlying database table. */
 
     public static void createTable(SQLiteDatabase db, boolean ifNotExists) {
 
         String constraint = ifNotExists? "IF NOT EXISTS ": "";
 
         db.execSQL("CREATE TABLE " + constraint + "'NOTE' (" + //
 
                 "'_id' INTEGER PRIMARY KEY ," + // 0: id
 
                 "'TEXT' TEXT NOT NULL ," + // 1: text
 
                 "'COMMENT' TEXT," + // 2: comment
 
                 "'DATE' INTEGER);"); // 3: date
 
     }
 
     /** Drops the underlying database table. */
 
     public static void dropTable(SQLiteDatabase db, boolean ifExists) {
 
         String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "'NOTE'";
 
         db.execSQL(sql);
 
     }
 
     /** @inheritdoc */
 
     @Override
 
     protected void bindValues(SQLiteStatement stmt, Note entity) {
 
         stmt.clearBindings();
 
         Long id = entity.getId();
 
         if (id != null) {
 
             stmt.bindLong(1, id);
 
         }
 
         stmt.bindString(2, entity.getText());
 
         String comment = entity.getComment();
 
         if (comment != null) {
 
             stmt.bindString(3, comment);
 
         }
 
         java.util.Date date = entity.getDate();
 
         if (date != null) {
 
             stmt.bindLong(4, date.getTime());
 
         }
 
     }
 
     /** @inheritdoc */
 
     @Override
 
     public Long readKey(Cursor cursor, int offset) {
 
         return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);
 
     }    
 
     /** @inheritdoc */
 
     @Override
 
     public Note readEntity(Cursor cursor, int offset) {
 
         Note entity = new Note( //
 
             cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id
 
             cursor.getString(offset + 1), // text
 
             cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2), // comment
 
             cursor.isNull(offset + 3) ? null : new java.util.Date(cursor.getLong(offset + 3)) // date
 
         );
 
         return entity;
 
     }
 
     /** @inheritdoc */
 
     @Override
 
     public void readEntity(Cursor cursor, Note entity, int offset) {
 
         entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));
 
         entity.setText(cursor.getString(offset + 1));
 
         entity.setComment(cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2));
 
         entity.setDate(cursor.isNull(offset + 3) ? null : new java.util.Date(cursor.getLong(offset + 3)));
 
 }
 
     /** @inheritdoc */
 
     @Override
 
     protected Long updateKeyAfterInsert(Note entity, long rowId) {
 
         entity.setId(rowId);
 
         return rowId;
 
     }
 
     /** @inheritdoc */
 
     @Override
 
     public Long getKey(Note entity) {
 
         if(entity != null) {
 
             return entity.getId();
 
         } else {
 
             return null;
 
         }
 
     }
 
     /** @inheritdoc */
 
     @Override    
 
     protected boolean isEntityUpdateable() {
 
         return true;
 
     }
 
 }

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

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

1.创建一个实体类

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

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

 dao.setTableName("NoteList");

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

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

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

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

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

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

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

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

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

(二)表的增删改查

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

1.查询

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

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

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

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

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

01.

/** 通过图片id查找其目录id */
 public int getTypeId(int picId)
 {
 QueryBuilder<PhotoGalleryDB> qb = photoGalleryDao.queryBuilder();
 qb.where(Properties.Id.eq(picId));
 if (qb.list().size() > 0)
 {
 return qb.list().get(0).getTypeId();
 }
 else
 {
 return -1;
 }
 }

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

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

范例5:多重条件查询

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

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

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

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

范例6:获取某列对象

 picJsonDao.loadByRowId(picId);

2.增添/插入、修改

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

 public void addToPhotoTable(Photo p)
 {
 photoDao.insert(p);
 }

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

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

修改更新:

1.photoDao.insertOrReplace(photo);

2.photoDao.insertInTx(photo);

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

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

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

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

3.删除:

(1)清空表格数据

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

(2)删除某个对象

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

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/505768.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#--使用Quartz实现定时任务

C#小技巧–使用Quartz实现定时任务 Quartz.net 简介 Quartz.NET是一个开源的作业调度框架&#xff0c;非常适合在平时的工作中&#xff0c;定时轮询数据库同步&#xff0c;定时邮件通知&#xff0c;定时处理数据等。 Quartz.NET允许开发人员根据时间间隔&#xff08;或天&…

js - 原型和原型链的简单理解

前言 有一个概念需要清楚&#xff0c;只有构造函数才有.prototype对象&#xff0c;对象是没有这个属性的&#xff0c;__proto__只是浏览器提供的非标准化的访问对象的构造函数的原型对象的一种方式; prototype(原型对象) 函数即对象&#xff0c;每个函数都有一个prototype属…

代码随想录 数组篇 螺旋矩阵II Java实现

文章目录 &#xff08;中等&#xff09;59. 螺旋矩阵II&#xff08;中等&#xff09;54. 螺旋矩阵&#xff08;简单&#xff09;JZ29 顺时针打印矩阵 &#xff08;中等&#xff09;59. 螺旋矩阵II 因为我是先做的JZ29&#xff0c;所以看到这题的时候&#xff0c;几乎就是一样的…

最适合家用的洗地机哪个牌子好?2023洗地机推荐

洗地机是目前众多清洁工具中的热门之选&#xff0c;我身边很多朋友都选择了洗地机来处理家居清洁&#xff0c;一说一&#xff0c;洗地机可以处理干湿垃圾&#xff0c;还都有一键自清洁功能&#xff0c;用起来确实方便简单。不过&#xff0c;市面上的洗地机参差不齐&#xff0c;…

RabbitMQ 详解

文章目录 RabbitMQ 详解一、MQ 简介1. MQ优缺点2. MQ应用场景3. AMQP 和 JMS4. 常见的 MQ 产品 二、RabbitMQ 工作原理三、Linux环境安装RabbitMQ1. 安装 Erlang2. 安装 RabbitMQ3. 管控台 四、RabbitMQ 工作模式1. 简单模式(Hello World)2. 工作队列模式(Work Queue)3. 发布订…

PMP项目管理-[第十三章]相关方管理

相关方管理知识体系&#xff1a; 识别相关方&#xff1a; 规划相关方参与&#xff1a; 管理相关方参与&#xff1a; 监督相关方参与 &#xff1a; 13.1 识别相关方 定义&#xff1a;定期识别项目相关方&#xff0c;分析和记录他们的利益、参与度、相互依赖性、影响力和对项目成…

rk3568 修改开机logo

rk3568 修改开机显示logo Android 显示 logo 的作用是为了标识应用程序或设备的品牌和身份。在应用程序中&#xff0c;logo 可以帮助用户快速识别应用程序&#xff0c;并与其他应用程序区分开来。在设备中&#xff0c;logo 可以帮助用户识别设备的品牌和型号&#xff0c;以及与…

抽象轻松js

全新声明类型2.0版本 var、let、const 三者的区别 用我的世界来区别三者关系 特别的本质关系是一样&#xff0c;都是有木头&#xff08;声明&#xff09;钻石&#xff08;赋值&#xff09;组成 木头&#xff08;声明&#xff09;钻石&#xff08;赋值&#xff09; 钻石剑(…

鸿蒙Hi3861学习六-Huawei LiteOS-M(软件定时器)

一、简介 软件定时器&#xff0c;是基于系统Tick时钟中断且由软件来模拟的定时器。当经过设定的Tick时钟计数值后&#xff0c;会触发用户定义的回调函数。定时精度与系统Tick时钟周期有关。 硬件定时器受硬件的限制&#xff0c;数量上不足以满足用户的实际需求。因此&#xff0…

如何监控软件定义的数据中心(SDDC)

网络管理不仅要防止网络停机&#xff0c;还要优化网络性能&#xff0c;最终增强最终用户体验。当今的网络变得如此先进&#xff0c;以至于传统模型已经过时&#xff0c;无法满足现代动态需求。用日益敏捷、安全、可扩展和可靠的现代可部署解决方案取代传统的遗留系统至关重要。…

企业遭受勒索攻击后,要支付赎金吗?

企业遭受勒索攻击后&#xff0c;要支付赎金吗&#xff1f; 针对这个问题的答案&#xff0c;一些企业选择了“不要”。例如&#xff1a;意大利法拉利公司拒绝向黑客支付赎金&#xff1b;蔚来汽车老板拒绝支付1500万的赎金&#xff1b;澳洲最大医保公司在被盗取970万客户信息后&a…

关于《永恒之塔私服》收费模式的大胆猜想

我们都知道从第一个网络游戏走进中国时就已经使用了点卡模式的收费方式,但是随着游戏行业的快速发展,这种点卡模式的游戏也渐渐快要退出游戏收费的平台,也随着越来越多的游戏加入到中国的游戏市场也导致了游戏的竞争也越来越大,游戏公司也挖空心事来吸引玩家,为了吸引玩家2004年…

景23转债,海能转债上市价格预测

景23转债 基本信息 转债名称&#xff1a;景23转债&#xff0c;评级&#xff1a;AA&#xff0c;发行规模&#xff1a;11.54亿元。 正股名称&#xff1a;景旺电子&#xff0c;今日收盘价&#xff1a;22.52元&#xff0c;转股价格&#xff1a;25.71元。 当前转股价值 转债面值 / …

汉诺塔+小青蛙跳台阶---《递归》

目录 前言&#xff1a; 1.汉诺塔&#xff1a; 1.1分析盘子数从1-3的情况 1.2盘子移动的规律总结 2.青蛙跳台阶&#xff1a; 2.1跳一个台阶或跳两个台阶 2.2扩展 ❤博主CSDN:啊苏要学习 ▶专栏分类&#xff1a;C语言◀ C语言的学习&#xff0c;是为我们今后学习其它语言打…

asp.net+C#教育机构高校教务管理系统

1.1用户类别 本系统分为3个角色&#xff1a;管理员、教师、学生&#xff1b; 1、管理员权限最大&#xff0c;排课、调课、汇总各类考试成绩、管理各类用户基本信息&#xff0c;以及各类查询统计、发布公告、收发邮件等功能&#xff1b; 2、教师查看自己的信息、修改登陆密码…

[C++]C++入门(一)

目录 前言&#xff1a; 一、C关键字&#xff1a; 二、命名空间&#xff1a; 三、C输入和输出&#xff1a; 四、缺省参数&#xff1a; 五、函数重载&#xff1a; 六、引用&#xff1a; 常引用&#xff1a; ​编辑引用和指针的区别&#xff1a; 引用和指针的不同点&…

九联UNT401H-Hi3798MV300/MV310-当贝纯净桌面-强刷卡刷固件包

九联UNT401H-Hi3798MV300&#xff0f;MV310-当贝纯净桌面-强刷卡刷固件包-内有教程 特点&#xff1a; 1、适用于对应型号的电视盒子刷机&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、修改dns&#xff0c;三网通用&#xff1b; 4、大量精简内置…

达摩院开源多模态对话大模型mPLUG-Owl

miniGPT-4的热度至今未减&#xff0c;距离LLaVA的推出也不到半个月&#xff0c;而新的看图聊天模型已经问世了。今天要介绍的模型是一款类似于miniGPT-4和LLaVA的多模态对话生成模型&#xff0c;它的名字叫mPLUG-Owl。 论文链接&#xff1a;https://arxiv.org/abs/2304.14178…

《NFT区块链进阶指南二》Etherscan验证Solidity智能合约(Remix插件验证)

文章目录 一、验证说明二、Etherscan Key三、验证插件四、源码认证4.1 Remix验证&#xff08;推荐&#xff09;4.1.1 无构造参数合约验证4.1.2 有构造参数合约验证 4.2 单文件验证&#xff08;不推荐&#xff09;4.3 Hardhat部署&#xff08;按照需要&#xff09; 五、验证结果…

( 位运算 ) 461. 汉明距离 ——【Leetcode每日一题】

❓461. 汉明距离 难度&#xff1a;简单 两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。 给你两个整数 x 和 y&#xff0c;计算并返回它们之间的汉明距离。 示例 1&#xff1a; 输入&#xff1a;x 1, y 4 输出&#xff1a;2 解释&#xff1a; 1…