SQL学习笔记之数据库课题(三):Android下Sqlite数据库ORM框架之GreenDao详解

SQL学习笔记之数据库专题(三):Android下Sqlite数据库ORM框架之GreenDao详解

在大型项目中,android的数据库操作不可能再像第二篇文章那样,用最基础的API去实现各方面的操作,那样效率会十分的底下。那么,在android开发中,提拱了androrm,Ormlite,greenDao三个主流框架,博主三生有幸,再开发第一个项目的时候,就被逼着学习使用greenDao这个ORM框架。现在回过头看,greenDao似乎是三种框架中效率最高的,但是对于初学者来说,使用起来非常的不方面,因为官方是纯英文文档,例子也不够详细。博主那个时候真的是在前进中摸索,各种坎坷,网上的博文介绍的都不够详细,不能满足博主的需求,对于数据库的多表设计,网上的例子也都不够详细,而且大部分都是从官方文档直接copy过来,并不是自己写的,更不会有注释。对于新手不好上手。最近这段时间博主比较有时间,于是整理之前的笔记,在数据库专题来详细讲解一下greendao的使用。博主从零开始,一段一段代码自己敲,并配上注释,保证新手容易上手。熟练掌握greendao的使用。

GreenDao官网:http://greendao-orm.com/

GreenDao github下载地址:https://github.com/greenrobot/greenDAO

GreenDao设计目的:最大性能,最快的Android ORM框架,易于使用的API,高度优化,最小内存的损耗

有兴趣的同学可以将完整的工程下载下来学习,看完后绝对可以掌握GreenDao的使用,可以直接拿去自己的项目工程里使用

示例代码下载地址:http://download.csdn.net/detail/victorfreedom/8353631


好了,废话说完了,接下来一步一步的开发一个使用greenDao的android项目工程。

一、新建一个JAVA工程,用于装载GreenDao类,生成Dao类文件。

在这个工程里面必须导入greendao-generator.jar和freemarker.jar或者直接在下载下来的例子里面的de.greenrobot.daogenerator包内容导入
博主的项目结构如图:
SQL学习笔记之数据库课题(三):Android下Sqlite数据库ORM框架之GreenDao详解
接下来,我们来写Dao类文件的生成代码,详情请看代码:
package com.batways.apopo.generator;

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

/**
 * @ClassName: TestCase
 * @author victor_freedom (x_freedom_reddevil@126.com)
 * @createddate 2015-1-12 下午2:17:52
 * @Description: TODO
 */
public class TestCase {
	// 数据库升级
	private static int dbVersion = 1;
	private String modelPackage = "com.example.freedomsql.bean";
	private Schema schema = new Schema(dbVersion, modelPackage);

	public static void main(String[] args) throws Exception {
		TestCase testCase = new TestCase();
		testCase.init();
		testCase.schema.enableKeepSectionsByDefault();
		testCase.schema.enableActiveEntitiesByDefault();
		new DaoGenerator().generateAll(testCase.schema,
				"E:\\mayflygeek\\mayflygeekprojects\\FreedomSql\\src");
	}

