/* * Copyright (C) 2012 www.amsoft.cn * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.ab.db.orm; import java.lang.reflect.Field; import java.sql.Blob; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import android.database.sqlite.SQLiteDatabase; import android.util.Log; import com.ab.db.orm.annotation.Column; import com.ab.db.orm.annotation.Id; import com.ab.db.orm.annotation.Relations; import com.ab.db.orm.annotation.Table; import com.ab.util.AbStrUtil; // TODO: Auto-generated Javadoc /** * © 2012 amsoft.cn * 名称:AbTableHelper.java * 描述:数据库辅助类 * * @author 还如一梦中 * @version v1.0 * @date:2013-5-23 上午10:10:53 */ public class AbTableHelper { /** 日志标记. */ private static final String TAG = "AbTableHelper"; /** * 根据映射的对象创建表. * * @param <T> the generic type * @param db 数据库对象 * @param clazzs 对象映射 */ public static <T> void createTablesByClasses(SQLiteDatabase db,Class<?>[] clazzs) { for (Class<?> clazz : clazzs){ createTable(db, clazz); } } /** * 根据映射的对象删除表. * * @param <T> the generic type * @param db 数据库对象 * @param clazzs 对象映射 */ public static <T> void dropTablesByClasses(SQLiteDatabase db,Class<?>[] clazzs) { for (Class<?> clazz : clazzs){ dropTable(db, clazz); } } /** * 创建表. * * @param <T> the generic type * @param db 根据映射的对象创建表. * @param clazz 对象映射 */ public static <T> void createTable(SQLiteDatabase db, Class<T> clazz) { String tableName = ""; if (clazz.isAnnotationPresent(Table.class)) { Table table = (Table) clazz.getAnnotation(Table.class); tableName = table.name(); } if(AbStrUtil.isEmpty(tableName)){ Log.d(TAG, "想要映射的实体["+clazz.getName()+"],未注解@Table(name=\"?\"),被跳过"); return; } StringBuilder sb = new StringBuilder(); sb.append("CREATE TABLE ").append(tableName).append(" ("); List<Field> allFields = AbTableHelper.joinFieldsOnlyColumn(clazz.getDeclaredFields(), clazz.getSuperclass().getDeclaredFields()); for (Field field : allFields) { if (!field.isAnnotationPresent(Column.class)) { continue; } Column column = (Column) field.getAnnotation(Column.class); String columnType = ""; if (column.type().equals("")) columnType = getColumnType(field.getType()); else { columnType = column.type(); } sb.append(column.name() + " " + columnType); if (column.length() != 0) { sb.append("(" + column.length() + ")"); } //实体类定义为Integer类型后不能生成Id异常 if ((field.isAnnotationPresent(Id.class)) && ((field.getType() == Integer.TYPE) || (field.getType() == Integer.class))) sb.append(" primary key autoincrement"); else if (field.isAnnotationPresent(Id.class)) { sb.append(" primary key"); } sb.append(", "); } sb.delete(sb.length() - 2, sb.length() - 1); sb.append(")"); String sql = sb.toString(); Log.d(TAG, "create table [" + tableName + "]: " + sql); db.execSQL(sql); } /** * 删除表. * * @param <T> the generic type * @param db 根据映射的对象创建表. * @param clazz 对象映射 */ public static <T> void dropTable(SQLiteDatabase db, Class<T> clazz) { String tableName = ""; if (clazz.isAnnotationPresent(Table.class)) { Table table = (Table) clazz.getAnnotation(Table.class); tableName = table.name(); } String sql = "DROP TABLE IF EXISTS " + tableName; Log.d(TAG, "dropTable[" + tableName + "]:" + sql); db.execSQL(sql); } /** * 获取列类型. * * @param fieldType the field type * @return 列类型 */ private static String getColumnType(Class<?> fieldType) { if (String.class == fieldType) { return "TEXT"; } if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) { return "INTEGER"; } if ((Long.TYPE == fieldType) || (Long.class == fieldType)) { return "BIGINT"; } if ((Float.TYPE == fieldType) || (Float.class == fieldType)) { return "FLOAT"; } if ((Short.TYPE == fieldType) || (Short.class == fieldType)) { return "INT"; } if ((Double.TYPE == fieldType) || (Double.class == fieldType)) { return "DOUBLE"; } if (Blob.class == fieldType) { return "BLOB"; } return "TEXT"; } /** * 合并Field数组并去重,并实现过滤掉非Column字段,和实现Id放在首字段位置功能. * * @param fields1 属性数组1 * @param fields2 属性数组2 * @return 属性的列表 */ public static List<Field> joinFieldsOnlyColumn(Field[] fields1, Field[] fields2) { Map<String, Field> map = new LinkedHashMap<String, Field>(); for (Field field : fields1) { // 过滤掉非Column定义的字段 if (!field.isAnnotationPresent(Column.class)) { continue; } Column column = (Column) field.getAnnotation(Column.class); map.put(column.name(), field); } for (Field field : fields2) { // 过滤掉非Column定义的字段 if (!field.isAnnotationPresent(Column.class)) { continue; } Column column = (Column) field.getAnnotation(Column.class); if (!map.containsKey(column.name())) { map.put(column.name(), field); } } List<Field> list = new ArrayList<Field>(); for (String key : map.keySet()) { Field tempField = map.get(key); // 如果是Id则放在首位置. if (tempField.isAnnotationPresent(Id.class)) { list.add(0, tempField); } else { list.add(tempField); } } return list; } /** * 合并Field数组并去重. * * @param fields1 属性数组1 * @param fields2 属性数组2 * @return 属性的列表 */ public static List<Field> joinFields(Field[] fields1, Field[] fields2) { Map<String, Field> map = new LinkedHashMap<String, Field>(); for (Field field : fields1) { // 过滤掉非Column和Relations定义的字段 if (field.isAnnotationPresent(Column.class)) { Column column = (Column) field.getAnnotation(Column.class); map.put(column.name(), field); }else if(field.isAnnotationPresent(Relations.class)){ Relations relations = (Relations) field.getAnnotation(Relations.class); map.put(relations.name(), field); } } for (Field field : fields2) { // 过滤掉非Column和Relations定义的字段 if (field.isAnnotationPresent(Column.class)) { Column column = (Column) field.getAnnotation(Column.class); if (!map.containsKey(column.name())) { map.put(column.name(), field); } }else if(field.isAnnotationPresent(Relations.class)){ Relations relations = (Relations) field.getAnnotation(Relations.class); if (!map.containsKey(relations.name())) { map.put(relations.name(), field); } } } List<Field> list = new ArrayList<Field>(); for (String key : map.keySet()) { Field tempField = map.get(key); // 如果是Id则放在首位置. if (tempField.isAnnotationPresent(Id.class)) { list.add(0, tempField); } else { list.add(tempField); } } return list; } }