《Android ORMLite ForeignCollection关联外部集合》
Android ORMLite ForeignCollection关联外部集合的功能,适合层级比较深,数据模型互相渗透、交叉的数据结构或集合。尤其方便解决复杂数据模型。简单期间,我们暂时以 班级 <-> 学生 这样的数据模型为例加以说明。一个班级里面有若干学生(一对多,1<-n),反过来说,若干个学生集合到一个班级中(n->1)。 在Android ORMLite中,这样的结构模型可以用@ForeignCollectionField,ForeignCollection建模。我们定义一个班级类AClass(之所以在 'Class'前加一个‘A’,是因为Java语言中,'Class'是保留字,却刚好是我们想用的班级英文单词,真不巧,所以前面加个'A'规避),AClass包含id(主键,方便查询和更新),name以及指向一个外部Student的集合(ForeignCollection<Student>)。同样,我们定义学生类Student,Student中埋入一个字段aclass指向外部的AClass。
备注:
Android ORMLite简介文章:http://blog.csdn.net/zhangphil/article/details/46878075
示例代码总共有4个文件:MainActivity.java,主Activity,用于测试。ORMLiteDatabaseHelper.java , AClass.java , Student.java 是数据库相关的代码文件,用于建模。
结构层次如图:
测试用的MainActivity.java :
package zhangphil.ormlitetest;
import java.sql.SQLException;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.ForeignCollection;
import zhangphil.ormlitetest.database.AClass;
import zhangphil.ormlitetest.database.ORMLiteDatabaseHelper;
import zhangphil.ormlitetest.database.Student;
import android.support.v7.app.ActionBarActivity;
import android.widget.Toast;
import android.os.Bundle;
public class MainActivity extends ActionBarActivity {
private Dao<AClass, Integer> mClassDao;
private Dao<Student, Integer> mStudentDao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ORMLiteDatabaseHelper mDatabaseHelper = ORMLiteDatabaseHelper
.getInstance(this);
mClassDao = mDatabaseHelper.getClassDao();
mStudentDao = mDatabaseHelper.getStudentDao();
// 创建5个班级用以演示。
for (int i = 1; i < 6; i++) {
AClass aclass = new AClass();
aclass.id = i;
aclass.name = i + "班";
try {
mClassDao.createIfNotExists(aclass);
} catch (SQLException e) {
e.printStackTrace();
}
}
// 找到id=1的1班。
AClass class1 = null;
try {
class1 = mClassDao.queryForId(1);
} catch (SQLException e) {
e.printStackTrace();
}
// 创建19个学生,这19个学生都归属到1班。
for (int i = 1; i < 20; i++) {
Student s = new Student();
s.id = i;
s.name = "学生" + i;
// 将新创建的这些学生所在班级指针指向1班。
// 数据模型:id=1的1班和这19个学生是1对多的学生,换句话说,这19个学生是1班的学生。
s.aclass = class1;
try {
mStudentDao.createIfNotExists(s);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
@Override
public void onStart() {
super.onStart();
/**
* 下面我们演示更新一个Student的信息, 然后向上,依据外键,从Student - > Class更新班级信息。
*
* */
// 假设我们更新其中id=1的这个学生所在的这个班级的name变成“一班”。
Student s1 = null;
try {
s1 = mStudentDao.queryForId(1);
s1.aclass.name = "一班";
// 更新1班的名字从“1班”变成“一班”
mClassDao.update(s1.aclass);
} catch (SQLException e) {
e.printStackTrace();
}
// 显示我们更新后的结果。
AClass class1 = null;
try {
class1 = mClassDao.queryForId(1);
} catch (SQLException e1) {
e1.printStackTrace();
}
ForeignCollection<Student> students = class1.students;
for (Student s : students) {
Toast.makeText(this, s.toString(), Toast.LENGTH_SHORT).show();
}
}
}
以下是数据库相关的建模:
AClass.java :
package zhangphil.ormlitetest.database;
import com.j256.ormlite.dao.ForeignCollection;
import com.j256.ormlite.field.DataType;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.field.ForeignCollectionField;
import com.j256.ormlite.table.DatabaseTable;
@DatabaseTable(tableName = "classes")
public class AClass {
@DatabaseField(canBeNull = false, dataType = DataType.LONG, id = true)
public long id;
@DatabaseField(canBeNull = false, defaultValue = "a class", dataType = DataType.STRING)
public String name;
@ForeignCollectionField(eager = false)
public ForeignCollection<Student> students = null;
public AClass() {
}
}
Student.java :
package zhangphil.ormlitetest.database;
import com.j256.ormlite.field.DataType;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
@DatabaseTable(tableName = "students")
public class Student {
public Student(String name, int student_id) {
this.name = name;
this.id = student_id;
}
@DatabaseField(canBeNull = false, dataType = DataType.INTEGER, id = true)
public int id;
@DatabaseField(canBeNull = false, dataType = DataType.STRING)
public String name;
@DatabaseField(canBeNull = false, foreign = true, foreignAutoRefresh = true)
public AClass aclass;
public Student() {
}
@Override
public String toString() {
return "id:" + id + " 姓名:" + name + " 所在班级:" + aclass.name;
}
}
ORMLiteDatabaseHelper.java :
package zhangphil.ormlitetest.database;
import java.sql.SQLException;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
public class ORMLiteDatabaseHelper extends OrmLiteSqliteOpenHelper {
private static ORMLiteDatabaseHelper mDatabaseHelper = null;
private Dao<AClass, Integer> mClassDao = null;
private Dao<Student, Integer> mStudentDao = null;
private final static String DataBase_NAME = "school.db";
private final static int DataBase_VERSION = 1;
public ORMLiteDatabaseHelper(Context context, String databaseName,
CursorFactory factory, int databaseVersion) {
super(context, DataBase_NAME, factory, DataBase_VERSION);
}
public static ORMLiteDatabaseHelper getInstance(Context context) {
if (mDatabaseHelper == null) {
mDatabaseHelper = new ORMLiteDatabaseHelper(context, DataBase_NAME,
null, DataBase_VERSION);
}
return mDatabaseHelper;
}
@Override
public void onCreate(SQLiteDatabase arg0, ConnectionSource connectionSource) {
Log.d(this.getClass().getName(), "ORMLite数据库 -> onCreate");
try {
TableUtils.createTableIfNotExists(connectionSource, AClass.class);
TableUtils.createTableIfNotExists(connectionSource, Student.class);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase database,
ConnectionSource connectionSource, int oldVersion, int newVersion) {
Log.i(this.getClass().getName(), "数据库 -> onUpgrade");
try {
// 删除旧的数据库表。
TableUtils.dropTable(connectionSource, AClass.class, true);
TableUtils.dropTable(connectionSource, Student.class, true);
// 重新创建新版的数据库。
onCreate(database, connectionSource);
} catch (SQLException e) {
e.printStackTrace();
}
}
public Dao<Student, Integer> getStudentDao() {
if (mStudentDao == null) {
try {
mStudentDao = getDao(Student.class);
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
}
return mStudentDao;
}
public Dao<AClass, Integer> getClassDao() {
if (mClassDao == null) {
try {
mClassDao = getDao(AClass.class);
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
}
return mClassDao;
}
@Override
public void close() {
super.close();
mClassDao = null;
mStudentDao = null;
}
}