大神们都说GreenDao性能最好,使用方便,最近在做一个项目,刚好用到操作本地数据库,so机缘巧合,开始学习GreenDao,顺便做一下笔记。

(1)原理

我总有那么一个习惯,就是使用别人的工具,总想着能对其原理了解一二,一来可以学习点经验,二来就是能更好的使用这个工具。原理不在本章讨论范围内,故贴上一个网址,供大家好好参详:ORM对象关系映射之GreenDAO源码解析

(2)eclipse配置使用

GreenDao不像其他工具一样,直接将jar包导进去就可以用了。它需要我们新建一个java工程,导入greenDao-generator.jar和freemarker.jar两个包,生成我们所需要的类文件和相应的Dao文件,然后copy到我们的Android工程供我们使用。具体请参照:Android 配置使用 GreenDao 教程

(3)高级使用(copy,以免链接失效)

增加:

dao.insert(Student entity);//添加一个

dao.insertInTx(Student...entity);//批量添加

删除:

dao.deleteByKey(Long key);//根据主键删除

dao.deleteByKeyInTx(Long...keys);//批量删除

dao.delete(Student entity);//根据实体删除

dao.deleteInTx(Student... entities);//

批量删除dao.deleteAll();//全部删除

修改:

dao.update(Student entity);//根据实体更新

dao.updateInTx(Student...entities);//批量更新

查找:

Query query = dao.queryBuilder().where(StudentDao.Properties.Name.eq(content)).build();

List list = query.list();//或者利用sql语言查询

