首先看一下效果图:

项目结构如下图所示:

第一步:在build中添加配置如下:

projet 目录下的build.gradle

dependencies {

classpath 'org.greenrobot:greendao-gradle-plugin:3.2.0'
}

moudle 下的build.gradle添加如下内容:
apply plugin: 'org.greenrobot.greendao'

dependencies {
.....................

compile 'org.greenrobot:greendao:3.2.0'
}

添加完成之后点击sync一下工程

第二步:

首先在moudle下  build.gradle的根目录下添加如下配置

greendao {
//数据库的schema版本,也可以理解为数据库版本号
schemaVersion 1
//设置DaoMaster、DaoSession、Dao包名,也就是要放置这些类的包的全路径。
daoPackage 'com.koimy.greedaotest.dao'
//设置DaoMaster、DaoSession、Dao目录
targetGenDir 'src/main/java'
}
在项目里面添加实体类Student如下所示:
@Entity
public class Student {
@Id
private Long id;
private String name;
private int age;
private String num;
}
此时项目目录如下所示:

然后点击 android studio 的 build-->make project

此时项目结构如下:

其中dao目录下的文件是由greendao自动生成的,Student 类里面的内容发生了编号如下:

/**
* Created by hp on 2018/1/23.
*/
@Entity
public class Student {
@Id
private Long id;
private String name;
private int age;
private String num;
@Generated(hash = 1538557423)
public Student(Long id, String name, int age, String num) {
this.id = id;
this.name = name;
this.age = age;
this.num = num;
}
@Generated(hash = 1556870573)
public Student() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
public String getNum() {
return this.num;
}
public void setNum(String num) {
this.num = num;
}
GreenDao帮助我们自动生成了一些get和set方法,以及构造方法
第三步:为了方便使用我们添加了一个 db包

DbManager类如下:

package com.koimy.greedaotest.db;

/**
* Created by hp on 2018/1/23.
*/

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;

import com.koimy.greedaotest.dao.DaoMaster;
import com.koimy.greedaotest.dao.DaoSession;


public class DbManager {

// 是否加密
public static final boolean ENCRYPTED = true;

private static final String DB_NAME = "test.db";
private static DbManager mDbManager;
private static DaoMaster.DevOpenHelper mDevOpenHelper;
private static DaoMaster mDaoMaster;
private static DaoSession mDaoSession;

private Context mContext;

private DbManager(Context context) {
this.mContext = context;
// 初始化数据库信息
mDevOpenHelper = new DaoMaster.DevOpenHelper(context, DB_NAME);
getDaoMaster(context);
getDaoSession(context);
}

public static DbManager getInstance(Context context) {
if (null == mDbManager) {
synchronized (DbManager.class) {
if (null == mDbManager) {
mDbManager = new DbManager(context);
}
}
}
return mDbManager;
}

/**
* 获取可读数据库
*
* @param context
* @return
*/
public static SQLiteDatabase getReadableDatabase(Context context) {
if (null == mDevOpenHelper) {
getInstance(context);
}
return mDevOpenHelper.getReadableDatabase();
}

/**
* 获取可写数据库
*
* @param context
* @return
*/
public static SQLiteDatabase getWritableDatabase(Context context) {
if (null == mDevOpenHelper) {
getInstance(context);
}

return mDevOpenHelper.getWritableDatabase();
}

/**
* 获取DaoMaster
*
* @param context
* @return
*/
public static DaoMaster getDaoMaster(Context context) {
if (null == mDaoMaster) {
synchronized (DbManager.class) {
if (null == mDaoMaster) {
mDaoMaster = new DaoMaster(getWritableDatabase(context));
}
}
}
return mDaoMaster;
}

// /**
// * 获取DaoMaster
// *
// * 判断是否存在数据库,如果没有则创建数据库
// * @param context
// * @return
// */
// public static DaoMaster getDaoMaster(Context context) {
// if (null == mDaoMaster) {
// synchronized (DbManager.class) {
// if (null == mDaoMaster) {
// MyOpenHelper helper = new MyOpenHelper(context,DB_NAME,null);
// mDaoMaster = new DaoMaster(helper.getWritableDatabase());
// }
// }
// }
// return mDaoMaster;
// }

/**
* 获取DaoSession
*
* @param context
* @return
*/
public static DaoSession getDaoSession(Context context) {
if (null == mDaoSession) {
synchronized (DbManager.class) {
mDaoSession = getDaoMaster(context).newSession();
}
}
return mDaoSession;
}
}
SutdentDaoOpe类如下:
package com.koimy.greedaotest.db;

/**
* Created by hp on 2018/1/23.
*/

import android.content.Context;


import com.koimy.greedaotest.dao.StudentDao;
import com.koimy.greedaotest.entity.Student;

import org.greenrobot.greendao.query.QueryBuilder;

import java.util.List;


public class StudentDaoOpe {

/**
* 添加数据至数据库
*
* @param context
* @param stu
*/
public static void insertData(Context context, Student stu) {
DbManager.getDaoSession(context).getStudentDao().insert(stu);
}


/**
* 将数据实体通过事务添加至数据库
*
* @param context
* @param list
*/
public static void insertData(Context context, List<Student> list) {
if (null == list || list.size() <= 0) {
return;
}
DbManager.getDaoSession(context).getStudentDao().insertInTx(list);
}

/**
* 添加数据至数据库,如果存在,将原来的数据覆盖
* 内部代码判断了如果存在就update(entity);不存在就insert(entity);
*
* @param context
* @param student
*/
public static void saveData(Context context, Student student) {
DbManager.getDaoSession(context).getStudentDao().save(student);
}

/**
* 删除数据至数据库
*
* @param context
* @param student 删除具体内容
*/
public static void deleteData(Context context, Student student) {
DbManager.getDaoSession(context).getStudentDao().delete(student);
}

/**
* 根据id删除数据至数据库
*
* @param context
* @param id 删除具体内容
*/
public static void deleteByKeyData(Context context, long id) {
DbManager.getDaoSession(context).getStudentDao().deleteByKey(id);
}

/**
* 删除全部数据
*
* @param context
*/
public static void deleteAllData(Context context) {
DbManager.getDaoSession(context).getStudentDao().deleteAll();
}

/**
* 更新数据库
*
* @param context
* @param student
*/
public static void updateData(Context context, Student student) {
DbManager.getDaoSession(context).getStudentDao().update(student);
}


/**
* 查询所有数据
*
* @param context
* @return
*/
public static List<Student> queryAll(Context context) {
QueryBuilder<Student> builder = DbManager.getDaoSession(context).getStudentDao().queryBuilder();

return builder.build().list();
}



/**
* 分页加载
* @param context
* @param pageSize 当前第几页(程序中动态修改pageSize的值即可)
* @param pageNum 每页显示多少个
* @return
*/
public static List<Student> queryPaging( int pageSize, int pageNum,Context context){
StudentDao studentDao = DbManager.getDaoSession(context).getStudentDao();
List<Student> listMsg = studentDao.queryBuilder()
.offset(pageSize * pageNum).limit(pageNum).list();
return listMsg;
}
}

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.koimy.demo2.MainActivity">


<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="增" />

<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="删" />

<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="改" />

<Button
android:id="@+id/button4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查" />

<LinearLayout
android:layout_marginTop="20dp"
android:gravity="center"
android:layout_gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<Button
android:id="@+id/btn_query_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="根据ID查询(分页查询)" />

<Button
android:id="@+id/button5"
android:layout_width="107dp"
android:layout_height="wrap_content"
android:text="删除全部" />
</LinearLayout>

<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>

</LinearLayout>

MainActivithy.java
package com.koimy.greedaotest;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.koimy.greedaotest.db.StudentDaoOpe;
import com.koimy.greedaotest.entity.Student;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity {

@BindView(R.id.button)
Button button;
@BindView(R.id.button2)
Button button2;
@BindView(R.id.button3)
Button button3;
@BindView(R.id.button4)
Button button4;
@BindView(R.id.btn_query_all)
Button btnQueryAll;
@BindView(R.id.button5)
Button button5;
@BindView(R.id.tv_content)
TextView tvContent;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initData();
}

private List<Student> studentList = new ArrayList<>();

/**
* 初始化数据
*/
private void initData() {
for (int i = 0; i < 100; i++) {
Student student = new Student((long) i, "huang" + i, 25,"666"+i);
studentList.add(student);
}

}

int page;

@OnClick({R.id.button, R.id.button2, R.id.button3, R.id.button4, R.id.button5, R.id.btn_query_all})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.button:
StudentDaoOpe.insertData(this, studentList);
break;
case R.id.button2:
Student student = new Student((long) 5, "haung" + 5, 25,"123456");
/**
* 根据特定的对象删除
*/
StudentDaoOpe.deleteData(this, student);
/**
* 根据主键删除
*/
StudentDaoOpe.deleteByKeyData(this, 7);
StudentDaoOpe.deleteAllData(this);
break;
case R.id.button3:
student = new Student((long) 2, "caojin", 1314,"888888");
StudentDaoOpe.updateData(this, student);
break;
case R.id.button4:
List<Student> students = StudentDaoOpe.queryAll(this);
tvContent.setText(students.toString());
for (int i = 0; i < students.size(); i++) {
Log.i("Log", students.get(i).getName());
}

break;
case R.id.button5:
StudentDaoOpe.deleteAllData(this);
break;
case R.id.btn_query_all:
List<Student> students2 = StudentDaoOpe.queryPaging(page, 20, this);

if (students2.size() == 0) {
Toast.makeText(this, "没有更多数据了", Toast.LENGTH_SHORT).show();
}
for (Student st : students2) {
Log.e("TAG", "onViewClicked: ==" + st);
Log.e("TAG", "onViewClicked: == num = " + st.getNum());
}
page++;
tvContent.setText(students2.toString());
break;
}
}


}
最终在/data/data/包名/databases/数据库名/表名 生成的表结构如下所示:

