1,配置
参考官方文档: https://github.com/greenrobot/greenDAO
// In your root build.gradle file:
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
}
}
// In your app projects build.gradle file:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin
/*针对greenDao的一些配置*/
greendao {
schemaVersion 1 //数据库版本号,迁移,升级数据库要增加版本号
daoPackage 'study.sll.com.bean.gen' //自动生成的工具类的包名,默认是entity所在的包
targetGenDir 'src/main/java' //路径,自定义生成数据库文件的目录
}
dependencies {
compile 'org.greenrobot:greendao:3.2.2' // add library
}
2. 编写实体类
@Entity
public class UserBean {
@Id
private Long id;
private String name;
private int age;
}
注:
@Entity:将我们的java普通类变为一个能够被greenDAO识别的数据库类型的实体类
@Id:通过这个注解标记的字段必须是Long类型的,这个字段在数据库中表示它就是主键,并且它默认就是自增的
3.Make Project
点击 Build --> Make Project,,
GreenDao会自动创建gen包,里面是自动生成的DaoMaster,DaoSession 和UserBeanDao
实体类里面发生如下变化:
4. 初始化数据库
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(MyApplication.getContext(), "name-db", null);
DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
DaoSession daoSession = daoMaster.newSession();
UserBeanDao userBeanDao = daoSession.getUserBeanDao();
name-db是数据库的名字。
获取dao对像操作数据库, 可以放到application中初始化
5. 操作数据库
- 5.1 增加
增加一条数据
UserBean userBean = new UserBean(null,"张三",18); userBeanDao.insert(userBean);
- 5.2 修改
名字修改为李四
UserBean user = userBeanDao.queryBuilder().where(UserBeanDao.Properties.Age.eq(18)).build().unique(); if (user != null) { user.setName("李四"); userBeanDao.update(user); LogUtils.loge("修改成功"); } else { LogUtils.loge("用户不存在"); }
- 5.3 删除
删除姓名为李四的
UserBean userBean1 = userBeanDao.queryBuilder().where(UserBeanDao.Properties.Name.eq("李四")).build().unique(); if (userBean1!= null){ userBeanDao.deleteByKey(userBean1.getId()); }
- 5.4 查询
查询姓名为张三的用户. limit限制查询的条目数为3,list()指定返回的为集合
List
userBeanList = userBeanDao.queryBuilder().where(UserBeanDao.Properties.Name.eq("张三")).limit(3).build().list(); if (userBeanList == null || userBeanList.size() == 0){ LogUtils.loge("查询的用户不存在"); }else{ ......... }
- where() 表示查询条件,可以有多个条件,list表示查询结果是一个集合,如果想查询一条数据,使用unique() :
userBeanDao.queryBuilder().where(UserBeanDao.Properties.Name.eq("张三")).limit(3).build().unique() - eq() 是等于
- le() 小于等于
- ge() 大于等于
6. 简单封装
-
6.1 在application的oncreate方法中调用setupDatabase()方法初始化
MySQLiteOpenHelper代码:
其中MigrationHelper是为了解决升级数据库数据丢失,代码放到最后.
- 6.2 最后简单封装成一个工具类GreenDaoManager:
` public class GreenDaoManager {
private static GreenDaoManager instance;
private static UserBeanDao userBeanDao;
private GreenDaoManager() {
}
public static GreenDaoManager getInstance() {
if (instance == null) {
synchronized (GreenDaoManager.class) {
if (instance == null) {
instance = new GreenDaoManager();
}
}
}
userBeanDao = AppApplication.getDaoInstant().getUserBeanDao();
return instance;
}
/**
* 根据用户id,取出用户信息
*
* @param id 用户id
* @return 用户信息
*/
public UserBean loadUser(long id) {
if (!TextUtils.isEmpty(id + "")) {
return userBeanDao.load(id);
}
return null;
}
/**
* 根据name,取出用户信息
*
* @return 用户信息
*/
public static List queryLove(String name) {
return userBeanDao.queryBuilder().where(UserBeanDao.Properties.Name.eq(name)).list();
}
}
- 6.3 调用
UserBean userBean = GreenDaoManager.getInstance().loadUser(1);
MigrationHelper代码:
/** greendao数据库更新帮助类
- 可以参考 github:https://github.com/yuweiguocn/GreenDaoUpgradeHelper
- 参考用法: https://github.com/WJKCharlie/GreenDaoExample
- please call {@link #migrate(SQLiteDatabase, Class[])} or {@link #migrate(Database,
Class[])}
*/
`public final class MigrationHelper {
public static boolean DEBUG = false;
private static String TAG = "MigrationHelper";
private static final String SQLITE_MASTER = "sqlite_master";
private static final String SQLITE_TEMP_MASTER = "sqlite_temp_master";
private static WeakReference weakListener;
public interface ReCreateAllTableListener {
void onCreateAllTables(Database db, boolean ifNotExists);
void onDropAllTables(Database db, boolean ifExists);
}
public static void migrate(SQLiteDatabase db, Class extends AbstractDao, ?>>... daoClasses) {
printLog("【The Old Database Version】" + db.getVersion());
Database database = new StandardDatabase(db);
migrate(database, daoClasses);
}
public static void migrate(SQLiteDatabase db, ReCreateAllTableListener listener, Class extends AbstractDao, ?>>... daoClasses) {
weakListener = new WeakReference<>(listener);
migrate(db, daoClasses);
}
public static void migrate(Database database, ReCreateAllTableListener listener, Class extends AbstractDao, ?>>... daoClasses) {
weakListener = new WeakReference<>(listener);
migrate(database, daoClasses);
}
public static void migrate(Database database, Class extends AbstractDao, ?>>... daoClasses) {
printLog("【Generate temp table】start");
generateTempTables(database, daoClasses);
printLog("【Generate temp table】complete");
ReCreateAllTableListener listener = weakListener.get();
if (listener != null) {
listener.onDropAllTables(database, true);
printLog("【Drop all table by listener】");
listener.onCreateAllTables(database, false);
printLog("【Create all table by listener】");
} else {
dropAllTables(database, true, daoClasses);
createAllTables(database, false, daoClasses);
}
printLog("【Restore data】start");
restoreData(database, daoClasses);
printLog("【Restore data】complete");
}
private static void generateTempTables(Database db, Class extends AbstractDao, ?>>... daoClasses) {
for (int i = 0; i < daoClasses.length; i++) {
String tempTableName = null;
DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
String tableName = daoConfig.tablename;
if (!isTableExists(db, false, tableName)) {
printLog("【New Table】" + tableName);
continue;
}
try {
tempTableName = daoConfig.tablename.concat("_TEMP");
StringBuilder dropTableStringBuilder = new StringBuilder();
dropTableStringBuilder.append("DROP TABLE IF EXISTS ").append(tempTableName).append(";");
db.execSQL(dropTableStringBuilder.toString());
StringBuilder insertTableStringBuilder = new StringBuilder();
insertTableStringBuilder.append("CREATE TEMPORARY TABLE ").append(tempTableName);
insertTableStringBuilder.append(" AS SELECT * FROM ").append(tableName).append(";");
db.execSQL(insertTableStringBuilder.toString());
printLog("【Table】" + tableName + "\n ---Columns-->" + getColumnsStr(daoConfig));
printLog("【Generate temp table】" + tempTableName);
} catch (SQLException e) {
Log.e(TAG, "【Failed to generate temp table】" + tempTableName, e);
}
}
}
private static boolean isTableExists(Database db, boolean isTemp, String tableName) {
if (db == null || TextUtils.isEmpty(tableName)) {
return false;
}
String dbName = isTemp ? SQLITE_TEMP_MASTER : SQLITE_MASTER;
String sql = "SELECT COUNT(*) FROM " + dbName + " WHERE type = ? AND name = ?";
Cursor cursor = null;
int count = 0;
try {
cursor = db.rawQuery(sql, new String[]{"table", tableName});
if (cursor == null || !cursor.moveToFirst()) {
return false;
}
count = cursor.getInt(0);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null)
cursor.close();
}
return count > 0;
}
private static String getColumnsStr(DaoConfig daoConfig) {
if (daoConfig == null) {
return "no columns";
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < daoConfig.allColumns.length; i++) {
builder.append(daoConfig.allColumns[i]);
builder.append(",");
}
if (builder.length() > 0) {
builder.deleteCharAt(builder.length() - 1);
}
return builder.toString();
}
private static void dropAllTables(Database db, boolean ifExists, @NonNull Class extends AbstractDao, ?>>... daoClasses) {
reflectMethod(db, "dropTable", ifExists, daoClasses);
printLog("【Drop all table by reflect】");
}
private static void createAllTables(Database db, boolean ifNotExists, @NonNull Class extends AbstractDao, ?>>... daoClasses) {
reflectMethod(db, "createTable", ifNotExists, daoClasses);
printLog("【Create all table by reflect】");
}
/**
* dao class already define the sql exec method, so just invoke it
*/
private static void reflectMethod(Database db, String methodName, boolean isExists, @NonNull Class extends AbstractDao, ?>>... daoClasses) {
if (daoClasses.length < 1) {
return;
}
try {
for (Class cls : daoClasses) {
Method method = cls.getDeclaredMethod(methodName, Database.class, boolean.class);
method.invoke(null, db, isExists);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
private static 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");
if (!isTableExists(db, true, tempTableName)) {
continue;
}
try {
// get all columns from tempTable, take careful to use the columns list
List columns = getColumns(db, tempTableName);
ArrayList properties = new ArrayList<>(columns.size());
for (int j = 0; j < daoConfig.properties.length; j++) {
String columnName = daoConfig.properties[j].columnName;
if (columns.contains(columnName)) {
properties.add("`" + columnName + "`");
}
}
if (properties.size() > 0) {
final String columnSQL = TextUtils.join(",", properties);
StringBuilder insertTableStringBuilder = new StringBuilder();
insertTableStringBuilder.append("REPLACE INTO ").append(tableName).append(" (");
insertTableStringBuilder.append(columnSQL);
insertTableStringBuilder.append(") SELECT ");
insertTableStringBuilder.append(columnSQL);
insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");
db.execSQL(insertTableStringBuilder.toString());
printLog("【Restore data】 to " + tableName);
}
StringBuilder dropTableStringBuilder = new StringBuilder();
dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);
db.execSQL(dropTableStringBuilder.toString());
printLog("【Drop temp table】" + tempTableName);
} catch (SQLException e) {
Log.e(TAG, "【Failed to restore data from temp table 】" + tempTableName, e);
}
}
}
private static List getColumns(Database db, String tableName) {
List columns = null;
Cursor cursor = null;
try {
cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 0", null);
if (null != cursor && cursor.getColumnCount() > 0) {
columns = Arrays.asList(cursor.getColumnNames());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null)
cursor.close();
if (null == columns)
columns = new ArrayList<>();
}
return columns;
}
private static void printLog(String info) {
if (DEBUG) {
Log.d(TAG, info);
}
}
}`
本文有任何问题欢迎指正。