Query query = dao.queryBuilder().where( new StringCondition("_ID IN "+"(SELECT _ID FROM STUDENT WHERE AGE = 20)").build()

创建属性约束

我们可以在为Schema添加实体的时候,在实体添加属性时候进行属性的一些约束,如

Schema schema = new Schema(1,"com.sunzxyong.greendao");

Entity entity = schema.addEntity("Student");

entity.addIdProperty().autoincrement().primaryKey();//主键,自增

entity.addStringProperty("name").notNull();//不为空

entity.addIntProperty("age");

entity.addBooleanProperty("is_man").notNull();

new DaoGenerator().generateAll(schema,"../GreenDAODemo/app/src/main/java-gen");

保持实体中自定义的代码不会被覆盖

假如你需要在实体类中自定义一些字段变量和方法,而再次generator的实体类通常会覆盖以前的,如果你不想覆盖掉你自定义的代码,可以这样设置:

schema.enableKeepSectionsByDefault();//通过次Schema对象添加的所有实体都不会覆盖自定义的代码//或者

entity.setHasKeepSections(true);//单独让某个实体不覆盖自定义的代码

如果设置了上述代码,则生成的实体中会多出以下代码:

// KEEP INCLUDES - put your custom includes here

在这里添加引入

// KEEP INCLUDES END

// KEEP FIELDS - put your custom fields here

在这里添加字段变量

// KEEP FIELDS END

// KEEP METHODS - put your custom methods here

在这里添加方法

// KEEP METHODS END

多线程环境下使用GreenDAO

在多线程的环境下使用查询,你必须调用query的 forCurrentThread()为当前的线程获得一个query实例,如:

Query query = dao.queryBuilder().where(StudentDao.Properties.Name.eq(content)).build().forCurrentThread();

List list = query.list();

LazyList和List

在通过queryBuilder建立查询时候:

1、如果你想得到一个唯一的结果,可以调用Query的unique()方法,如:

Query query = dao.queryBuilder().where(StudentDao.Properties.Name.eq(content)).build().forCurrentThread();

Student student = query.unique();

2、如果你想得到多个结果,可以调用Query的list()或者listLazy()方法,这两个方法有什么区别呢?

(1)List - 当所有的实体查询完会立即一次性加载到内存中,即在List集合中

(2)LazyList - 懒加载的方式,即实体按照需求加载进入内存(查询完不会立即加载到内存中,只有在需要数据的时候也就是遍历这个LazyList的时候,才会加载到内存中),列表中的元素在第一次访问时候就会同时缓存在一个ArrayList集合中,它再次访问这些元素则直接从集合中拿。如果你不想缓存这些数据又想懒加载,可以通过Query的listLazyUncached()方法。这个集合在使用完毕必须close,即调用:listLazy.close();

GreenDao的代码混淆配置

-keepclassmembersclass*extendsde.greenrobot.dao.AbstractDao {

publicstaticjava.lang.String TABLENAME;

}

-keepclass**$Properties

借助两个Flag打印出SQL命令和传入的值

通过设置这两个Flag,可以在控制台中打印出我们执行的sql语句以及传入的值,方便用于检查

//下面两个Flag的设置可以在控制台中打印出此次查询的sql语句和value值

QueryBuilder.LOG_SQL = true;

QueryBuilder.LOG_VALUES = true;

Query query = dao.queryBuilder().where(StudentDao.Properties.Name.eq(content)).build().forCurrentThread();

LazyList list = query.listLazyUncached();

一对一关联

通常我们在操作数据库的时候,我们往往不是单独的对一张表进行操作,而是对这张表的操作会联动的影响另外一张表或者多张表,比如:现在有两张表,一张是用户User表(有name、age、sex三个字段),一张是头像Picture表(有pictureId、pictureName、width、height四个字段)。假如用户表和头像表是一对一关系,一个用户只有一个头像,一个头像只能有一个用户,所以要建立这两张表之间的联系,这两张表肯定是需要关联的,这样就可以通过用户的信息得到它的头像信息。我们知道在数据库中,关联两张表(暂且不说多对多关系的)一般都是把一张表的主键作为另外一张表的外键来做的,所以在Android中也同样,如果我们要关联User表和Picture表,那么只需要把Picture表的主键(假如是pictureId)作为User表的外键即可,另外一个亦是如此,如:

一对一

假设还是以上面的场景为例,则利用GreenDAO建立User表和Picture表一对一的关联可以这样建立:

//把User表的主键name作为Picture表的外键,把Picture的主键pictureId作为User表的外键,这样得到任何一个实体的信息都可以得到关联的另外一个实体的信息

Property property =  user.addLongProperty("pictureId").getProperty();

user.addToOne(picture,property);

Property propertyName = picture.addStringProperty("name").getProperty();

picture.addToOne(user,propertyName);

在为Schema添加实体的时候,我们在相应的实体中添加另外一个表的主键即可:

Schema schema = new Schema(1,"com.sunzxyong.greendao2");//User

Entity user = schema.addEntity("User");

user.addStringProperty("name").notNull().primaryKey();

user.addStringProperty("sex");//Picture

Entity picture =  schema.addEntity("Picture");

picture.addLongProperty("pictureId").primaryKey();

picture.addStringProperty("pictureName").notNull();

picture.addIntProperty("width");picture.addIntProperty("height");

//建立一对一关联

Property property =  user.addLongProperty("pictureId").getProperty();

user.addToOne(picture,property);//user通过pictureId可以找到对应的picture

property propertyName = picture.addStringProperty("name").getProperty();

picture.addToOne(user,propertyName);//picture通过name可以找到对应的user

new DaoGenerator().generateAll(schema,"../GreenDAODemo/app/src/main/java-gen");

运行之后会出现:

User类

一对多

大家都知道在超市购物时候,一位顾客可以有很多订单,而一个订单只能属于一位顾客,所以这就成了一对多的关系,假设顾客Customer表有customerId(primaryKey)、name两个属性,订单Order表有orderId(primaryKey)、money两个属性。

一对多

Schema schema = new Schema(1,"com.sunzxyong.greendao3");//顾客

Entity customer = schema.addEntity("Customer");

customer.addLongProperty("customerId").primaryKey();

customer.addStringProperty("name").notNull();//订单

Entity order = schema.addEntity("Order");

order.addLongProperty("orderId").primaryKey();

order.addDoubleProperty("money").notNull();

//建立一对多关联(顾客对订单为一对多)

Property property = order.addLongProperty("customerId").getProperty();

order.addToOne(customer,property);//order通过customerId可以找到对应的customer

customer.addToMany(order,property).setName("orders");//customer可以通过orders找到很多order

new DaoGenerator().generateAll(schema,"../GreenDAODemo/app/src/main/java-gen");

当设置了顾客对订单一对多关联后,Order实体(和表)中会多一个属性为customerId,所以通过订单我们可以得到该顾客信息,而Customer实体(和表)中会多一个List集合变量:List orders,表示该顾客的所有订单,其中orders其实是我们自定义的名字,在刚刚setName("orders")就是给这个变量设置了“orders“名称,而Customer实体中还提供了一个方法getOrders()表示得到该顾客所有订单:

Customer类

事实上它也是封装好了查询Order中顾客id为customerId的所有订单。

多对多

通常来说,在建立多对多关联上,我们都会采用新建一张中间表,利用中间表把多对多这种复杂关系简单化,在通常的选课系统上,一个学生可以选择多门课,一门课可以被多个学生选,这就是多对多关系了,假设Student有studentId、name两个属性,Course有courseId、courseName两个属性,则建立多对多关系为:

多对多

Schema schema = new Schema(1,"com.sunzxyong.greendao4");//学生

Entity student = schema.addEntity("Student");

student.addLongProperty("studentId").primaryKey();

student.addStringProperty("name").notNull();//课程

Entity course = schema.addEntity("Course");

course.addLongProperty("courseId").primaryKey();

course.addStringProperty("courseName").notNull();

//建立多对多关联

Entity studentCourse = schema.addEntity("StudentCourse");

Property studentId =  studentCourse.addLongProperty("studentId").getProperty();

Property courseId =  studentCourse.addLongProperty("courseId").getProperty();

studentCourse.addToOne(student,studentId);

studentCourse.addToOne(course,courseId);

student.addToMany(studentCourse, studentId);

course.addToMany(studentCourse,courseId);

new DaoGenerator().generateAll(schema,"../GreenDAODemo/app/src/main/java-gen");

这样就建立学生和课程表多对多的关联,学生实体和课程实体中都有这么一个方法:

public List getStudentCourseList(){

//...}

意思就是得到一个StudentCourse的集合,而StudentCourse实体中又有这么两个方法:

public Student getStudent(){//...}

public Course getCourse(){//...}

所以当我们得到了StudentCourse的List集合,我们可以通过StudentCourse中的这两个方法来得到对应的学生或者课程信息。

在使用GreenDAO定义实体的属性时候,通常来说定义的实体属性名就是对应的表的字段名、实体中属性的类型(如Long、String等)就是表的字段名类型,但是我们难免会有不一样的需求,比如实体中我定义了一个Color类型的属性或者其它自定义类型的属性,而表的字段类型只有一些原始类型肯定是没有这些类型的,所以这时候该怎么办呢?

不用急,GreenDAO给我们提供了一个强大的工具,就是属性转换器:PropertyConverter。这是一个接口,我们使用它可以让实体的属性类型不再局限于原始类型, 可以自定义任何的类型,充分保证了实体的灵活性。既然实体的类型可以是自定义的任何类型,而表中只有一些原始类型,那么自定义类型和原始类型之间怎么进行值的交互呢?这是通过PropertyConverter来进行转换的,它就是相当于一个中间层,让数据在实体中是一种表现形式,而在表中又是另外一种表现形式。所以在进行CRUD的时候我们就可以直接赋值了,转换工作交给PropertyConverter做就好了。

好了,我们来使用一下吧,刚刚说PropertyConverter是个接口,那么要定义一个属性转换器肯定是需要实现这个接口的,实现这个接口是要在Android工程中,而这个接口中有两个方法需要实现,为:

public class MyPropertyConverter implements PropertyConverter {

@Override

public String convertToEntityProperty(Long databaseValue) {

returnnull;

}

@Override

public Long convertToDatabaseValue(String entityProperty) {

returnnull;

}

}

其中PropertyConverter接口中需要定义两个泛型,意思分别为P:实体中自定义的类型,D:数据库中的类型。

下面通过一个简单的实例来看看具体怎么使用:

假如有一个时间数据,实体类中的类型为String类型(用来直接展示2015-09-16 17:50 星期三格式的数据),而数据库中的类型为Long类型,用来存放精确的毫秒值,而且需要进行一系列的运算,所以类型肯定是要为Long类型。

我们先来定义一个属性转换器:

public class MyPropertyConverter implements PropertyConverter {

@Override

public String convertToEntityProperty(Long databaseValue) {

SimpleDateFormat format =newSimpleDateFormat("yyyy-MM-dd HH:mm EEEE",             Locale.CHINA);

String result = format.format(newDate(databaseValue));returnresult;

}

@Override

public Long convertToDatabaseValue(String entityProperty) {

SimpleDateFormat format =newSimpleDateFormat("yyyy-MM-dd HH:mm EEEE",             Locale.CHINA);

Long result;

try{

Datedate= format.parse(entityProperty);

result =date.getTime();

}catch(ParseException e) {

result =0L;

}

returnresult;

}

}

然后在添加实体的时候这样添加:

Schema schema = new Schema(1,"com.sunzxyong.greendao5");

Entity item = schema.addEntity("Item");

item.addLongProperty("time").customType("java.lang.String","com.sunzxyong.greendaodemo.MyPropertyConverter");

new DaoGenerator().generateAll(schema,"../GreenDAODemo/app/src/main/java-gen");

其中customType()方法的第一个参数为实体中的自定义类型的包名+类名,第二个参数为转换器的包名+类名。

点击运行生成实体后,我们打开Item类看看,发现time的类型为String类型:

public classItem {

private String time;

public Item() {

}

public Item(String time) {

this.time = time;

}

public String getTime() {

return time;

}

public void setTime(String time) {

this.time = time;

}

}

我们再打开数据库文件看看time字段的类型:

数据库

发现为Integer类型,原因是我用第三方工具打开后,设计表中的类型没有Long类型,而就为Integer类型了

所以利用自定义属性转换器PropertyConverter我们只需要直接按实体中的类型添加数据,存入表中时候转换器会帮我们做好一系列转换工作。

以上都是别人写的,因为条理比较清晰,自己整理整理,做项目的时候可以迅速查阅一下。

greendao连接mysql_使用GreenDao操作数据库相关推荐

  1. jedis连接mysql_使用Jedis操作Redis数据库

    Redis不仅是使用命令来操作,现在基本上主流的语言都有客户端支持,比如java.C.C#.C++.php.Node.js.Go等. 在官方网站里列一些Java的客户端,有Jedis.Redisson ...

  2. xshell如何登陆数据库_Xshell连接远程服务器和操作数据库

    (1)连接服务器的操作: 打开xshell,连接远程服务器: 填好主机地址,点击确定后:跳到会话页面,点击连接:输入登陆的用户名(用户必须经过授权后才能登陆),进入身份验证页面:用户密钥一般会自动生成 ...

  3. 云虚拟主机连接mysql_云虚拟主机数据库使用

    进入数据库 A登录控制台->虚拟主机->数据库,找到对应的数据库 点击 管理 B登录控制台->虚拟主机->云虚拟主机,选择需要创建数据库的云虚拟主机,点击管理,进入主机详情页 ...

  4. linq 连接mysql_使用LINQ访问数据库

    1. LINQ to SQL 概览 • 把.NET 类和 SQL 数据通过关系进行映射 • 把 LINQ 查询转化为 SQL 语言进行执行 • 支持对插入,更新,删除操作进行跟踪. 支持实体级别的验证 ...

  5. 火车头连接mysql_火车头如何进行数据库配置管理

    火车头是什么? 火车头是什么? 我们看一下百度的解释: 火车采集器(LocoySpider) 是一个供各大主流文章系统,论坛系统等使用的多线程内容采集发布程序.使用火车采集器,你可以瞬间建立一个拥有 ...

  6. php怎么和数据库建立连接数据库服务器端,PHP和 mysql 数据库服务器连接上,才能进一步操作数据库。...

    [单选题]The advantage of dynamic RAM over static RAM is that ( ). [判断题]胎盘的屏障功能表现在两个方面,一是阻止某些物质的运输,二是起到免 ...

  7. python 连接hive_《go语言从入门到入坟》Go 操作 数据库、Redis、HDFS

    楔子 这里我们来介绍一下如何使用 Go 连接数据库.Redis.HDFS,当然数据库.Redis.HDFS本身我们就不介绍了,这里我们主要介绍如何使用 Go 进行连接并执行相应操作. Go 操作数据库 ...

  8. c#操作mysql 执行语句_C# Command:操作数据库

    在上一节<C# Connection>中我们讲解了 C# 语言连接数据库的方法,在与数据库建立连接之后即可开始操作数据库中的对象. 操作数据库需则要用到 Command 类中提供的属性和方 ...

  9. greendao连接mysql_Android数据库GreenDao使用说明

    介绍 GreenDao是一个开源的 Android ORM嵌入式关系数据库,通过将 Java 对象映射到数据库表(称为 ORM,"对象/关系映射") ,使用一个简单的面向对象的 A ...

最新文章

  1. Spring MVC入门
  2. vue 数组中嵌套数组_来,一起聊聊Excel中的数组
  3. [leetcode]1007. 行相等的最少多米诺旋转
  4. 阿里笔试-二叉树由前序遍历和中序遍历推导后序遍历
  5. win7 蓝牙4.0 ble驱动_初识物联网无线通信技术之蓝牙4.0BLE协议栈
  6. 前端学习(650):标识符 关键字 保留字
  7. 【声学基础】概述——传播
  8. OpenShift 4 之 配置基于Red Hat SSO的Identity Providers
  9. ai软件基础教程自学网,怎么快速学会ai软件
  10. 谷歌浏览器:快速切换搜索引擎
  11. MySQL主从- slave跳过错误
  12. html前端的几种加密/解密方式
  13. 【wordpress】文章编辑器插件
  14. Mysql引擎的知识
  15. cdq分治和整体二分
  16. ipaddress库:Python中网络地址的处理
  17. CMDB开发之基础搭建
  18. qsv文件转码mp4格式过程记录
  19. WPF ListBox
  20. 托管中的柴犬交易员可以感谢SHIB的最新成就

热门文章

  1. iOS系统如何彻底删除微信聊天记录?分布式删除,挖掘深层数据!
  2. Linux HA Cluster高可用集群之HeartBeat2
  3. 【嗜血GO笔记】引入包的一个异常
  4. C# 阿里云Redis存储服务 使用总结
  5. 阿里云Redis报NOAUTH Authentication required
  6. 各种鲜榨果汁配方及制作方法
  7. 事务的acid属性是指_什么是事务的acid性质
  8. [pyecharts学习笔记]——Bar 柱状图/条形图
  9. redis3.2.100在windows不支持daemonize命令后台启动
  10. 拜占庭将军问题与区块链共识算法PBFT