	public void init() {

		// 定义一个实体
		Entity OrderHeader = schema.addEntity("OrderHeader");
		// 实现序列化接口
		OrderHeader.implementsSerializable();
		// 定义ID主键
		OrderHeader.addIdProperty();
		// 增加其他字段,这里可以定义很多类型,还可以指定属性
		OrderHeader.addStringProperty("orderName").notNull();
		
		//如果不想用上面的定义ID主键,还可以自己这样定义。
//		OrderHeader.addLongProperty("orderId").primaryKey().autoincrement();

		//后面的实体定义和上面的差不多。就不在详细描述
		Entity OrderItem = schema.addEntity("OrderItem");
		OrderItem.implementsSerializable();
		OrderItem.addIdProperty();
		OrderItem.addStringProperty("itemName");
		// 用于做多表设计使用
		Property orderId = OrderItem.addLongProperty("orderId").getProperty();

		Entity Student = schema.addEntity("Student");
		Student.implementsSerializable();
		Student.addIdProperty();
		Student.addStringProperty("studentName");
		// 增加一个字段,数据库升级
		// Student.addDoubleProperty("results");

		Entity Teacher = schema.addEntity("Teacher");
		Teacher.implementsSerializable();
		Teacher.addIdProperty();
		Teacher.addStringProperty("teacherName");
		
		Entity StudentTeacher = schema.addEntity("StudentTeacher");
		Property teacherId = StudentTeacher.addLongProperty("teacherId")
				.getProperty();
		Property studentId = StudentTeacher.addLongProperty("studentId")
				.getProperty();

		// Entity Grade = schema.addEntity("Grade");
		// Grade.implementsSerializable();
		// Grade.addIdProperty();
		// Grade.addStringProperty("gradeName");

		// 树状结构,自身实现1对多
		Entity Tree = schema.addEntity("Tree");
		Tree.addIdProperty();
		Tree.addStringProperty("treeName");
		Property parentId = Tree.addLongProperty("parentId").getProperty();
		Tree.addToOne(Tree, parentId).setName("parent");
		Tree.addToMany(Tree, parentId).setName("children");

		// 外键添加,1对多
		OrderItem.addToOne(OrderHeader, orderId);
		ToMany addToMany = OrderHeader.addToMany(OrderItem, orderId);
		addToMany.setName("orderItems");

		// greenDao不支持多对多的实现,但是我们可以 自定义实现多对多
		StudentTeacher.addToOne(Student, studentId);
		StudentTeacher.addToOne(Teacher, teacherId);
		Student.addToMany(StudentTeacher, studentId)
				.setName("studentsteachers");
		Teacher.addToMany(StudentTeacher, teacherId)
				.setName("studentsteachers");

	}
}

二、Android工程中GreenDao的使用

首先需要导入对应的jar包。这个无需在详细说明。下载下来的例子里面有。

1、Android工程中代码生成的结构

1、DaoMaster,DaoSession的生成

  这两个文件是最关键的两个文件,数据库的生成和表的操作都在这两个类里面。如果没有指定生成目录,会和实体文件一起生成在同一目录里面

2、实体类和对应Dao类的生成

这里以OrderHeader实体来说明,详情看代码:
package com.example.freedomsql.bean;

import java.util.List;
import com.example.freedomsql.bean.DaoSession;
import de.greenrobot.dao.DaoException;

// THIS CODE IS GENERATED BY greenDAO, EDIT ONLY INSIDE THE "KEEP"-SECTIONS

// KEEP INCLUDES - put your custom includes here
// KEEP INCLUDES END
/**
 * Entity mapped to table ORDER_HEADER.
 */
public class OrderHeader implements java.io.Serializable {

	private Long id;
	private String orderName;

	/** Used to resolve relations */
	private transient DaoSession daoSession;

	/** Used for active entity operations. */
	private transient OrderHeaderDao myDao;

	private List<OrderItem> orderItems;

	// 如果设置了enableKeepSectionsByDefault();enableActiveEntitiesByDefault();这两个属性,那么我们可以再指定的区域内写入自定义代码,方便下次升级的时候不会被覆盖掉
	// KEEP FIELDS - put your custom fields here
	// KEEP FIELDS END

	public OrderHeader() {
	}

	public OrderHeader(Long id) {
		this.id = id;
	}

	public OrderHeader(Long id, String orderName) {
		this.id = id;
		this.orderName = orderName;
	}