下面讲一下数据库的升级:

首先新建一个helper包引入两个类,内容如下:

MigrationHelper类:

package com.koimy.greedaotest.helper;

/**
* 数据库更新辅助类
*
* 原理:创建临时表-->删除原表-->创建新表-->复制临时表数据到新表并删除临时表;这样数据库表的更新就完成了
*/

import android.database.Cursor;
import android.text.TextUtils;
import android.util.Log;


import com.koimy.greedaotest.dao.DaoMaster;

import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.internal.DaoConfig;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class MigrationHelper {

private static final String CONVERSION_CLASS_NOT_FOUND_EXCEPTION = "MIGRATION HELPER - CLASS DOESN'T MATCH WITH THE CURRENT PARAMETERS";
private static MigrationHelper instance;

public static MigrationHelper getInstance() {
if (instance == null) {
instance = new MigrationHelper();
}
return instance;
}

public void migrate(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {

generateTempTables(db, daoClasses);
DaoMaster.dropAllTables(db, true);
DaoMaster.createAllTables(db, false);
restoreData(db, daoClasses);
}

/**
* 生成临时列表
*
* @param db
* @param daoClasses
*/
private void generateTempTables(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
for (int i = 0; i < daoClasses.length; i++) {
DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);

String divider = "";
String tableName = daoConfig.tablename;
String tempTableName = daoConfig.tablename.concat("_TEMP");
ArrayList<String> properties = new ArrayList<>();

StringBuilder createTableStringBuilder = new StringBuilder();

createTableStringBuilder.append("CREATE TABLE ").append(tempTableName).append(" (");

for (int j = 0; j < daoConfig.properties.length; j++) {
String columnName = daoConfig.properties[j].columnName;

if (getColumns(db, tableName).contains(columnName)) {
properties.add(columnName);

String type = null;

try {
type = getTypeByClass(daoConfig.properties[j].type);
} catch (Exception exception) {
exception.printStackTrace();
}

createTableStringBuilder.append(divider).append(columnName).append(" ").append(type);

if (daoConfig.properties[j].primaryKey) {
createTableStringBuilder.append(" PRIMARY KEY");
}

divider = ",";
}
}
createTableStringBuilder.append(");");

db.execSQL(createTableStringBuilder.toString());

StringBuilder insertTableStringBuilder = new StringBuilder();

insertTableStringBuilder.append("INSERT INTO ").append(tempTableName).append(" (");
insertTableStringBuilder.append(TextUtils.join(",", properties));
insertTableStringBuilder.append(") SELECT ");
insertTableStringBuilder.append(TextUtils.join(",", properties));
insertTableStringBuilder.append(" FROM ").append(tableName).append(";");

db.execSQL(insertTableStringBuilder.toString());

}
}

/**
* 存储新的数据库表 以及数据
*
* @param db
* @param daoClasses
*/
private void restoreData(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
for (int i = 0; i < daoClasses.length; i++) {
DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
String tableName = daoConfig.tablename;
String tempTableName = daoConfig.tablename.concat("_TEMP");
ArrayList<String> properties = new ArrayList();

for (int j = 0; j < daoConfig.properties.length; j++) {
String columnName = daoConfig.properties[j].columnName;

if (getColumns(db, tempTableName).contains(columnName)) {
properties.add(columnName);
}
}

StringBuilder insertTableStringBuilder = new StringBuilder();

insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");
insertTableStringBuilder.append(TextUtils.join(",", properties));
insertTableStringBuilder.append(") SELECT ");
insertTableStringBuilder.append(TextUtils.join(",", properties));
insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");

StringBuilder dropTableStringBuilder = new StringBuilder();
dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);
db.execSQL(insertTableStringBuilder.toString());
db.execSQL(dropTableStringBuilder.toString());
}
}

