《Andorid开源》greenDao 数据库orm框架
一
前言:以前没用框架写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 */@Overrideprotected 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 */@Overridepublic Long readKey(Cursor cursor, int offset) {return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);} /** @inheritdoc */@Overridepublic Note readEntity(Cursor cursor, int offset) {Note entity = new Note( //cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // idcursor.getString(offset + 1), // textcursor.isNull(offset + 2) ? null : cursor.getString(offset + 2), // commentcursor.isNull(offset + 3) ? null : new java.util.Date(cursor.getLong(offset + 3)) // date);return entity;}/** @inheritdoc */@Overridepublic 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 */@Overrideprotected Long updateKeyAfterInsert(Note entity, long rowId) {entity.setId(rowId);return rowId;}/** @inheritdoc */@Overridepublic 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进行数据库的增删改查时及其方便,而且性能极佳。
相关文章:

《Andorid开源》greenDao 数据库orm框架
一 前言:以前没用框架写Andorid的Sqlite的时候就是用SQLiteDatabase ,SQLiteOpenHelper ,SQL语句等一些东西,特别在写SQL语句来进行 数据库操作的时候是一件很繁琐的事情,有时候没有错误提示的,很难找到错误的地方&a…...

Android类似微信聊天页面教程(Kotlin)五——选择发送图片
前提条件 安装并配置好Android Studio Android Studio Electric Eel | 2022.1.1 Patch 2 Build #AI-221.6008.13.2211.9619390, built on February 17, 2023 Runtime version: 11.0.150-b2043.56-9505619 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 11 …...

MongoDB:Win/Linux环境安装及一键部署脚本
1. Win安装 1.1 下载 MongoDB 安装程序 访问 MongoDB 官网,进入下载页面:Download MongoDB Community Server | MongoDB 选择 Windows 平台并下载最新版的 MongoDB 安装程序。 1.2 安装 MongoDB 双击安装程序,按照提示完成 MongoDB 的安装…...

KingbaseES V8R3 集群运维系列 -- failover切换后集群自动恢复
案例说明: KingbaseES V8R3集群默认在触发failover切换后,为保证数据安全,原主库需要通过人工介入后,恢复为新的备库加入到集群。在无人值守的现场环境,需要在触发failover切换后,主库可以自动恢复为新备…...

【Selenium中】——全栈开发——如桃花来
目录索引 查找元素:查找方法:单个元素查找:多个元素查找:*代码演示:* 元素交互操作:清空文字: 推荐的变量名定义名称:执行JavaScript :滚动页面方法:*滚动到底…...

Sarsa增强版之Sarsa-λ依然走迷宫
Sarsa-λ(Sarsa Lambda)是Sarsa算法的一种变体,其中“λ”表示一个介于0和1之间的参数,用于平衡当前状态和之前所有状态的重要性。 Sarsa算法是一种基于Q-learning算法的增量式学习方法,通过在实际环境中不断探索和学…...

生成 Cypher 能力:MOSS VS ChatGLM
生成 Cypher 能力:MOSS VS ChatGLM 生成 Cypher 能力:MOSS VS ChatGLM一、 测试结果二、 测试代码(包含Prompt) Here’s the table of contents: 生成 Cypher 能力:MOSS VS ChatGLM MOSS介绍:MOSS 是复旦大…...

数据库的键和存储
主键:数据库表中对存储数据对象给予以唯一和完整表示的数据列或属性的组合。一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空。 外键:在一个表中存在另一个表得主键称此为表的外键。 为什么用自增列作为主键? 如果我们定义了主…...

基于AT89C51单片机的并入串出乘法口诀的设计与仿真
点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87779146?spm1001.2014.3001.5503 源码获取 并入串出乘法口诀的设计与仿真系统设计 目录 第一章 概述 3 1.1课题研究及意义 3 1.2课题设计内容 4 第二章系统设计…...

人生在世皆有过错,来一起看看Java中的异常吧!!!
Java中的异常问题详解 一、异常的概念与分类 1.异常概念 概念:Java异常是一个描述在代码段中发生异常的对象,当发生异常情况时,一个代表该异常的对象被创建并且在导致该异常的方法中被抛出,而该方法可以选择自己处理异常或者传…...

linux 测试连接网络和端口 telnet
一、安装telnet 1、检测telnet-server的rpm包是否安装 [rootlocalhost ~]# rpm -qa telnet-server 若无输入内容,则表示没有安装。出于安全考虑telnet-server.rpm是默认没有安装的,而telnet的客户端是标配。即下面的软件是默认安装的。 2、若未安装&…...

一文快速入门体验 Hibernate
前言 Hibernate 是一个优秀的持久层的框架,当然,虽然现在说用得比较多的是 MyBaits,但是我工作中也不得不接触 Hibernate,特别是一些老项目需要你维护的时候。所以,在此写下这篇文章,方便自己回顾…...

【RabbitMQ】SpringAMQP
RabbitMQ 1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式: 同步通讯:就像打电话,需要实时响应。 异步通讯:就像发邮件,不需要马上回复。 两种方式各有优劣,打电话可以立即得到响应&am…...

错题汇总08
1.如果友元函数重载一个运算符时,其参数表中没有任何参数则说明该运算符是 A 一元运算符 B 二元运算符 C 选项A)和选项B)都可能 D 重载错误 运算符重载 1.重载成类的成员函数------>形参数目看起来比该运算符需要的参数个数少1&#x…...