	/** called by internal mechanisms, do not call yourself. */
	public void __setDaoSession(DaoSession daoSession) {
		this.daoSession = daoSession;
		myDao = daoSession != null ? daoSession.getOrderHeaderDao() : null;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getOrderName() {
		return orderName;
	}

	public void setOrderName(String orderName) {
		this.orderName = orderName;
	}

	/**
	 * To-many relationship, resolved on first access (and after reset). Changes
	 * to to-many relations are not persisted, make changes to the target
	 * entity.
	 */
	public List<OrderItem> getOrderItems() {
		if (orderItems == null) {
			if (daoSession == null) {
				throw new DaoException("Entity is detached from DAO context");
			}
			OrderItemDao targetDao = daoSession.getOrderItemDao();
			List<OrderItem> orderItemsNew = targetDao
					._queryOrderHeader_OrderItems(id);
			synchronized (this) {
				if (orderItems == null) {
					orderItems = orderItemsNew;
				}
			}
		}
		return orderItems;
	}

	/**
	 * Resets a to-many relationship, making the next get call to query for a
	 * fresh result.
	 */
	public synchronized void resetOrderItems() {
		orderItems = null;
	}

	/**
	 * Convenient call for {@link AbstractDao#delete(Object)}. Entity must
	 * attached to an entity context.
	 */
	public void delete() {
		if (myDao == null) {
			throw new DaoException("Entity is detached from DAO context");
		}
		myDao.delete(this);
	}

	/**
	 * Convenient call for {@link AbstractDao#update(Object)}. Entity must
	 * attached to an entity context.
	 */
	public void update() {
		if (myDao == null) {
			throw new DaoException("Entity is detached from DAO context");
		}
		myDao.update(this);
	}

	/**
	 * Convenient call for {@link AbstractDao#refresh(Object)}. Entity must
	 * attached to an entity context.
	 */
	public void refresh() {
		if (myDao == null) {
			throw new DaoException("Entity is detached from DAO context");
		}
		myDao.refresh(this);
	}

	// KEEP METHODS - put your custom methods here
	// KEEP METHODS END

}
这里需要特别注意的是,在使用getOrderItems()拿到自己1对多的实体内容的时候,一定要记得resetOrderItems一下,不然由于缓存机制,会拿不到最新的实体内容。我们可以看到刚刚在test类中设置的内容都出现了,而且和Orderitem的1对多关系也得到了体现。在数据库操作的时候会变得非常的便捷
在看看Dao类
package com.example.freedomsql.bean;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;

import de.greenrobot.dao.AbstractDao;
import de.greenrobot.dao.Property;
import de.greenrobot.dao.internal.DaoConfig;

import com.example.freedomsql.bean.OrderHeader;

// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/** 
 * DAO for table ORDER_HEADER.
*/
public class OrderHeaderDao extends AbstractDao<OrderHeader, Long> {

    public static final String TABLENAME = "ORDER_HEADER";

    /**
     * Properties of entity OrderHeader.<br/>
     * Can be used for QueryBuilder and for referencing column names.
    */
    public static class Properties {
        public final static Property Id = new Property(0, Long.class, "id", true, "_id");
        public final static Property OrderName = new Property(1, String.class, "orderName", false, "ORDER_NAME");
    };

    private DaoSession daoSession;


    public OrderHeaderDao(DaoConfig config) {
        super(config);
    }
    
    public OrderHeaderDao(DaoConfig config, DaoSession daoSession) {
        super(config, daoSession);
        this.daoSession = daoSession;
    }

    /** Creates the underlying database table. */
    public static void createTable(SQLiteDatabase db, boolean ifNotExists) {
        String constraint = ifNotExists? "IF NOT EXISTS ": "";
        db.execSQL("CREATE TABLE " + constraint + "'ORDER_HEADER' (" + //
                "'_id' INTEGER PRIMARY KEY ," + // 0: id
                "'ORDER_NAME' TEXT);"); // 1: orderName
    }

    /** Drops the underlying database table. */
    public static void dropTable(SQLiteDatabase db, boolean ifExists) {
        String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "'ORDER_HEADER'";
        db.execSQL(sql);
    }

    /** @inheritdoc */
    @Override
    protected void bindValues(SQLiteStatement stmt, OrderHeader entity) {
        stmt.clearBindings();
 
        Long id = entity.getId();
        if (id != null) {
            stmt.bindLong(1, id);
        }
 
        String orderName = entity.getOrderName();
        if (orderName != null) {
            stmt.bindString(2, orderName);
        }
    }

    @Override
    protected void attachEntity(OrderHeader entity) {
        super.attachEntity(entity);
        entity.__setDaoSession(daoSession);
    }

    /** @inheritdoc */
    @Override
    public Long readKey(Cursor cursor, int offset) {
        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);
    }    

