您的位置:首页 > 其它

GreenDao框架使用教程

2016-04-28 16:27 344 查看
github地址:https://github.com/greenrobot/greenDAO

1、首先建立一个java工程的Generator,注意是java工程不是android工程。导入freemaker.jar和greendao-generator.jar,加入到build path。建一个如下的类:

package com.luckchoudog.greendao;

import de.greenrobot.daogenerator.DaoGenerator;
import de.greenrobot.daogenerator.Entity;
import de.greenrobot.daogenerator.Schema;

/**
* 此工程为java工程,需要依赖库freemarker和greendao-generator两个类库
*
* @author luckchoudog
*/
public class MyDaoGenerator {
public static void main(String[] args) throws Exception {
Schema schema = new Schema(1, "com.example.greendao.db");// 生成文件的目录,代码中第一行package的目录,将此修改为自己项目目录
addTest(schema);
addTest2(schema);
addTest3(schema);
new DaoGenerator().generateAll(schema, "../DaoGenerator/java-gen");// 将文件生成在java-gen文件夹下
}

private static void addTest(Schema schema) {
Entity testData = schema.addEntity("TestData");//名称
testData.addIdProperty().primaryKey().autoincrement();//主键
testData.addStringProperty("testString");
testData.addLongProperty("testLong");
testData.addDateProperty("testDate");
testData.addIntProperty("testInt");
testData.addBooleanProperty("testBoolean");
}

private static void addTest2(Schema schema) {
Entity testData = schema.addEntity("TestData2");
testData.addIdProperty().primaryKey().autoincrement();
testData.addStringProperty("testString");
testData.addLongProperty("testLong");
testData.addDateProperty("testDate");
testData.addIntProperty("testInt");
testData.addBooleanProperty("testBoolean");
}

private static void addTest3(Schema schema) {
Entity testData = schema.addEntity("TestData3");
testData.addIdProperty().primaryKey().autoincrement();
testData.addStringProperty("testString");
testData.addLongProperty("testLong");
testData.addDateProperty("testDate");
testData.addIntProperty("testInt");
testData.addBooleanProperty("testBoolean");
}
}
这里注意下这两个方法:

(1)Schema schema = new Schema(1, "com.example.greendao.db");//第一个参数是数据库的版本号, 第二个参数是生成文件的目录,代码中第一行package的目录,将此修改为自己项目目录

(2)new DaoGenerator().generateAll(schema, "../DaoGenerator/java-gen");// 第二个参数是将文件生成在java-gen文件夹下,必须保证java-gen文件夹已经存在

运行这个类,然后在控制台出现以下信息:



自动生成model和dao,大家也可以看看目录结构,感受下new DaoGenerator().generateAll(schema, "../DaoGenerator/java-gen")第二个参数



2、将上边的生成的文件复制到自己的工程中,dao类中也有各种基本的方法,如insert,update,delete等等。基本可能完成大部分需求了,终于不用写那么繁琐的数据库操作啦!

再看看怎么在client获取到dao,注意client要加入greendao.jar。有了dao就可以对数据库各种操作了!

UpgradeHelper helper = new UpgradeHelper(this, "test.db",
null);
daoMaster = new DaoMaster(helper.getWritableDatabase());
daoSession = daoMaster.newSession();
mTestData = daoSession.getTestData();
毕竟GreenDao是ORM框架,用起来那也是相当的爽啦这里就不再多说了,接下来说下数据库的更新这块

3、greendao虽然有update等方法,但是在实际当中,程序进行升级,数据库也升级,官方的方法是删除旧的,然后再建立新的数据库表,那原来的数据会都删除,这点比较坑,网上也有好多方法,我在这里整理了一下,比较传统NB的,接下来咱们单独说说数据库升级这块,请继续看

(1)首先为了以后管理方便,先创建一个抽象类

/**
* 数据库升级抽象类
*
* @author luckchoudog
*/
public abstract class AbstractMigratorHelper {
public abstract void onUpgrade(SQLiteDatabase db);
}
(2)自己在程序中写逻辑类,先继承AbstractMigratorHelper,比如说从第一版到第二版,如果有 TestData2Dao和TestDataDao两个数据库表修改了,需要把原来的数据先存储下,然后删除旧数据表,建立新数据库表,再将存储下来的数据放到新的数据库表中。