使用urllib库简单入门
使用urllib库简单入门 Python中的urllib库是一个非常强大的工具,它提供了一些模块,如urllib.request、urllib.parse、urllib.error、urllib.robotparser等,可以用来处理URLs和网页数据的获取、发送和处理。 在本文中,我们将介绍…...

C++学习 Day11
目录 1. 再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表 1.3 explicit关键字 2. stastic成员 2.1 概念 2.2 特性 1. 再谈构造函数 1.1 构造函数体赋值 在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。 class Date…...

python中函数与类 类中的方法-静态方法/动态方法
class student():position即令def __init__(self,name,age):self.namenameself.ageagedef eat(self):passclassmethoddef cla(cls):passstaticmethoddef sta():passpassstustudent(name张三,age12) print(stu.position)stu.sta() stu.cla()# 直接使用静态和类方法 student.cla(…...

基于trace_id实现ForkJoinPool的链路追踪
一、引言 之前写过一篇博客:基于trace_id的链路追踪(含Feign、Hystrix、线程池等场景),主要介绍在微服务体系架构中,如何实现分布式系统的链路追踪的博客,其中主要实现了以下几种场景: Filter…...

Qt推流程序(视频文件/视频流/摄像头/桌面转成流媒体rtmp+hls+webrtc)可在网页和播放器远程观看
一、前言说明 推流直播就是把采集阶段封包好的内容传输到服务器的过程。其实就是将现场的视频信号从手机端,电脑端,摄影机端打包传到服务器的过程。“推流”对网络要求比较高,如果网络不稳定,直播效果就会很差,观众观…...

ChatGPT入门到高级【第一章】
第一章:Chatgpt的起源和发展 1.1 人工智能和Chatbot的概念 1.2 Chatbot的历史发展 1.3 机器学习技术在Chatbot中的应用 1.4 Chatgpt的诞生和发展 第二章:Chatgpt的技术原理 2.1 自然语言处理技术 2.2 深度学习技术 2.3 Transformer模型 2.4 GPT模型 第…...

云原生应用架构
本博客地址:https://security.blog.csdn.net/article/details/130566883 一、什么是云原生应用架构 成为云原生应用至少需要满足下面几个特点: ● 使用微服务架构对业务进行拆分。单个微服务是个自治的服务领域,对这个领域内的业务实体能够…...

rem、px、em的区别 -前端
文章目录 三者的区别特点与换算举例emrem 总结一总结二 三者的区别 在css中单位长度用的最多的是px、em、rem,这三个的区别是: 一、px是固定的像素,一旦设置了就无法因为适应页面大小而改变。 二、em和rem相对于px更具有灵活性,…...
分享几款小白从零开始学习的会用到的工具/网站
大二狗接触编程也有两年了,差生文具多这大众都认可的一句话,在这里蹭一下这个活动分享一下从0开始学习编程有啥好用的工具 目录 伴侣一、Snipaste截图工具 伴侣二、Postman软件(可用ApiPost平替) 伴侣三、字体图标网站 伴侣四…...

第八章 文件处理命令
第八章 文件处理命令 一、 文本编辑器 vi • vi 是 Unix 类操作系统中最为流行的文本编辑器。尽管目前 已有 gedit 等一些工作在图形界面下使用起来也更为方便 的文本编辑器,但在很多情况下,vi 这种专为字符界面操 作而设计的编辑器恐怕还是要充当首…...

LVS 负载均衡群集的 NAT 模式和 DR 模式
1. 对比 LVS 负载均衡群集的 NAT 模式和 DR 模式,比较其各自的优势 DR 模式 * 负载各节点服务器通过本地网络连接,不需要建立专用的IP隧道 原理:首先负载均衡器接收到客户的请求数据包时,根据调度算法决定将请求发送给哪个后端的…...

自学自动化测试,第一份工作就18K,因为掌握了这些技术
我个人的情况是有1年自动化测试工作经验半年的实习经验,2020年毕业,专业通信工程,大一的时候学过C语言,所以一直对于编程感兴趣,之所以毕业后没做通信的工作,通信行业的朋友应该都明白,通信的天…...

C++ 类的继承与派生
目录 1、继承的概念 2、继承(Inherit) 3、继承方式 4、父子同名成员并存 5、虚函数(virtual) 6、纯虚函数 1、继承的概念 以李白为例 类1是类2的基类(父类),类2是类3的基类(父类…...

分布式系统基础理论
CAP是分布式系统方向中的一个非常重要的理论,可以粗略的将它看成是分布式系统的起点,CAP分别代表的是分布式系统中的三种性质,分别是Consistency(可用性)、Availability(一致性)、Partition tol…...

HttpServletRequestWrapper的使用与原理
介绍 HttpServletRequestWrapper 实现了 HttpServletRequest 接口,可以让开发人员很方便的改造发送给 Servlet 的请求.HttpServletRequest 对参数值的获取实际调的是org.apache.catalina.connector.Request没有提供对应的set方法修改属性所以不能对前端传来的参…...

PBDB Data Service:List of fossil occurrences(化石产出记录列表)
List of fossil occurrences(化石产出记录列表) 描述用法参数选择PBDB所有记录(all_records)以下参数可用于按各种条件查询化石产出记录以下参数可用于筛选所选内容以下参数还可用于根据分类筛选结果列表以下参数可用于生成数据存…...