    /** @inheritdoc */
    @Override
    public OrderHeader readEntity(Cursor cursor, int offset) {
        OrderHeader entity = new OrderHeader( //
            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id
            cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1) // orderName
        );
        return entity;
    }
     
    /** @inheritdoc */
    @Override
    public void readEntity(Cursor cursor, OrderHeader entity, int offset) {
        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));
        entity.setOrderName(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1));
     }
    
    /** @inheritdoc */
    @Override
    protected Long updateKeyAfterInsert(OrderHeader entity, long rowId) {
        entity.setId(rowId);
        return rowId;
    }
    
    /** @inheritdoc */
    @Override
    public Long getKey(OrderHeader entity) {
        if(entity != null) {
            return entity.getId();
        } else {
            return null;
        }
    }

    /** @inheritdoc */
    @Override    
    protected boolean isEntityUpdateable() {
        return true;
    }
    
}
我们可以看到对应的表生成语句和字段绑定等都在这个类里面。其实这个类和之前哪篇文件说的Dao类一样,是操作数据库用的。增删改查全部靠这个类来实行。

2、使用greenDao在项目中操作数据库。

1、操作DaoMaster,DaoSession类编写

    之前说过,DaoMaster和DaoSession是非常关键的两个类,所以我们需要单独将他们两个类独立出来处理,新建一个GreenDao类来实现,详情看代码:
package com.example.freedomsql.bean;

import android.content.Context;

import com.example.freedomsql.utils.Config;

/**
 * @ClassName: GreenDao
 * @author victor_freedom (x_freedom_reddevil@126.com)
 * @createddate 2015-1-12 下午3:21:02
 * @Description: TODO
 */
public class GreenDao {
	private static DaoMaster daoMaster;
	private static DaoSession daoSession;

	/**
	 * 获取DaoMaster实例
	 * 
	 * @param context
	 * @return
	 */
	public static DaoMaster getDaoMaster(Context context) {
		if (daoMaster == null) {
			DaoMaster.OpenHelper helper = new DaoMaster.DevOpenHelper(context,
					Config.DB_NAME, null);
			daoMaster = new DaoMaster(helper.getWritableDatabase());
		}
		return daoMaster;
	}

	/**
	 * 获取DaoSession实例
	 * 
	 * @param context
	 * @return
	 */
	public static DaoSession getDaoSession(Context context) {
		if (daoSession == null) {
			if (daoMaster == null) {
				daoMaster = getDaoMaster(context);
			}
			daoSession = daoMaster.newSession();
		}
		return daoSession;
	}
}

2、数据库增删改查接口类编写

   在拿到两个非常重要的类之后,接下来就是对数据库操作的接口类的编写。我们以OrderHeader和OrderItem类来举例说明我们写先接口
package com.example.freedomsql.service;

import com.example.freedomsql.bean.OrderHeader;
import com.example.freedomsql.bean.OrderItem;
import com.example.freedomsql.bean.Student;
import com.example.freedomsql.bean.Teacher;

public interface IOrderHeaderService {

	/**
	 * @Title: createOrder
	 * @Description: 创建一个订单
	 * @param order
	 * @return
	 * @throws
	 */
	public OrderHeader createOrder(OrderHeader order);

	/**
	 * @Title: updateOrder
	 * @Description: 更新一个订单
	 * @param orderHeader
	 * @return
	 * @throws
	 */
	public OrderHeader updateOrder(OrderHeader orderHeader);

	/**
	 * @Title: findOrderByName
	 * @Description: 根据名称查找订单
	 * @param orderName
	 * @return
	 * @throws
	 */
	public OrderHeader findOrderByName(String orderName);

	/**
	 * @Title: findOrderById
	 * @Description: 根据主键ID查找订单
	 * @param orderId
	 * @return
	 * @throws
	 */
	public OrderHeader findOrderById(long orderId);

	/**
	 * @Title: findOrderItemById
	 * @Description:根据主键ID查找订单明细
	 * @param orderItemId
	 * @return
	 * @throws
	 */
	public OrderItem findOrderItemById(long orderItemId);

