GreenDao3.2数据库使用教程
greenDao github地址
相关gradle配置
// 根目录下 build.gradle 文件:
buildscript {repositories {jcenter()mavenCentral() // add repository}dependencies {classpath 'com.android.tools.build:gradle:2.3.3'classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin}
}// app项目 build.gradle 文件:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply pluginandroid {//...其他相关配置//...compileSdkVersion / buildToolsVersion//数据库配置项[必填] greendao {schemaVersion 1 //数据库版本号daoPackage 'com.micro.testgreengao.greendao.gen' //自动生成的工具类包名targetGenDir 'src/main/java' //自动代码生成路径}
}dependencies {compile 'org.greenrobot:greendao:3.2.2' // add library
}
可参考配置:点这里
基本增删改查命令【CRUD】
新建User.java文件,如下:
@Entity
public class User {@Id(autoincrement = true)@Property(nameInDb = "_id")private Long _id ;@Property(nameInDb = "_name" )private String name ;@Property(nameInDb = "_age")private int age ;@Generated()public User() {}
这里声明一下,各种注解稍后解释,大家先看着就行,User的属性getter/setter方法不需要你生成,使用Ctrl+F9(或者Build -> make module)进行编译,然后在你所写的greendao/package路径下生成了三个文件:UserDao,DaoMaster,DaoSession,如下图(其他文件无视即可):
同时再回过头来,你会发现你的User.java文件也生成了getter/setter方法,那么说明自动生成已经凑效了。
下面就greenDao的注解,简单说明一下各个注解的含义:
@Entity 标识实体类,greenDAO会映射成sqlite的一个表,表名为实体类名的大写形式@Id 标识主键,该字段的类型为long或Long类型,autoincrement设置是否自动增长@Property 标识该属性在表中对应的列名称, nameInDb设置名称@Transient 标识该属性将不会映射到表中,也就是没有这列@NotNull 设置表中当前列的值不可为空@Convert 指定自定义类型(@linkPropertyConverter)@Generated greenDAO运行所产生的构造函数或者方法,被此标注的代码可以变更或者下次运行时清除@Index 使用@Index作为一个属性来创建一个索引;定义多列索引(@link Entity#indexes())@JoinEntity 定义表连接关系@JoinProperty 定义名称和引用名称属性关系@Keep 注解的代码段在GreenDao下次运行时保持不变 1.注解实体类:默认禁止修改此类 2.注解其他代码段,默认禁止修改注解的代码段@OrderBy 指定排序@ToMany 定义与多个实体对象的关系@ToOne 定义与另一个实体(一个实体对象)的关系@Unique 向数据库列添加了一个唯一的约束
注解需要在实际中运用,光这个我也是记不住的,写多了自然就记住了。
编写dao处理对象:
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(ctx,DB_NAME);
DaoMaster mDaoMaster = new DaoMaster(devOpenHelper.getWritableDb());
DaoSession mDaoSession = mDaoMaster.newSession();
具体代码可以参考这里;
新增操作
public void addData(User user) {UserDao userDao = mDaoSession.getUserDao();long insertId = userDao.insert(user);LogUtils.d("insertId:"+insertId);}
注意,User的初始化为:
User user = new User(null,"zhangsan",18);
User的Id应该设置为null,不然id默认为0,在自增主键情况下,插入数据将会报错。
同时还有以下方法:
userDao.insertWithoutSettingPk(user); //如果没有对象没有设置主键,使用这个方法,你基本上放进去的东西就废了,因为不知道怎么找出来:)userDao.insertOrReplace(user); //如果主键一致,则替换为新的User对象userDao.insertInTx(List<User>); //批量插入User对象
删除
public void deleteUser(long _id) {UserDao userDao = mDaoSession.getUserDao();userDao.deleteByKey(_id);LogUtils.d("delete User finished");}
上面是使用primary_key删除的,还有以下删除方式:
userDao.deleteAll(); //删除全部
userDao.deleteByKeyInTx(List<Long> idList); //删除id为idList中的User
userDao.deleteInTx(List<User> userList); //删除集合中的user
userDao.delete(user); //删除目标User[需要包含主键]
还可以使用条件删除,使用StringCondition模式,删除name=micro和age>20岁的人
QueryBuilder<User> queryBuilder = mDaoSession.queryBuilder(User.class);;WhereCondition.StringCondition stringCondition = new WhereCondition.StringCondition("_name = 'micro'");
WhereCondition.StringCondition stringCondition1 = new WhereCondition.StringCondition("_age > 20");queryBuilder.where(stringCondition,stringCondition1).buildDelete().executeDeleteWithoutDetachingEntities();
删除name=micro 或者 name>20的user
queryBuilder.whereOr(stringCondition,stringCondition1).buildDelete().executeDeleteWithoutDetachingEntities();
当然还可以使用Property进行删除:
QueryBuilder<User> queryBuilder = mDaoSession.queryBuilder(User.class);WhereCondition nameCondition = null ;WhereCondition ageCondition = null;Property[] properties = mDaoSession.getUserDao().getProperties();for (Property p : properties) {if(p.columnName.equals("_name")) {nameCondition = p.eq("micro");}if(p.columnName.equals("_age")){ageCondition = p.gt(20);}}queryBuilder.whereOr(nameCondition,ageCondition).buildDelete().executeDeleteWithoutDetachingEntities();
基本套路是一致的。
修改
基本代码如下:
public void updateUser(User user) {UserDao userDao = mDaoSession.getUserDao();userDao.update(user);LogUtils.d("update user finished");}
这里User中需要有主键,不然没法修改的。
当然还有
userDao.updateInTx(Iterator<User>); //批量修改User
查找
这个查找是SQL中最复杂最难的一个科目,也是考验程序员经验的时候,面对大数据量的数据库,一条有经验的SQL往往能节省很多时间,到了我们android这里,就不扯了,greenDao已经做了很好的优化了,你只需要怎么查找就行了。
通过Id查找
这个最简单了,就不说了,代码为:
public void btnGetById(View view) {User user = mDaoSession.load(User.class,2L);if(null != user) {mTvInfo.setText(user.toString());}else{Toast.makeText(this, "查询数据失败", Toast.LENGTH_SHORT).show();}}
通过原生SQL查找
这个一般在条件语句中用的比较多:
public void btnGetBySQL(View view) {String sql = "select * from " + UserDao.TABLENAME + " where _age > ? " ;Cursor cursor = mDaoSession.getDatabase().rawQuery(sql,new String[]{String.valueOf(23)});while (null != cursor && cursor.moveToNext()) {Long _id = cursor.getLong(cursor.getColumnIndex("_id"));String name = cursor.getString(cursor.getColumnIndex("_name")) ;int age = cursor.getInt(cursor.getColumnIndex("_age"));//..... 原生的SQLite写法}
}
通过StringCondition查找
这个其实也说过了,就是上面的删除项,其实删除就是你先查出来再删除啊:
public void btnGetByStringCondition(View view) {QueryBuilder<User> queryBuilder = mDaoSession.queryBuilder(User.class);WhereCondition.StringCondition stringCondition = new WhereCondition.StringCondition("_name = 'micro'");WhereCondition.StringCondition stringCondition1 = new WhereCondition.StringCondition("_age > 20");List<User> userList = queryBuilder.where(stringCondition,stringCondition1).build().list();Log.d("TAG","---->>>" + userList);}
通过PropertyCondition查找
QueryBuilder<User> queryBuilder = mDaoSession.queryBuilder(User.class);WhereCondition nameCondition = null ;
WhereCondition ageCondition = null;
Property[] properties = mDaoSession.getUserDao().getProperties();for (Property p : properties) {if(p.columnName.equals("_name")) {nameCondition = p.eq("micro"); //p.eq,p.nep,p.like,p.between,p.in,p.notIn,p.isNull,p.isNotNull 各种SQL操作}if(p.columnName.equals("_age")){ageCondition = p.gt(20);}
}List<User> userList = queryBuilder.where(queryBuilder.or(nameCondition,ageCondition)).build().list();
数据库关系模型
目前greenDao支持的数据库模型为一对比一,一对多模型,暂未支持多对多模型。这是这篇博客的重点所在,在项目中,遇到几张表,没什么逻辑关系,那么使用原生的SQLite就可以搞定了,就不比请greenDao大佬了。由于在项目中遇到了很多表出现了相互依赖的关系,那么使用greenDao简单配置一下,就可以使用了。
一对一关系
什么是一对一,读官方的解释我不会,就举个例子吧,每个人对应一张身份证信息,那么提取对象人与身份证 就是一对一的关系。在greenDao中,建立这种一对一的关系,先要确定谁是主导关系,这里是人,因为有人才有身份证信息,那么看IdCard和Person对象:
IdCard对象
@Entity
public class IdCard {@Id(autoincrement = true)private Long _id ;private String cardName;private String location;@Generated()public IdCard() {}
}
Person对象
@Entity
public class Person {@Id(autoincrement = true)private Long _id;private String name ;private Long idCardId ;@ToOne(joinProperty = "idCardId")private IdCard idCard;@Generatedpublic Person(){}}
可以看到,Person对象中存在了IdCard的引用,而且IdCard的注解上为@ToOne,而其中的joinProperty对应了Person中一个私有属性idCardId。
完成编译之后,我们可以打开greenDao给我们建立的数据库,其中Person与IdCard表的结构为:
我们看到了Person表里面引用了IdCard的id,那么添加数据时应该这样:
public void addPersonAndIdCard(View view) {IdCard idCard = new IdCard(null,"421111111133","shanghai22");mDaoSession.getIdCardDao().insert(idCard);Person p = new Person(null,"lisi",null);p.setIdCard(idCard);Long insertId = mDaoSession.getIdCardDao().getPersonDao().insert(p);Toast.makeText(this, "the insert id is " + insertId, Toast.LENGTH_SHORT).show();}
结果为:
一对多关系
对于一对多关系,这个字面上很好解释,一个人可以拥有多套房子,一个人可以买多件商品,水有不同的状态等等。在greenDao中,有三种映射方式生成一对
第一种:
@ToMany(referencedJoinProperty = “referenceId”)
一个人可有多个产品订单,抽象之后产生:顾客Customer与订单Order对象。一个顾客对应多个订单:
Order.java:
@Entity(nameInDb = "t_order")
public class Order {@Idprivate Long _id ;private java.util.Date date ;//引用了顾客的Idprivate long customerId ;@Generated()public Order() {}
Customer.java:
@Entity
public class Customer {@Idprivate Long id ;@ToMany(referencedJoinProperty = "customerId")@OrderBy("date ASC")private List<Order> orders;@Generated()public Customer() {}
在Custom中使用注解@ToMany, 其referencedJoinProperty 对应Order对象中的customerId 对应的多个订单为List类型,生成的表的结构为:
插入数据:
public void btnAdd(View view) {CustomerDao customerDao = mSession.getCustomerDao();Customer customer = new Customer(null);customerDao.insert(customer);OrderDao orderDao = mSession.getOrderDao();Order order1 = new Order(null,new Date(),customer.getId());Order order2 = new Order(null,new Date(),customer.getId());Order order3 = new Order(null,new Date(),customer.getId());orderDao.insert(order1);orderDao.insert(order2);orderDao.insert(order3);Toast.makeText(this, "add data finished...", Toast.LENGTH_SHORT).show();}
第二种:
@ToMany(joinProperties = {
@JoinProperty(name = “current_object_param”,referencedName = “reference_object_params”)
})
什么意思呢?不好解释,那还是举个例子吧,比如一个成功的人SuccessfulMan拥有很多家公司,抽象出来,这个SuccessfulMan对应多个公司对象,那么相对应的对象分别为:
SuccessFulMan.java
@Entity
public class SuccessfulMan {@Id(autoincrement = true)private Long _id;private int age ;@NotNullprivate String name;@ToMany(joinProperties = {@JoinProperty(name = "name",referencedName = "successfulManName")})@OrderBy("date ASC")private List<Company> companyList;@Generated()public SuccessfulMan (){}}
Company.java:
@Entity
public class Company {@Id(autoincrement = true)private Long _id;@NotNullprivate String successfulManName ;//当前公司名称private String companyName ;private java.util.Date date ;//销售额private double price;@Generated()public Company(){}
}
编译成功之后,我们查看两张表的结构:
SuccessfulMan表中的name字段与Company表中的successful_man_name绑定了,我们来添加数据试一下:
public void addBtn(View view) {SuccessfulMan man = new SuccessfulMan(null, "micro", 34);mDaoSession.getSuccessfulManDao().insert(man);Company company = new Company(null, "micro", "baidu1", new Date(), 2000);Company company2 = new Company(null, "micro", "tencent1", new Date(), 4000);Company company3 = new Company(null, "micro", "ali1", new Date(), 5000);mDaoSession.getCompanyDao().insert(company);mDaoSession.getCompanyDao().insert(company2);mDaoSession.getCompanyDao().insert(company3);Toast.makeText(this, "insert data finished....", Toast.LENGTH_SHORT).show();}
可以看到的结果为:
可以看到绑定的name是一致的。
第三种:
@ToMany
@JoinEntity(entity = A_AND_B.class,
sourceProperty = “referenceAId” ,
targetProperty = “referenceBId”)
个人感觉这个是最好理解的,同时感觉这个也是最greenDao中最接近多对多关系的一种模式。还是拿例子说话吧。一个城市图书馆很多书,那么图书馆与书就是一对多的关系,抽象成代码为:
Book.java:
@Entity
public class Book {@Idprivate Long _id;private String name ;private double price ;@Generatedpublic Book(){}
City.java:[library不会写!!!]
@Entity
public class City {@Idprivate Long _id;private String name ;@ToMany@JoinEntity(entity = CityAndBooks.class,sourceProperty = "cityId" ,targetProperty = "bookId")private List<Book> bookList;@Generatedpublic City(){}
中间体CityAndBooks.java:
@Entity
public class CityAndBooks {@Idprivate Long _id;private long bookId;private long cityId ;@Generated()public CityAndBooks() {}
编译之后,获取的表结构为:
图中可以看出,此时的一对多关系建立了三张表,而city_and_book表记录了city表的id,book表的id,相互查询时就是按照这张中间表进行的,我们插入数据看一下结果:
City city = new City(null,"shanghai");City city1 = new City(null,"北京");Book book = new Book(null,"one night",40);Book book1 = new Book(null,"thinking in java",68);mDaoSession.getCityDao().insert(city);mDaoSession.getCityDao().insert(city1);mDaoSession.getBookDao().insert(book);mDaoSession.getBookDao().insert(book1);CityAndBooks cb = new CityAndBooks(null,book.get_id(),city.get_id());CityAndBooks cb1 = new CityAndBooks(null,book1.get_id() , city1.get_id());mDaoSession.getCityAndBooksDao().insert(cb);mDaoSession.getCityAndBooksDao().insert(cb1);Toast.makeText(this, "insert data finished....", Toast.LENGTH_SHORT).show();
我们来看一下结果:
可以看出,我们的city与book已经建立了联系,那么查询起来应该不是那么困难吧。
数据库的更新
对于greenDao,或者对于SQLite数据库更新,一般比较负责任的方式一般是这样的:
* 对于需要更新的表,创建临时表,复制数据
* 删除需要更新的表
* 创建新的目标表
* 将临时数据复制到新的目标表中,并删除临时表
这个就不说,下面的地址中会给出代码更新代码。
好了,greenDao的基本用法就介绍得差不多了,当然还有很多细节问题需要大家去注意了,这个只有大家在应用中去体会了,东西还是很多的,如果有问题或者疑惑,请留言。
所有代码地址为:https://github.com/Microhx/studyCodes/tree/master/testgreengao
效果图为:
GreenDao3.2数据库使用教程相关推荐
- MySQL数据库实用教程考核_《MySQL数据库实用教程》郑明秋,蒙连超,赵海侠【pdf】...
内容简介 郑明秋.蒙连超.赵海侠主编的<MySQL数据库实用教程>是作者在多年的数据库开发实践与教学经验的基础上,根据计算机相关专业的职业岗位能力需求及学生的认知规律倾心组织编写的.本教材 ...
- xp 安装mysql数据库_Windows XP系统中安装MySQL5.5.28数据库图文教程
Windows XP系统中安装MySQL5.5.28数据库图文教程 2014-07-13 16:35来源:中国存储网 导读:MySQL数据库的安装一共分为两个部分:数据库的安装和数据库的配置.一.My ...
- mysql connector安装教程_通过安装MySQL Connector/Net实现VS2017 C#编程连接MySQL数据库-网络教程与技术
-亦是美网络...
对编程有一定了解的小伙伴都知道,一般情况下使用微软的visual studio进行编程开发都会搭配自家的SQL server.Access数据库,而开发web程序一般情况下PHP搭配MySQL使用,但 ...
- myeclipse mysql连接_MyEclipse连接MySQL数据库图文教程
这篇文章主要为大家详细介绍了MyEclipse连接MySQL数据库图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 自己在自学JavaEE课程时,在做一些小东西的时候,需要连接MySQL数据 ...
- mysql数据库入门教程(11):视图讲解大全
一.视图的介绍 含义:虚拟表,和普通表一样使用 mysql5.1版本出现的新特性,是通过表动态生成的数据 举例说明什么是视图:假设一个年级有10个班,上面有领导来啦,说要检查舞蹈功底,学校为了应付检查 ...
- mysql数据库入门教程(6):数据的增删改
前面两篇博文介绍了数据库的查询 mysql数据库入门教程(4):查询讲解大全 mysql数据库入门教程(5):多表操作(连接查询,子查询,分页查询,联合查询) 今天介绍下数据库的增删改. 数据库基本操 ...
- mysql数据库入门教程(5):多表操作(连接查询,子查询,分页查询,联合查询)
前文介绍了单表查询:mysql数据库入门教程(4):查询讲解大全 今天介绍下多表查询 一.连接查询 含义:又称多表查询,当查询的字段来自于多个表时,就会用到连接查询 先送上下面所讲用到的sql脚本 h ...
- Oracle数据库基础教程:入门其实很简单
为什么80%的码农都做不了架构师?>>> Oracle数据库基础教程:入门其实很简单 Oracle数据库系统是目前最流行的客户/服务器数据库之一.本文集从初学者的角度出发,由浅 ...
- 卸载linux下的mysql数据库实例_Linux下卸载MySQL数据库实例教程
本文主要介绍了Linux下卸载MySQL数据库的方法,不知道Linux下卸载MySQL数据库的小伙伴们可以学习一下,本文具有一定的参考价值,希望能帮助到大家. 如何在Linux下卸载MySQL数据库呢 ...
最新文章
- 关于mac注册机core keygen在10.12及以上版本不能使用的解决方法
- App设计灵感之十二组精美的家具产品电商App设计案例
- 第一周周日DailyReporting——PM(李忠)
- [单选]物联网产业链的主要产品不包括下列哪一项 - 关于物联网(主讲:柳毅)笔记...
- 言图科技:GPU服务器选型
- 吴恩达深度学习5.1练习_Sequence Models_Building a RNN Step by Step
- hdu 4318 Power transmission 临接表 广搜 多校联合赛(二) 第九题
- 关于android中PendingIntent.getBroadcase的注册广播
- RDCMan之DPI 和 Screen Resolution设置
- matlab指数e是如何表示,Matlab中表达e怎么操作?表达e方法详解
- 在linaro中安装opencv
- sqli-labs闯关指南 1—10
- 【Modbus 】Modbus 协议
- 服务器个别目录下不能新建文件夹,域服务器不能创建sysvol和netlogon共享文件夹...
- 高一计算机课的总结,高中《信息技术》期末教学总结范文
- Jmeter简单操作
- UDS刷写上位机全套CAPL脚本,有简单panel界面
- Quectel BC28-CNV 多频段、高性能、低功耗 LTE Cat NB2 无线通信模块[移远通信]
- 这些年我用过的 6个API 接口文档平台,真的好用
- 对傅里叶变换公式讨论 很经典
热门文章
- matlab获取手机传感器,分享采集Android内置传感器数据到MATLAB的方法
- Mac系统清理软件有必要安装CleanMyMac吗 Mac电脑怎么彻底清理卸载的软件
- BUUCTF-MISC-[GXYCTF2019]SXMgdGhpcyBiYXNlPw==~zip
- 后疫情时代,VR全景创业的应用场景有哪些?
- Safari中new Date()格式化问题总结
- FastJson序列化后Date日期类型变成时间戳
- 3d网上渲染平台是怎么渲图的_云渲染流程详解!
- Kubernetes 最佳实践
- 在Linux上创建txt文件,并编辑
- Win10内核驱动断链式隐藏指定进程