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

news/2025/2/12 8:54:30/

  一

前言:以前没用框架写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进行数据库的增删改查时及其方便,而且性能极佳。


http://www.ppmy.cn/news/66493.html

相关文章

05-HTML-图片标签

<img> 标签&#xff1a;src 属性是必需的。它规定图像的 URL。 绝对 URL - 指向另一个网站&#xff08;比如 src"http://www.example.com/image.gif"&#xff09;相对 URL - 指向网站内的一个文件&#xff08;比如 src"image.gif"&#xff09; <…

探索 Elasticsearch 8.X Terms Set 检索的应用与原理

1、Terms Set 检索简介 Terms Set查询是Elasticsearch中一种强大的查询类型&#xff0c;主要用于处理多值字段中的文档匹配。 其核心功能在于&#xff0c;它可以检索至少匹配一定数量给定词项的文档&#xff0c;其中匹配的数量可以是固定值&#xff0c;也可以是基于另一个字段的…

【人口模型】基于Logistic模型与Malthusian模型预测人口

基于Logistic模型与Malthusian模型预测人口 1 逻辑斯特模型(Logistic)1.1 简介1.2 案例2 马尔萨斯模型(Malthusian)2.1 简介2.2 案例参考人口预测是指根据某一区域某一期间已知的人口现状和人口变化过程的规律性, 提出影响人口发展过程的各种假设条件, 结合某种计算方法推…

【Python】什么才是好代码

什么才是好代码 背景有哪些静态分析工具呢度量Python代码的静态属性度量Python的生态系统 代码的坏味道在类层面上在方法层面上 结语 背景 静态代码分析工具能够提炼出丰富的代码静态属性信息&#xff0c;这使得程序员可以对代码的复杂性、可修改性和可读性有进一步的了解。 …

MySQL的学习

文章目录 一、MySQL 创建数据库二、MySQL 删除数据库三、MySQL 选择数据库四、MySQL 创建数据表五、MySQL 删除数据表总结 一、MySQL 创建数据库 使用 PHP脚本 创建数据库 PHP 使用 mysqli_query 函数来创建或者删除 MySQL 数据库。 该函数有两个参数&#xff0c;在执行成功…

无线蓝牙耳机佩戴舒适的有哪几款?佩戴舒适的蓝牙耳机推荐

自从真无线蓝牙耳机产品推出以来&#xff0c;它已经逐渐成为了当代年轻人外出必带的随身数码产品。虽然市面上不缺好产品&#xff0c;但大家对于蓝牙耳机的佩戴舒适度害死更加重要的&#xff0c;下面就来分享几款佩戴舒适的蓝牙耳机吧。 一、南卡小音舱Lite2蓝牙耳机 参考价格…

Qt与Halcon联合编程获取当前程序根目录以及相应变量转换

目录 1.Qt与Halcon联合编程获取当前程序根目录 2.Qt与Halcon联合编程变量转换 3.项目实例程序片段:

嘉兴桐乡外语提升-剑桥商务英语考试(BEC)日程

【报名时间】2月28日10:00至3月10日16:00 【考试时间】 BEC初级&#xff1a;5月13日 BEC中级&#xff1a;5月27日 BEC高级&#xff1a;5月20日 【准考证打印时间】 BEC初级&#xff1a;5月5日10:00 BEC中级&#xff1a;5月19日10:00 BEC高级&#xff1a;…