private String getTypeByClass(Class<?> type) throws Exception {
if (type.equals(String.class)) {
return "TEXT";
}
if (type.equals(Long.class) || type.equals(Integer.class) || type.equals(long.class)) {
return "INTEGER";
}
if (type.equals(Boolean.class)) {
return "BOOLEAN";
}

Exception exception = new Exception(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(" - Class: ").concat(type.toString()));
exception.printStackTrace();
throw exception;
}

private List<String> getColumns(Database db, String tableName) {
List<String> columns = new ArrayList<>();
Cursor cursor = null;
try {
cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 1", null);
if (cursor != null) {
columns = new ArrayList<>(Arrays.asList(cursor.getColumnNames()));
}
} catch (Exception e) {
Log.v(tableName, e.getMessage(), e);
e.printStackTrace();
} finally {
if (cursor != null)
cursor.close();
}
return columns;
}
}
MyOpenHelper类:

package com.koimy.greedaotest.helper;

/**
* Created by hp on 2018/1/23.
*/

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;


import com.koimy.greedaotest.dao.DaoMaster;
import com.koimy.greedaotest.dao.StudentDao;

import org.greenrobot.greendao.database.Database;


public class MyOpenHelper extends DaoMaster.OpenHelper {

public MyOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}

/**
* 数据库升级
* @param db
* @param oldVersion
* @param newVersion
*/
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
//操作数据库的更新 有几个表升级都可以传入到下面

