您的位置:首页 > 数据库

搭建自己的SQLiteDataBase框架(五)

2016-11-17 11:16 316 查看

搭建自己的SQLiteDataBase框架(五)

一对多关系,同样也有两种关系,1,关联表存储对应关系,2,直接数据库操作增删改查

此时实体类的对应模型如下:

@Table(name = "developer")
public class Developer implements Serializable {
private static final long serialVersionUID = 1L;
@Column(id = true)
private String id;
@Column
private String name;
@Column
private int age;
@Column(type = Column.ColumnType.SERIALIZABLE)
private ArrayList<Skill> skills;
}

@Table(name = "company")
public class Company {
@Column(id = true)
private String id;
@Column
private String name;
@Column
private String url;
@Column
private String tel;
@Column
private String address;

private String group;
//添加一对多关系
@Column(type = Column.ColumnType.TMANY,autoRefresh=true)
private ArrayList<Developer> developers;
}

即:一个company可以对应多个developer,这个关系要理清


完善建表语句,相比之前变化略大:

public static void createTable(SQLiteDatabase db, Class<?> clz) throws SQLException {
System.out.println(getCreateTableStmt(clz));
ArrayList<String> stmts = getCreateTableStmt(clz);
for (String stmt : stmts) {
db.execSQL(stmt);
}
}

//建表语句,以Company为例说明
private static ArrayList<String> getCreateTableStmt(Class<?> clz) {
StringBuilder mColumnStmts = new StringBuilder();
ArrayList<String> stmts = new ArrayList<String>();
if (clz.isAnnotationPresent(Table.class)) {
Field[] fields = clz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
if (fields[i].isAnnotationPresent(Column.class)) {
if (fields[i].getAnnotation(Column.class).type() == Column.ColumnType.TMANY) {
//建关联表语句,create table if not exists company_developers( pk1 TEXT,pk2 TEXT)
stmts.add("create table if not exists " + getAssociationTableName(clz, fields[i].getName()) + "(" + PK1 + " TEXT, " + PK2
+ " TEXT)");
}
mColumnStmts.append(getOneColumnStmt(fields[i]));
mColumnStmts.append(",");
}
}
if (mColumnStmts.length() > 0) {
mColumnStmts.delete(mColumnStmts.length() - 2, mColumnStmts.length());
}
}
// create table if not exists company (id TEXT primary key,...)
stmts.add("create table if not exists " + getTableName(clz) + " (" + mColumnStmts + ")");
return stmts;
}

//获取关联表 表名
public static String getAssociationTableName(Class<?> clz, String association) {
return getTableName(clz) + "_" + association;
}


完善增删改查:

public <T> void newOrUpdate(T t) {
ContentValues contentValues = new ContentValues();
try {
String idValue = (String) id_field_.get(t);
for (Field field : fields) {
if (field.isAnnotationPresent(Column.class)) {
field.setAccessible(true);
Class<?> clz = field.getType();
if (clz == String.class) {
System.out.println("key:" + DBUtils.getColumnName(field) + ",value:" + field.get(t).toString());
contentValues.put(DBUtils.getColumnName(field), field.get(t).toString());
} else if (clz == int.class || clz == Integer.class) {
contentValues.put(DBUtils.getColumnName(field), field.getInt(t));
} else {
Column column = field.getAnnotation(Column.class);
Column.ColumnType columnType = column.type();
if (!TextUtils.isValidate(columnType.name())) {
throw new IllegalArgumentException("you should set  type to the special column:" + t.getClass().getSimpleName() + "." + field.getName());
}
if (columnType == Column.ColumnType.SERIALIZABLE) {
contentValues.put(DBUtils.getColumnName(field), SerializeUtil.serialize(field.get(t)));
} else if (columnType == Column.ColumnType.TONE) {
Object tone = field.get(t);
if (tone == null) {
continue;
}
if (column.autoRefresh()) {
// save object to related table
DBManager.getInstance().getDao(tone.getClass()).newOrUpdate(tone);

}
if (tone.getClass().isAnnotationPresent(Table.class)) {
String idName = DBUtils.getIDColumnName(tone.getClass());
Field id_field = tone.getClass().getDeclaredField(idName);
id_field.setAccessible(true);
contentValues.put(DBUtils.getColumnName(field), id_field.get(tone).toString());
}
} else if (columnType == Column.ColumnType.TMANY) {//添加一对多关系
List<Object> tmany = (List<Object>) field.get(t);
if (!TextUtils.isValidate(tmany)) {
continue;
}
//先清空再插入
String associationTable = DBUtils.getAssociationTableName(t.getClass(), field.getName());
delete(associationTable, "pk1=?", new String[]{idValue});
ContentValues assosiationValues = new ContentValues();
for (Object object : tmany) {
if (column.autoRefresh()) {
DBManager.getInstance().getDao(object.getClass()).newOrUpdate(object);
}
assosiationValues.clear();
assosiationValues.put(DBUtils.PK1, idValue);
String idName = DBUtils.getIDColumnName(object.getClass());
Field idField = object.getClass().getDeclaredField(idName);
idField.setAccessible(true);
assosiationValues.put(DBUtils.PK2, idField.get(object).toString());
newOrUpdate(associationTable, assosiationValues);
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("newOrUpdate:" + e.toString());
}
newOrUpdate(mTableName, contentValues);
}

//删除关联数据
public void delete(String id) {
try {
delete(mTableName, mIdName + "=?", new String[]{id});
//delete related association data
for (Field field : mForeignds) {
delete(DBUtils.getAssociationTableName(clz, field.getName()), "pk1=?", new String[]{id});
}
} catch (Exception e) {
System.out.println(e.toString());
}
}

//
public T queryById(String id) {
Cursor cursor = rawQuery(mTableName, mIdName + "=?", new String[]{id});
T t = null;
if (cursor.moveToNext()) {
try {
t = clz.newInstance();
for (Field field : fields) {
if (field.isAnnotationPresent(Column.class)) {
field.setAccessible(true);
Class<?> clazz = field.getType();
if (clazz == int.class || clazz == Integer.class) {
field.setInt(t, cursor.getInt(cursor.getColumnIndex(DBUtils.getColumnName(field))));
} else if (clazz == String.class) {
field.set(t, cursor.getString(cursor.getColumnIndex(DBUtils.getColumnName(field))));
} else {
// TONE columnType.newInstance -- setId--set to T (lazy load)
// Serializable deserializable to object --set to T (lazy load)
Column column = field.getAnnotation(Column.class);
Column.ColumnType columnType = column.type();
if (!TextUtils.isValidate(columnType.name())) {
throw new IllegalArgumentException("you should set  type to the special column:" + t.getClass().getSimpleName() + "." + field.getName());
}
if (columnType == Column.ColumnType.SERIALIZABLE) {
field.set(t, SerializeUtil.deserialize(cursor.getBlob(cursor.getColumnIndex(DBUtils.getColumnName(field)))));
} else if (columnType == Column.ColumnType.TONE) {
String idtone = cursor.getString(cursor.getColumnIndex(DBUtils.getColumnName(field)));
if (!TextUtils.isValidate(idtone)) {
continue;
}
Object tone = null;
if (column.autoRefresh()) {
//去数据库查询
tone = DBManager.getInstance().getDao(field.getType()).queryById(idtone);
} else {
tone = field.getType().newInstance();
if (field.getType().isAnnotationPresent(Table.class)) {
String idName = DBUtils.getIDColumnName(field.getType());
Field id_field = field.getType().getDeclaredField(idName);
id_field.setAccessible(true);
id_field.set(tone, idtone);
}
}
field.set(t, tone);
} else if (columnType == Column.ColumnType.TMANY) {//添加一对多关系
//获取List<T>中的T
Class realatedClass = (Class) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
Cursor tmanyCursor = db.rawQuery("select * from " + DBUtils.getAssociationTableName(clz, field.getName()) + " where " + DBUtils.PK1 + " =?", new String[]{id});
List list = new ArrayList();
String tmanyId = null;
Object tmany = null;
while (tmanyCursor.moveToNext()) {
tmanyId = tmanyCursor.getString(tmanyCursor.getColumnIndex(DBUtils.PK2));
if (column.autoRefresh()) {
tmany = DBManager.getInstance().getDao(realatedClass).queryById(tmanyId);
} else {
tmany = realatedClass.newInstance();
String idName = DBUtils.getIDColumnName(realatedClass);
Field id_field = realatedClass.getDeclaredField(idName);
id_field.setAccessible(true);
id_field.set(tmany, tmanyId);
}
list.add(tmany);
}
if (!TextUtils.isValidate(list)) {
continue;
}
field.set(t, list);
}

}

}
}

} catch (Exception e) {
e.printStackTrace();
System.out.println("queryById:" + e.toString());
}
}
return t;
}


测试一下:

public void add() {
Company company = new Company();
company.setId("00001");
company.setName("stay4it");
company.setUrl("www.stay4it.com");
company.setTel("10086");
company.setAddress("Shanghai");
Developer developer = new Developer();
developer.setId("00001");
developer.setName("Stay");
developer.setAge(17);
Skill skill = new Skill();
skill.setName("coding");
skill.setDesc("android");
ArrayList<Skill> skills = new ArrayList<Skill>();
skills.add(skill);
developer.setSkills(skills);
ArrayList<Developer> developers = new ArrayList<Developer>();
developers.add(developer);
company.setDevelopers(developers);
DBManager.getInstance().getDao(Company.class).newOrUpdate(company);
}

public void queryCompanyById() {
Company company = DBManager.getInstance().getDao(Company.class).queryById("00001");
if (company != null) {
System.out.println(company.toString());
}
}

看下日志输出:

11-17 11:18:43.812 26469-26469/project.charles.com.myapplication I/System.out: id:00001,name:stay4it,url:www.stay4it.com,tel:10086,address:Shanghai,developers[{"age":17,"id":"00001","name":"Stay","skills":[{"desc":"android","name":"coding"}]}]


接下来还有多对多的关系…

至此,DB框架的大体结构就成型了,后续就是在项目使用中的维护,扩展了,从简至繁,一步一步就构造出了一个简易的DB框架,如果只是轻量级使用SQLiteDataBase,自己搭建一个架子也就足够了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据库