	/**
	 * @Title: findOrderItemByName
	 * @Description: 根据名称查找订单明细
	 * @param orderItemName
	 * @return
	 * @throws
	 */
	public OrderItem findOrderItemByName(String orderItemName);

	/**
	 * @Title: createOrderItem
	 * @Description: 创建订单明细
	 * @param orderHeader
	 * @param name
	 * @return
	 * @throws
	 */
	public OrderItem createOrderItem(OrderHeader orderHeader, String name);
}
接下来写实现类:
package com.example.freedomsql.service.impl;

import android.content.Context;

import com.example.freedomsql.bean.DaoSession;
import com.example.freedomsql.bean.GreenDao;
import com.example.freedomsql.bean.OrderHeader;
import com.example.freedomsql.bean.OrderHeaderDao;
import com.example.freedomsql.bean.OrderItem;
import com.example.freedomsql.bean.OrderItemDao;
import com.example.freedomsql.service.IOrderHeaderService;

/**
 * @ClassName: OrderHeaderService
 * @author victor_freedom (x_freedom_reddevil@126.com)
 * @createddate 2015-1-12 下午3:26:41
 * @Description: TODO
 */
public class OrderHeaderService implements IOrderHeaderService {

	private static DaoSession daoSession;
	private static OrderHeaderService service;
	private OrderHeaderDao orderHeaderDao;
	private OrderItemDao orderItemDao;

	private OrderHeaderService(OrderHeaderDao orderHeaderDao,
			OrderItemDao orderItemDao) {
		this.orderHeaderDao = orderHeaderDao;
		this.orderItemDao = orderItemDao;
	}

	/**
	 * @param context
	 * @return
	 */
	public static OrderHeaderService getService(Context context) {
		if (service == null) {
			daoSession = GreenDao.getDaoSession(context);
			service = new OrderHeaderService(daoSession.getOrderHeaderDao(),
					daoSession.getOrderItemDao());
		}
		return service;
	}

	@Override
	public OrderHeader createOrder(OrderHeader order) {
		return orderHeaderDao.loadByRowId(orderHeaderDao.insert(order));
	}

	@Override
	public OrderHeader updateOrder(OrderHeader orderHeader) {
		orderHeaderDao.update(orderHeader);
		return orderHeader;
	}

	@Override
	public OrderHeader findOrderByName(String orderName) {
		OrderHeader orderHeader = orderHeaderDao.queryBuilder()
				.where(OrderHeaderDao.Properties.OrderName.eq(orderName))
				.unique();
		return orderHeader;
	}

	@Override
	public OrderHeader findOrderById(long orderId) {
		return orderHeaderDao.load(orderId);
	}

	@Override
	public OrderItem findOrderItemById(long orderItemId) {
		return orderItemDao.load(orderItemId);
	}

	@Override
	public OrderItem findOrderItemByName(String orderItemName) {
		return orderItemDao.queryBuilder()
				.where(OrderItemDao.Properties.ItemName.eq(orderItemName))
				.unique();
	}

	@Override
	public OrderItem createOrderItem(OrderHeader orderHeader, String name) {
		OrderItem orderItem = new OrderItem();
		orderItem.setItemName(name);
		orderItem.setOrderHeader(orderHeader);
		return orderItemDao.load(orderItemDao.insert(orderItem));
	}

}

我们可以看到,查询条件非常容易写,这里博主只写了些简单的查询条件,在where方法中是可以支持多条件限制查询的,查询方法非常的强大。还支持延迟lazy查询。但是使用延迟查询的话要记得close()掉。我们可以将相关系的表文件的Dao文件写到一起,便于查询方法的编写。这里博主没有演示删除操作,其实也非常简单,API在Dao类里面,一看就懂的。

3、在主项目中的编写

1、接口位置的放置
这些接口,我们肯定是要做成全局变量的,那么,之前说过,全局变量的最好放置地方就是在Application中,参考代码如下
package com.example.freedomsql;

import android.app.Application;

import com.example.freedomsql.service.IClassService;
import com.example.freedomsql.service.IOrderHeaderService;
import com.example.freedomsql.service.impl.ClassService;
import com.example.freedomsql.service.impl.OrderHeaderService;

/**
 * @ClassName: FreedomApplication
 * @author victor_freedom (x_freedom_reddevil@126.com)
 * @createddate 2015-1-12 下午3:39:56
 * @Description: TODO
 */
public class FreedomApplication extends Application {

	public IClassService classService;
	public IOrderHeaderService orderHeaderService;

	@Override
	public void onCreate() {
		super.onCreate();
		classService = ClassService.getService(getApplicationContext());
		orderHeaderService = OrderHeaderService
				.getService(getApplicationContext());
	}
}
2、主Activity的编写
我们需要在这里生成一些数据来观察数据库:(那些 注释掉的东西是博主后面用来升级数据库使用的)
package com.example.freedomsql;

import android.app.Activity;
import android.os.Bundle;

import com.example.freedomsql.bean.OrderHeader;
import com.example.freedomsql.bean.Student;
import com.example.freedomsql.bean.StudentTeacher;
import com.example.freedomsql.bean.Teacher;
import com.example.freedomsql.service.IClassService;
import com.example.freedomsql.service.IOrderHeaderService;

public class MainActivity extends Activity {
	private IClassService classService;
	private IOrderHeaderService orderHeaderService;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		classService = ((FreedomApplication) getApplication()).classService;
		orderHeaderService = ((FreedomApplication) getApplication()).orderHeaderService;
		initGreenDaoDB();
	}

	private void initGreenDaoDB() {
		Teacher t1 = new Teacher();
		t1.setTeacherName("freedom");
		// t1.setTeacherName("freedom2");
		classService.createTeacher(t1);
		Teacher t2 = new Teacher();
		t2.setTeacherName("freedom1");
		// t2.setTeacherName("freedom3");
		Student t3 = new Student();
		t3.setStudentName("victor");
		// t3.setStudentName("victor2");
		Student t4 = new Student();
		 t4.setStudentName("victor1");
		// t4.setStudentName("victor3");
		classService.createTeacher(t1);
		classService.createTeacher(t2);
		classService.createStudent(t3);
		classService.createStudent(t4);
		StudentTeacher st1 = new StudentTeacher(t1.getId(), t3.getId());
		StudentTeacher st2 = new StudentTeacher(t1.getId(), t4.getId());
		StudentTeacher st3 = new StudentTeacher(t2.getId(), t3.getId());
		StudentTeacher st4 = new StudentTeacher(t2.getId(), t4.getId());
		classService.createStudentTeacher(st1);
		classService.createStudentTeacher(st2);
		classService.createStudentTeacher(st3);
		classService.createStudentTeacher(st4);
		OrderHeader order = new OrderHeader();
		order.setOrderName("订单1");
		// order.setOrderName("订单3");
		OrderHeader order1 = new OrderHeader();
		order1.setOrderName("订单2");
		// order1.setOrderName("订单4");
		orderHeaderService.createOrder(order);
		orderHeaderService.createOrder(order1);
		orderHeaderService.createOrderItem(order1, "明细1");
		orderHeaderService.createOrderItem(order1, "明细2");
		// orderHeaderService.createOrderItem(order1, "明细3");
		// orderHeaderService.createOrderItem(order1, "明细4");

	}
}

生成数据后如图所示:这里就只上传OrderHeader和OrderItem的图
SQL学习笔记之数据库课题(三):Android下Sqlite数据库ORM框架之GreenDao详解SQL学习笔记之数据库课题(三):Android下Sqlite数据库ORM框架之GreenDao详解

好了,greenDao的操作基本讲解完毕,相信看了代码的同学基本上学会了如何使用GreenDao,以及多表结构的设计。博主这里就不演示那些查询方法了,都很简单,通俗易懂。接下来博主再讲讲再数据库升级中,如何保存原有数据。


3、使用GreenDao升级数据库

1、TestCase类文件修改

    数据库的升级,一般是在于字段的增加或者表的增加,这里,博主再一个实体中增加一个字段,又增加一个实体来演示
    首先,增加数据库版本号:
private static int dbVersion = 2;

    再在Student类中增加一个字段
