搭建自己的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,自己搭建一个架子也就足够了
相关文章推荐
- 搭建自己的SQLiteDataBase框架(二)
- 搭建自己的SQLiteDataBase框架(三)
- 搭建自己的SQLiteDataBase框架(四)
- 搭建自己的SQLiteDataBase框架(-)
- PHP搭建自己的web框架-程序初始化
- 架构探险读书笔记——自己搭建轻量级javaWeb框架之MVC和IOC
- 利用Admin-LTE项目搭建自己前端的开发框架模板
- 创业互联网公司如何搭建自己的技术框架
- 从零搭建自己的Vue框架(1) —— 技术栈介绍及框架整理
- 辛星浅析windows下搭建rails框架的sqlite的一个问题
- 创业互联网公司如何搭建自己的技术框架[转-2016]
- 手把手教你如何搭建一个自己的安卓快速开发框架之带你做自己的APP(三)
- 搭建自己的第一个SpringBoot框架(2)
- 创业互联网公司如何搭建自己的技术框架
- Windows环境搭建Web自己主动化測试框架Watir(基于Ruby)
- 搭建自己的框架之2:MVP+Rxjava2,封装自己的mvp框架
- 01 自己搭建类似vue-cli 框架
- 总结自己重新搭建SSM框架中遇到的几种奇葩问题
- 自己动手搭建ava通用开发框架之三—通用权限模型建立