/**
* DBMigrationHelper后边的数字代表着数据库如果升级,前一版本需要修改的有啥,例如DBMigrationHelper1,数据库从1升级到2,
* 那么数据库版本是1的需要有啥啥修改
*
* @author LuckChouDog
*
*/
public class DBMigrationHelper1 extends AbstractMigratorHelper {
/*
* Upgrade from DB schema 1 to schema 2 , version numbers are just examples
*/
public void onUpgrade(SQLiteDatabase db) {
MigrationHelper.getInstance().migrate(db, TestData2Dao.class, TestDataDao.class);
}
}

(3)接下来咱们写个工具类UpgradeHelper ,只管升级和隔代升级版本库

public class UpgradeHelper extends OpenHelper {

public UpgradeHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory);
}

/**
* 这里是升级数据库的方法
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

/*
* 这个是升级的逻辑,当前程序的版本如果和新的程序出现隔代,那数据库要迭代升级
*/
for (int i = oldVersion; i < newVersion; i++) {
try {
/*
* 这里使用反射去找中间更新数据库做过的操作
*/
AbstractMigratorHelper migratorHelper = (AbstractMigratorHelper) Class
.forName("com.example.greendao.DBMigrationHelper" + i)
.newInstance();
if (migratorHelper != null) {
migratorHelper.onUpgrade(db);
}
} catch (ClassNotFoundException | ClassCastException | IllegalAccessException | InstantiationException e) {
Log.e("UpgradeHelper", "Could not migrate from schema from schema: " + i + " to " + i++);
/*
* 数据库没有更新成功,需要做特殊的处理
*/
break;
}
}
}
}


其中MigrationHelper是一个国外大牛写的,直接上代码:

/**
* greendao db upgrade helper class
*/
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(SQLiteDatabase db, @SuppressWarnings("unchecked") Class<? extends AbstractDao<?, ?>>... daoClasses) {
generateTempTables(db, daoClasses);
dropAllTables(db, true,daoClasses);
createAllTables(db, false,daoClasses);
restoreData(db, daoClasses);
}

@SuppressWarnings("unchecked")
private void generateTempTables(SQLiteDatabase 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<String>();

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 e) {
e.printStackTrace();
}
createTableStringBuilder.append(divider).append(columnName).append(" ").append(type);

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

divider = ",";
}
}
createTableStringBuilder.append(");");
if(createTableStringBuilder.toString().contains(" ();")){
continue;
}

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());
}
}

private void dropAllTables(SQLiteDatabase db, boolean ifExists,Class<? extends AbstractDao<?, ?>>... daoClasses){
for(int i = 0; i < daoClasses.length; i++) {
DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\""+daoConfig.tablename+"\"";
db.execSQL(sql);
}
}
private void createAllTables(SQLiteDatabase db, boolean ifNotExists,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;
ArrayList<String> properties = new ArrayList<String>();

StringBuilder createTableStringBuilder = new StringBuilder();

String constraint = ifNotExists? "IF NOT EXISTS ": "";

createTableStringBuilder.append("CREATE TABLE ").append(constraint).append(tableName).append(" (");

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

try {
type = getTypeByClass(daoConfig.properties[j].type);
} catch (Exception e) {
e.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());
}
}

private void restoreData(SQLiteDatabase 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<String>();

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);

if(insertTableStringBuilder.toString().contains("()")){
continue;
}

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) || type.equals(Date.class)) {
return "INTEGER";
}
if(type.equals(Boolean.class)) {
return "BOOLEAN";
}

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

private static List<String> getColumns(SQLiteDatabase db, String tableName) {
List<String> columns = new ArrayList<String>();
Cursor cursor = null;
try {
cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 1", null);
if (cursor != null) {
columns = new ArrayList<String>(Arrays.asList(cursor.getColumnNames()));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null)
cursor.close();
}
return columns;
}
}
至此GreenDao算基本使用讲完了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: