- 浏览: 223027 次
- 性别:
- 来自: 成都
文章分类
- 全部博客 (213)
- SQLServer (8)
- flex (8)
- 文章 (5)
- java (91)
- 数据结构 (0)
- 设计模式 (0)
- C# (2)
- Oracle (4)
- 技术 (4)
- 云计算 (0)
- 算法 (0)
- 记录 (3)
- javascript (5)
- div/css (1)
- http (0)
- IE (1)
- web (1)
- hadoop (0)
- extjs (4)
- hibernate (6)
- 错误记录 (5)
- mysql (4)
- json (1)
- jvm (1)
- spring (4)
- 工具 (2)
- tomcat (3)
- cxf (3)
- spring data (1)
- memcached (5)
- android-exception (2)
- 数据压缩 (1)
- 博客 (2)
- bat (0)
- nginx (3)
- svn (2)
- jpa (1)
- windows (2)
- h2 (2)
- webservice (2)
- android (5)
- oa (0)
- eclipse (2)
- jquery (2)
- jni (4)
- weblogic (1)
- work (0)
- smartclient (1)
- sql (0)
- excel (0)
- test (0)
- t (0)
- js (4)
- utils (0)
- bootstrap (0)
- sniper (0)
- ztree (0)
- google (0)
- mdb (0)
- redis (1)
- 思想 (1)
- css (0)
- appCan (0)
- activiti (0)
- 工作 (0)
- 浏览器 (1)
http://blog.csdn.net/victorfreedom/article/details/42584561
在大型项目中,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包内容导入
博主的项目结构如图:
接下来,我们来写Dao类文件的生成代码,详情请看代码:
[java] view plaincopy
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实体来说明,详情看代码:
[java] view plaincopy
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类
[java] view plaincopy
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类来实现,详情看代码:
[java] view plaincopy
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类来举例说明我们写先接口
[java] view plaincopy
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);
}
接下来写实现类:
[java] view plaincopy
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中,参考代码如下
[java] view plaincopy
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的编写
我们需要在这里生成一些数据来观察数据库:(那些 注释掉的东西是博主后面用来升级数据库使用的)
[java] view plaincopy
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的图
好了,greenDao的操作基本讲解完毕,相信看了代码的同学基本上学会了如何使用GreenDao,以及多表结构的设计。博主这里就不演示那些查询方法了,都很简单,通俗易懂。接下来博主再讲讲再数据库升级中,如何保存原有数据。
3、使用GreenDao升级数据库
1、TestCase类文件修改
数据库的升级,一般是在于字段的增加或者表的增加,这里,博主再一个实体中增加一个字段,又增加一个实体来演示
首先,增加数据库版本号:
[java] view plaincopy
private static int dbVersion = 2;
再在Student类中增加一个字段
[java] view plaincopy
// 增加一个字段,数据库升级
Student.addDoubleProperty("results");
增加一个实体Grade
[java] view plaincopy
Entity Grade = schema.addEntity("Grade");
Grade.implementsSerializable();
Grade.addIdProperty();
Grade.addStringProperty("gradeName");
2、DaoMaster类的修改,这里我们只需要重写一下onUpgrade方法
[java] view plaincopy
@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,我们需要重新生成一些数据对比之前的数据即可
[java] view plaincopy
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表效果图对比
我们可以看到新生的字段也在,之前的数据也在
在大型项目中,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包内容导入
博主的项目结构如图:
接下来,我们来写Dao类文件的生成代码,详情请看代码:
[java] view plaincopy
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实体来说明,详情看代码:
[java] view plaincopy
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类
[java] view plaincopy
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类来实现,详情看代码:
[java] view plaincopy
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类来举例说明我们写先接口
[java] view plaincopy
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);
}
接下来写实现类:
[java] view plaincopy
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中,参考代码如下
[java] view plaincopy
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的编写
我们需要在这里生成一些数据来观察数据库:(那些 注释掉的东西是博主后面用来升级数据库使用的)
[java] view plaincopy
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的图
好了,greenDao的操作基本讲解完毕,相信看了代码的同学基本上学会了如何使用GreenDao,以及多表结构的设计。博主这里就不演示那些查询方法了,都很简单,通俗易懂。接下来博主再讲讲再数据库升级中,如何保存原有数据。
3、使用GreenDao升级数据库
1、TestCase类文件修改
数据库的升级,一般是在于字段的增加或者表的增加,这里,博主再一个实体中增加一个字段,又增加一个实体来演示
首先,增加数据库版本号:
[java] view plaincopy
private static int dbVersion = 2;
再在Student类中增加一个字段
[java] view plaincopy
// 增加一个字段,数据库升级
Student.addDoubleProperty("results");
增加一个实体Grade
[java] view plaincopy
Entity Grade = schema.addEntity("Grade");
Grade.implementsSerializable();
Grade.addIdProperty();
Grade.addStringProperty("gradeName");
2、DaoMaster类的修改,这里我们只需要重写一下onUpgrade方法
[java] view plaincopy
@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,我们需要重新生成一些数据对比之前的数据即可
[java] view plaincopy
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表效果图对比
我们可以看到新生的字段也在,之前的数据也在
发表评论
-
黑马全套视频
2017-05-13 23:26 0http://pan.baidu.com/s/1dDmE1qh ... -
android---draw9patch
2016-07-21 08:44 0ddddddddddddddddddddddddddddddd ... -
解决Android SDK Manager下载太慢问题
2015-05-30 22:06 925http://blog.csdn.net/exlsunshin ... -
报错java.lang.NoClassDefFoundError的问题
2015-03-16 10:09 1379------------------------------- ... -
Android客户端和服务端如何使用Token和Session
2015-03-03 16:58 799对于初学者来说,对Toke ... -
Android开源项目 分类 便于查看
2015-02-01 14:26 0http://blog.csdn.net/vipzjyno1/ ... -
android引用包问题
2015-01-29 11:11 903http://blog.csdn.net/m694449212 ...
相关推荐
SQLite3的ORM(Object-Relational Mapping)框架是一种在C++编程中将数据库关系模型与对象模型进行对应的技术。ORM框架使得开发者可以使用面向对象的方式来操作数据库,避免了直接编写SQL语句,提高了开发效率和代码...
**Android GreenDao数据库框架的深度解析** 在移动应用开发中,数据存储是不可或缺的一部分,而GreenDao作为Android平台上的一款高效、轻量级的对象关系映射(ORM)框架,深受开发者喜爱。它允许开发者以Java对象的...
在Android开发中,SQLite是一个非常重要的组成部分,它是一个轻量级的、开源的、嵌入式的SQL数据库引擎,被广泛用于存储和管理应用程序中的数据。SQLite具有高效、可靠且易于集成的特点,使得它成为Android应用数据...
一个简单的Android SQLite ORM框架不想花资源分的同学可以上我的github主页下载:https://github.com/chenyihan/Simple-SQLite-ORM-Android,因为要传到github,所以代码中的注释和doc文档都是英文的,对自己英文不...
这篇资料主要围绕的是Android中的SQLite ORM(Object-Relational Mapping)框架,这是一种将数据库操作与对象模型相结合的技术,简化了数据库的使用。ORM框架使得开发者可以使用面向对象的方式来操作数据库,避免了...
SQLite是Android系统内置的关系型数据库,它为...综上所述,Android轻量级SQLite ORM框架简化了Android应用的数据库操作,提高了开发效率。开发者可以根据项目的规模和复杂程度,以及自身的熟悉程度选择合适的框架。
在Android开发中,数据库操作是不可或缺的一部分,而greenDAO作为一款高效、轻量级的对象关系映射(ORM)框架,可以简化我们对SQLite数据库的操作。它允许开发者直接将Java对象映射到数据库表,大大减少了与SQL交互...
- Android中的SQLite:Android SDK内置了SQLite,提供了SQLiteOpenHelper和SQLiteDatabase接口供开发者使用。 - 数据库操作:创建、打开、升级、关闭数据库,以及增删改查(CRUD)等基本操作。 2. **ORM概念** -...
SQLite ORM(对象关系映射)框架则简化了Android开发者与SQLite数据库之间的交互,使得数据操作更加方便,代码更简洁。本文将深入探讨Android轻量级SQLite ORM框架,并结合提供的源码进行学习。 首先,我们需要了解...
greenDAO是一个可以帮助Android开发者快速将Java对象映射到SQLite数据库的表单中的ORM解决方案,通过使用一个简单的面向对象API,开发者可以对Java对象进行存储、更新、删除和查询。
1. 数据库操作:Android SDK提供了`SQLiteOpenHelper`类,它是处理SQLite数据库的主要接口。这个类的主要职责是创建和升级数据库,以及提供`SQLiteDatabase`实例进行具体的查询和操作。在轻量级ORM框架中,通常会...
这里提到的"Android轻量级sqlite orm框架"可能是诸如GreenDAO、ORMLite、SugarORM等框架之一。以GreenDAO为例,它是一个性能优秀的ORM框架,支持快速映射Java对象到SQLite表。 GreenDAO的使用步骤大致如下: 1. ...
在Android开发中,数据库管理是不可或缺的一部分,而GreenDAO作为一款高效的对象关系映射(ORM)框架,使得在Android上处理SQLite数据库变得异常简便。本文将深入探讨GreenDAO的基本操作,帮助开发者快速理解和掌握...
Android Greendao数据库框架是一个高效、轻量级的ORM(对象关系映射)解决方案,专为Android平台设计。它允许开发者将Java对象直接映射到SQLite数据库,从而简化了数据库操作,提高了开发效率。在Android应用开发中...
GreenDao是一个流行的ORM(对象关系映射)框架,它使得Java对象与SQLite数据库之间的交互变得简单易行。本资源提供了一份关于如何封装和使用GreenDao的教程,特别适合初学者以及希望提升数据库操作效率的开发者。 ...
**绿色DAO(greenDAO)** 是一款针对Android平台设计的高效、轻量级的对象关系映射(ORM)框架。它的主要目标是简化Android应用中对SQLite数据库的操作,将Java对象直接映射为数据库表,避免了传统的SQL语句编写,...
GreenDao是一个流行的ORM(Object-Relational Mapping)框架,专为Android设计,能够帮助开发者高效地操作SQLite数据库。本教程将通过一个名为"MyGreenDao"的示例项目,详细介绍如何在Android Studio中使用GreenDao...
为了解决这个问题,GreenDao应运而生,它是一个强大的Android ORM(对象关系映射)框架,简化了数据库操作,让开发者能够更高效地与SQLite进行交互。 **1. GreenDao介绍** GreenDao是德国Genymobile公司开发的一款...
3. **SQLite ORM框架**:了解ORM框架在Android中的应用,例如ActiveAndroid、GreenDao、ORMLite等。这些框架将Java对象与SQLite数据库中的记录自动映射,减少了手动编写SQL语句的工作量。在这个项目中,你可能接触到...
SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。 就像其他数据库,SQLite 引擎不是一个...