运行效果图:
GreenDao的配置(AS):
第一步:在build中添加配置如下:
projet 目录下的build.gradle
[html] view plain copy
- dependencies {
- classpath 'org.greenrobot:greendao-gradle-plugin:3.2.0'
- }
moudle 下的build.gradle添加如下内容:
[html] view plain copy
- apply plugin: 'org.greenrobot.greendao'
- dependencies {
- .....................
- compile 'org.greenrobot:greendao:3.2.0'
- }
添加完成之后点击sync一下工程
第二步:
首先在moudle下 build.gradle的根目录下添加如下配置
[html] view plain copy
-
apply plugin: 'org.greenrobot.greendao'
- greendao {
- //数据库的schema版本,也可以理解为数据库版本号
- schemaVersion 1
- //设置DaoMaster、DaoSession、Dao包名,也就是要放置这些类的包的全路径。
- daoPackage 'com.koimy.greedaotest.dao'
- //设置DaoMaster、DaoSession、Dao目录
- targetGenDir 'src/main/java'
- }
在项目里面添加实体类Student如下所示:
然后点击 android studio 的 build-->make project
此时项目结构如下(会自动生成一个dao包):
StudentBean 类里面的内容发生了变化如下:
GreenDao帮助我们自动生成了一些get和set方法,以及构造方法
第三步:为了方便使用我们添加了一个 db包
DbManager类如下:
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import com.koimy.greedaotest.dao.DaoMaster;
import com.koimy.greedaotest.dao.DaoSession;
/**
* CDbManager
*/
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;
}
/**
* 获取DaoSession
*
* @param context
* @return
*/
public static DaoSession getDaoSession(Context context) {
if (null == mDaoSession) {
synchronized (DbManager.class) {
mDaoSession = getDaoMaster(context).newSession();
}
}
return mDaoSession;
}
}
SutdentDaoOpe类如下:
import android.content.Context;
import com.koimy.greedaotest.dao.StudentBeanDao;
import com.rock.administrator.greendao.StudentBean;
import org.greenrobot.greendao.query.QueryBuilder;
import java.util.List;
/**
* Created by Administrator on 2018/4/1 0001.
*/
public class SutdentDaoOpe {
/**
* 添加数据至数据库
*
* @param context
* @param stu
*/
public static void insertData(Context context, StudentBean stu) {
DbManager.getDaoSession(context).getStudentBeanDao().insert(stu);
}
/**
* 将数据实体通过事务添加至数据库
*
* @param context
* @param list
*/
public static void insertData(Context context, List<StudentBean> list) {
if (null == list || list.size() <= 0) {
return;
}
DbManager.getDaoSession(context).getStudentBeanDao().insertInTx(list);
}
/**
* 添加数据至数据库,如果存在,将原来的数据覆盖
* 内部代码判断了如果存在就update(entity);不存在就insert(entity);
*
* @param context
* @param StudentBean
*/
public static void saveData(Context context, StudentBean StudentBean) {
DbManager.getDaoSession(context).getStudentBeanDao().save(StudentBean);
}
/**
* 删除数据至数据库
*
* @param context
* @param StudentBean 删除具体内容
*/
public static void deleteData(Context context, StudentBean StudentBean) {
DbManager.getDaoSession(context).getStudentBeanDao().delete(StudentBean);
}
/**
* 根据id删除数据至数据库
*
* @param context
* @param id 删除具体内容
*/
public static void deleteByKeyData(Context context, long id) {
DbManager.getDaoSession(context).getStudentBeanDao().deleteByKey(id);
}
/**
* 删除全部数据
*
* @param context
*/
public static void deleteAllData(Context context) {
DbManager.getDaoSession(context).getStudentBeanDao().deleteAll();
}
/**
* 更新数据库
*
* @param context
* @param StudentBean
*/
public static void updateData(Context context, StudentBean StudentBean) {
DbManager.getDaoSession(context).getStudentBeanDao().update(StudentBean);
}
/**
* 查询所有数据
*
* @param context
* @return
*/
public static List<StudentBean> queryAll(Context context) {
QueryBuilder<StudentBean> builder = DbManager.getDaoSession(context).getStudentBeanDao().queryBuilder();
return builder.build().list();
}
/**
* 分页加载
* @param context
* @param pageSize 当前第几页(程序中动态修改pageSize的值即可)
* @param pageNum 每页显示多少个
* @return
*/
public static List<StudentBean> queryPaging( int pageSize, int pageNum,Context context){
StudentBeanDao StudentBeanDao = DbManager.getDaoSession(context).getStudentBeanDao();
List<StudentBean> listMsg = StudentBeanDao.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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_margin="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="id : "
android:layout_marginRight="5dp"
android:textSize="16sp"/>
<EditText
android:id="@+id/et_id"
android:layout_width="0dp"
android:layout_weight="2.5"
android:layout_height="wrap_content"
android:textSize="16sp"
android:inputType="number"
android:hint="输入id"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="name : "
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:textSize="16sp"/>
<EditText
android:id="@+id/et_name"
android:layout_width="0dp"
android:layout_weight="2.5"
android:layout_height="wrap_content"
android:textSize="16sp"
android:hint="输入name"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_margin="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="age : "
android:layout_marginRight="5dp"
android:textSize="16sp"/>
<EditText
android:id="@+id/et_age"
android:layout_width="0dp"
android:layout_weight="2.5"
android:layout_height="wrap_content"
android:textSize="16sp"
android:inputType="number"
android:hint="输入age"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="num : "
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:textSize="16sp"/>
<EditText
android:id="@+id/et_num"
android:layout_width="0dp"
android:layout_weight="2.5"
android:layout_height="wrap_content"
android:textSize="16sp"
android:hint="输入num"/>
</LinearLayout>
<Button
android:id="@+id/btnAdd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="增"/>
<Button
android:id="@+id/btnDel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="删"/>
<Button
android:id="@+id/btnUpd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="改"/>
<Button
android:id="@+id/btnSel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查"/>
<EditText
android:id="@+id/et_show"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MainActivithy.java
package com.rock.administrator.greendao;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.db.SutdentDaoOpe;
import com.koimy.greedaotest.dao.StudentBeanDao;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText et_id, et_name, et_age, et_num, et_show;
private Button btnAdd, btnDel, btnUpd, btnSel;
private int getID;
private String getName;
private int getAge;
private String getNum;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
et_id = (EditText) findViewById(R.id.et_id);
et_name = (EditText) findViewById(R.id.et_name);
et_age = (EditText) findViewById(R.id.et_age);
et_num = (EditText) findViewById(R.id.et_num);
et_show = (EditText) findViewById(R.id.et_show);
btnAdd = (Button) findViewById(R.id.btnAdd);
btnDel = (Button) findViewById(R.id.btnDel);
btnUpd = (Button) findViewById(R.id.btnUpd);
btnSel = (Button) findViewById(R.id.btnSel);
btnAdd.setOnClickListener(this);
btnDel.setOnClickListener(this);
btnUpd.setOnClickListener(this);
btnSel.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//增
case R.id.btnAdd:
getDate();
StudentBean sBean = new StudentBean((long) getID, getName, getAge, getNum);
SutdentDaoOpe.insertData(this, sBean);
break;
//删
case R.id.btnDel:
int getID2 = Integer.valueOf(et_id.getText().toString().trim());
SutdentDaoOpe.deleteByKeyData(this, getID2);
break;
//改
case R.id.btnUpd:
getDate();
StudentBean upBean = new StudentBean((long) getID, getName, getAge, getNum);
SutdentDaoOpe.updateData(this, upBean);
break;
//查
case R.id.btnSel:
List<StudentBean> student = SutdentDaoOpe.queryAll(this);
if (student.size() == 0) {
et_show.setText("数据库没有数据!");
} else {
//创建一个list,用来收集一组数据
ArrayList list1 = new ArrayList();
for (int i = 0; i < student.size(); i++) {
list1.add(" [");
list1.add(student.get(i).getId());
list1.add(student.get(i).getName());
list1.add(student.get(i).getAge());
list1.add(student.get(i).getNum());
list1.add("] ");
}
et_show.setText(list1.toString());
}
break;
}
}
/*
优化获取editText数据的重复代码
*/
private void getDate() {
getID = Integer.valueOf(et_id.getText().toString().trim());
getName = et_name.getText().toString().trim();
getAge = Integer.valueOf(et_age.getText().toString().trim());
getNum = et_num.getText().toString().trim();
}
}
数据库的升级:
首先新建一个helper包引入两个类,内容如下:
MigrationHelper类:
package com.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.helper;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import com.koimy.greedaotest.dao.DaoMaster;
import com.koimy.greedaotest.dao.StudentBeanDao;
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);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
super.onUpgrade(db, oldVersion, newVersion);
Log.i("version", oldVersion + "---先前和更新之后的版本---" + newVersion);
if (oldVersion < newVersion) {
Log.i("version", oldVersion + "---先前和更新之后的版本---" + newVersion);
MigrationHelper.getInstance().migrate(db, StudentBeanDao.class);
//更改过的实体类(新增的不用加) 更新UserDao文件 可以添加多个 XXDao.class 文件
// MigrationHelper.getInstance().migrate(db, UserDao.class,XXDao.class);
}
}
}
注:有两个onUpgrade,这里使用的是DataBase,不是SQLiteDatabase。
然后将
[html] view plain copy
- /**
- * 获取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;
- }
换成如下所示:
[html] view plain copy
- /**
- * 获取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;
- }
注:这里有getDaoMaster和getDaoSessin,修改的是getDaoMaster。
接下来:我们在Student类里面添加一个 属性 grade属性,然后将build.gradle里面schemaVersion改为 2
然后编译,运行一下程序,就OK了。
参考:https://blog.csdn.net/wzgbgz/article/details/79140056