GreenDao3.2使用详解(增,删,改,查,升级)
首先看一下效果图:
项目结构如下图所示:
第一步:在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使用详解(增,删,改,查,升级)的更多相关文章
- 好用的SQL TVP~~独家赠送[增-删-改-查]的例子
以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化. 本系列主要是针对T-SQL的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础] ...
- iOS FMDB的使用(增,删,改,查,sqlite存取图片)
iOS FMDB的使用(增,删,改,查,sqlite存取图片) 在上一篇博客我对sqlite的基本使用进行了详细介绍... 但是在实际开发中原生使用的频率是很少的... 这篇博客我将会较全面的介绍FM ...
- iOS sqlite3 的基本使用(增 删 改 查)
iOS sqlite3 的基本使用(增 删 改 查) 这篇博客不会讲述太多sql语言,目的重在实现sqlite3的一些基本操作. 例:增 删 改 查 如果想了解更多的sql语言可以利用强大的互联网. ...
- django ajax增 删 改 查
具于django ajax实现增 删 改 查功能 代码示例: 代码: urls.py from django.conf.urls import url from django.contrib impo ...
- ADO.NET 增 删 改 查
ADO.NET:(数据访问技术)就是将C#和MSSQL连接起来的一个纽带 可以通过ADO.NET将内存中的临时数据写入到数据库中 也可以将数据库中的数据提取到内存中供程序调用 ADO.NET所有数据访 ...
- MVC EF 增 删 改 查
using System;using System.Collections.Generic;using System.Linq;using System.Web;//using System.Data ...
- python基础中的四大天王-增-删-改-查
列表-list-[] 输入内存储存容器 发生改变通常直接变化,让我们看看下面列子 增---默认在最后添加 #append()--括号中可以是数字,可以是字符串,可以是元祖,可以是集合,可以是字典 #l ...
- 简单的php数据库操作类代码(增,删,改,查)
这几天准备重新学习,梳理一下知识体系,同时按照功能模块划分做一些东西.所以.mysql的操作成为第一个要点.我写了一个简单的mysql操作类,实现数据的简单的增删改查功能. 数据库操纵基本流程为: 1 ...
- MongoDB增 删 改 查
增 增加单篇文档 > db.stu.insert({sn:'001', name:'lisi'}) WriteResult({ "nInserted" : 1 }) > ...
- Go语言之进阶篇mysql增 删 改 查
一.mysql操作基本语法 1.创建名称nulige的数据库 CREATE DATABASE nulige DEFAULT CHARSET utf8 COLLATE utf8_general_ci; ...
随机推荐
- MYSQL基础常见常用语句200条
数据库 # 查看所有的数据库 SHOW DATABASES ; # 创建一个数据库 CREATE DATABASE k; # 删除一个数据库 DROP DATABASE k; # 使用这个数据库 US ...
- cs实时系统之网关设计
今天给大家讲一下client-server系统(cs)设计,基本结构 1.client 客户端,插件式开发,负责对应ui的展示 2.gateway 网关层,管理客户端通信连接,负载后端集群服务 3.s ...
- 2021-2-18:请你说说MySQL的字符集与排序规则对开发有哪些影响?
任何计算机存储数据,都需要字符集,因为计算机存储的数据其实都是二进制编码,将一个个字符,映射到对应的二进制编码的这个映射就是字符编码(字符集).这些字符如何排序呢?决定字符排序的规则就是排序规则. 查 ...
- Windows 10 & git & bash
Windows 10 & git & bash If you are on Windows, we recommend downloading Git for Windows and ...
- console.clear
console.clear Chrome console.clear && console.clear() refs xgqfrms 2012-2020 www.cnblogs.com ...
- js script all in one
js script all in one 你不知道的 js secret https://html.spec.whatwg.org/multipage/scripting.html https://h ...
- 比特币市场活跃,VAST发行在即!
截至1月25日13:30,BTC合约多空持仓人数比为1.44,市场做多人数占据优势:季度合约基差保持在1255美元上方,永续合约资金费率为正,交割及永续合约持仓总量为19.5亿美元,总体上多军占优:B ...
- CURTIS SAVANAH:数字经济=智能基础设施+海量数据+新生业态
前不久,Datahero Inc公司(公司编号:20141166945)创始人CURTIS SAVANAH在会议上表示,要构建数字经济的愿景,需要智能基础设施.海量数据和全新新生业态. 他在演讲中说到 ...
- NGK全球启动大会圆满召开,一起预见区块链的美好未来!
NGK Global全球启动大会在高新技术产业区硅谷于美国当地时间11月25日圆满召开!这次会议邀请了星盟高管.NGK全球各大市场领导人.NGK生态产业代表等上百位嘉宾出席,此次会议持续了一个多小时, ...
- Azure Functions(二)集成 Azure Blob Storage 存储文件
一,引言 上一篇文章有介绍到什么是 SeverLess ,ServerLess 都有哪些特点,以及多云环境下 ServerLess 都有哪些解决方案.在这众多解决方案中就包括 Function App ...