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

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


增加一个实体Grade



在大型项目中,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.****.net/detail/victorfreedom/8353631
好了,废话说完了,接下来一步一步的开发一个使用greenDao的android项目工程。
一、新建一个JAVA工程,用于装载GreenDao类,生成Dao类文件。
在这个工程里面必须导入greendao-generator.jar和freemarker.jar或者直接在下载下来的例子里面的de.greenrobot.daogenerator包内容导入
博主的项目结构如图:
接下来,我们来写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的图
好了,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表效果图对比
我们可以看到新生的字段也在,之前的数据也在
在看看新生成的Grade表
我们可以看到GRADE表也成功的生成了。整个数据库的数据都还保留着。