// 增加一个字段,数据库升级
		 Student.addDoubleProperty("results");

    增加一个实体Grade
Entity Grade = schema.addEntity("Grade");
		Grade.implementsSerializable();
		Grade.addIdProperty();
		Grade.addStringProperty("gradeName");

2、DaoMaster类的修改,这里我们只需要重写一下onUpgrade方法

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			Log.i("greenDAO", "Upgrading schema from version " + oldVersion
					+ " to " + newVersion + " by dropping all tables");
			//正常情况下,GreenDao默认升级的时候,将所有的表删除后再建,所以我们需要在这里处理
			// dropAllTables(db, true);
			// onCreate(db);
			if (oldVersion == 1 && newVersion == 2) {
				// 增加一个实体表
				GradeDao.createTable(db, false);
				// 修改Student表
				db.execSQL("ALTER TABLE 'STUDENT' ADD 'RESULTS' REAL");
			}

		}

3、主Activity的修改,其他地方都不用修改了

对于主Activity,我们需要重新生成一些数据对比之前的数据即可
package com.example.freedomsql;

import android.app.Activity;
import android.os.Bundle;

import com.example.freedomsql.bean.OrderHeader;
import com.example.freedomsql.bean.Student;
import com.example.freedomsql.bean.StudentTeacher;
import com.example.freedomsql.bean.Teacher;
import com.example.freedomsql.service.IClassService;
import com.example.freedomsql.service.IOrderHeaderService;

public class MainActivity extends Activity {
	private IClassService classService;
	private IOrderHeaderService orderHeaderService;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		classService = ((FreedomApplication) getApplication()).classService;
		orderHeaderService = ((FreedomApplication) getApplication()).orderHeaderService;
		initGreenDaoDB();
	}

	private void initGreenDaoDB() {
		Teacher t1 = new Teacher();
		// t1.setTeacherName("freedom");
		t1.setTeacherName("freedom2");
		classService.createTeacher(t1);
		Teacher t2 = new Teacher();
		// t2.setTeacherName("freedom1");
		t2.setTeacherName("freedom3");
		Student t3 = new Student();
		// t3.setStudentName("victor");
		t3.setStudentName("victor2");
		Student t4 = new Student();
		// t4.setStudentName("victor1");
		t4.setStudentName("victor3");
		classService.createTeacher(t1);
		classService.createTeacher(t2);
		classService.createStudent(t3);
		classService.createStudent(t4);
		StudentTeacher st1 = new StudentTeacher(t1.getId(), t3.getId());
		StudentTeacher st2 = new StudentTeacher(t1.getId(), t4.getId());
		StudentTeacher st3 = new StudentTeacher(t2.getId(), t3.getId());
		StudentTeacher st4 = new StudentTeacher(t2.getId(), t4.getId());
		classService.createStudentTeacher(st1);
		classService.createStudentTeacher(st2);
		classService.createStudentTeacher(st3);
		classService.createStudentTeacher(st4);
		OrderHeader order = new OrderHeader();
		// order.setOrderName("订单1");
		order.setOrderName("订单3");
		OrderHeader order1 = new OrderHeader();
		// order1.setOrderName("订单2");
		order1.setOrderName("订单4");
		orderHeaderService.createOrder(order);
		orderHeaderService.createOrder(order1);
		// orderHeaderService.createOrderItem(order1, "明细1");
		// orderHeaderService.createOrderItem(order1, "明细2");
		orderHeaderService.createOrderItem(order1, "明细3");
		orderHeaderService.createOrderItem(order1, "明细4");

	}
}

我们来看看运行前后的数据库Student表效果图对比

SQL学习笔记之数据库课题(三):Android下Sqlite数据库ORM框架之GreenDao详解SQL学习笔记之数据库课题(三):Android下Sqlite数据库ORM框架之GreenDao详解
我们可以看到新生的字段也在,之前的数据也在

在看看新生成的Grade表

SQL学习笔记之数据库课题(三):Android下Sqlite数据库ORM框架之GreenDao详解

我们可以看到GRADE表也成功的生成了。整个数据库的数据都还保留着。