GreenDao框架使用教程

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算基本使用讲完了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值