Log.i("version", oldVersion + "---先前和更新之后的版本---" + newVersion);
if (oldVersion < newVersion) {
Log.i("version", oldVersion + "---先前和更新之后的版本---" + newVersion);
MigrationHelper.getInstance().migrate(db, StudentDao.class);
//更改过的实体类(新增的不用加) 更新UserDao文件 可以添加多个 XXDao.class 文件
// MigrationHelper.getInstance().migrate(db, UserDao.class,XXDao.class);
}



//MigrationHelper.getInstance().migrate(db,StudentDao.class);
}

}
然后将
/**
* 获取DaoMaster
*
* @param context
* @return
*/
public static DaoMaster getDaoMaster(Context context) {
if (null == mDaoMaster) {
synchronized (DbManager.class) {
if (null == mDaoMaster) {
mDaoMaster = new DaoMaster(getWritableDatabase(context));
}
}
}
return mDaoMaster;
}
换成如下所示:

/**
* 获取DaoMaster
*
* 判断是否存在数据库,如果没有则创建数据库
* @param context
* @return
*/
public static DaoMaster getDaoMaster(Context context) {
if (null == mDaoMaster) {
synchronized (DbManager.class) {
if (null == mDaoMaster) {
MyOpenHelper helper = new MyOpenHelper(context,DB_NAME,null);
mDaoMaster = new DaoMaster(helper.getWritableDatabase());
}
}
}
return mDaoMaster;
}
接下来:我们在Student类里面添加一个 属性 grade属性,然后将build.gradle里面schemaVersion改为 2

然后编译,运行一下程序,然后我们再来看升级后的数据库,如下图所示成功添加了我么新增的字段,还保留了以前的数据

GreenDao3.2使用详解(增,删,改,查,升级)的更多相关文章

  1. 好用的SQL TVP~~独家赠送[增-删-改-查]的例子

    以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化.  本系列主要是针对T-SQL的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础] ...

  2. iOS FMDB的使用(增,删,改,查,sqlite存取图片)

    iOS FMDB的使用(增,删,改,查,sqlite存取图片) 在上一篇博客我对sqlite的基本使用进行了详细介绍... 但是在实际开发中原生使用的频率是很少的... 这篇博客我将会较全面的介绍FM ...

  3. iOS sqlite3 的基本使用(增 删 改 查)

    iOS sqlite3 的基本使用(增 删 改 查) 这篇博客不会讲述太多sql语言,目的重在实现sqlite3的一些基本操作. 例:增 删 改 查 如果想了解更多的sql语言可以利用强大的互联网. ...

  4. django ajax增 删 改 查

    具于django ajax实现增 删 改 查功能 代码示例: 代码: urls.py from django.conf.urls import url from django.contrib impo ...

  5. ADO.NET 增 删 改 查

    ADO.NET:(数据访问技术)就是将C#和MSSQL连接起来的一个纽带 可以通过ADO.NET将内存中的临时数据写入到数据库中 也可以将数据库中的数据提取到内存中供程序调用 ADO.NET所有数据访 ...

  6. MVC EF 增 删 改 查

    using System;using System.Collections.Generic;using System.Linq;using System.Web;//using System.Data ...

  7. python基础中的四大天王-增-删-改-查

    列表-list-[] 输入内存储存容器 发生改变通常直接变化,让我们看看下面列子 增---默认在最后添加 #append()--括号中可以是数字,可以是字符串,可以是元祖,可以是集合,可以是字典 #l ...

  8. 简单的php数据库操作类代码(增,删,改,查)

    这几天准备重新学习,梳理一下知识体系,同时按照功能模块划分做一些东西.所以.mysql的操作成为第一个要点.我写了一个简单的mysql操作类,实现数据的简单的增删改查功能. 数据库操纵基本流程为: 1 ...

  9. MongoDB增 删 改 查

    增 增加单篇文档 > db.stu.insert({sn:'001', name:'lisi'}) WriteResult({ "nInserted" : 1 }) > ...

  10. Go语言之进阶篇mysql增 删 改 查

    一.mysql操作基本语法 1.创建名称nulige的数据库 CREATE DATABASE nulige DEFAULT CHARSET utf8 COLLATE utf8_general_ci; ...

随机推荐

  1. windows 命令行 cmd 控制exe程序输入输出并比较

    参考 https://www.cnblogs.com/zccz14/p/4588634.html 例子: 对exe输入输出 使用fc比较不同

  2. Sentry 中文版

    Sentry 中文版 汉化 https://sentry.io/settings/account/details/ 打开用户设置 User settings 语言选择中文 Simplified Chi ...

  3. TypeScript Errors All In One

    TypeScript Errors All In One 1. Property 'name' has no initializer and is not definitely assigned in ...

  4. Azure & FaaS in Action

    Azure & FaaS in Action VSCode & Azure azure tenant select subscription Cloud Shell https://a ...

  5. Google can't be accessed again, today is shit day

    Google can't be accessed again, today is shit day 2019.11.28 12:00~20:56 holy shit (pile of poop) Go ...

  6. css icons fontawesome-free

    官网 examples v4.7.0 cdnjs icons basic-use 安装 λ npm install --save @fortawesome/fontawesome-free fa前缀在 ...

  7. django学习-1.开始hello world!

    1.前言 当你想走上测试开发之路,用python开发出一个web页面的时候,需要找一个支持python语言的web框架.django框架有丰富的文档和学习资料,也是非常成熟的web开发框架,想学pyt ...

  8. Error: Actions must be plain objects. Use custom middleware for async actions.

    原本代码: import { SREACH_FOCUS, SREACH_BLUR } from "./actionType" export const searchFocus = ...

  9. token、cookie和session区别以及django中的cookie,csrf

    参考:https://my.oschina.net/xianggao/blog/395675?fromerr=GC9KVenE [前言]登录时需要post的表单信息. 先跳过具体案例,讲解基础知识: ...

  10. POJ-2253(最短路变形+dijikstra算法+求解所有路径中所有最长边中的一个最小值)

    frogger POJ-2253 这题的代码特别像prim求解最小生成树的代码,其实两者本来也很像. 这里的d数组不再维护的起点到该点的最短距离了,而是路径中的最长距离. #include<io ...