package com.litesuits.orm.db.utils; import android.database.Cursor; import com.litesuits.android.log.Log; import com.litesuits.orm.db.assit.Checker; import com.litesuits.orm.db.model.EntityTable; import com.litesuits.orm.db.model.Property; import java.io.*; import java.lang.reflect.Field; import java.util.Date; /** * SQLite支持的数据类型 * 类型描述摘自sqlite官网 http://sqlite.org/datatype3.html * * @author mty * @date 2013-6-10下午5:28:10 */ public class DataUtil implements Serializable { public static final String TAG = DataUtil.class.getSimpleName(); private static final long serialVersionUID = 6668874253056236676L; /** * NULL. The value is a NULL value. */ public static final String NULL = " NULL "; /** * INTEGER. The value is a signed integer, stored in 1, 2, 3, 4, 6, or 8 * bytes depending on the magnitude of the value. */ public static final String INTEGER = " INTEGER "; /** * REAL. The value is a floating point value, stored as an 8-byte IEEE * floating point number. */ public static final String REAL = " REAL "; /** * TEXT. The value is a text string, stored using the database encoding * (UTF-8, UTF-16BE or UTF-16LE). */ public static final String TEXT = " TEXT "; /** * BLOB. The value is a blob of data, stored exactly as it was input. */ public static final String BLOB = " BLOB "; /** * Value returned by {@link #getType(Object)} if the specified column is null */ public static final int FIELD_TYPE_NULL = 0; /** * Value returned by {@link #getType(Object)} if the specified column type is * integer or long */ public static final int FIELD_TYPE_LONG = 1; /** * Value returned by {@link #getType(Object)} if the specified column type is * float or double */ public static final int FIELD_TYPE_REAL = 2; /** * Value returned by {@link #getType(Object)} if the specified column type is * string */ public static final int FIELD_TYPE_STRING = 3; /** * Value returned by {@link #getType(Object)} if the specified column type is * blob */ public static final int FIELD_TYPE_BLOB = 4; /** * Value returned by {@link #getType(Object)} if the specified column type is * date */ public static final int FIELD_TYPE_DATE = 5; /** * Value returned by {@link #getType(Object)} if the specified column type is * serializable */ public static final int FIELD_TYPE_SERIALIZABLE = 6; /** * Returns data type of the given object. * <p> * Returned column types are * <ul> * <li>{@link #FIELD_TYPE_NULL}</li> * <li>{@link #FIELD_TYPE_LONG}</li> * <li>{@link #FIELD_TYPE_REAL}</li> * <li>{@link #FIELD_TYPE_STRING}</li> * <li>{@link #FIELD_TYPE_BLOB}</li> * <li>{@link #FIELD_TYPE_DATE}</li> * <li>{@link #FIELD_TYPE_SERIALIZABLE}</li> * </ul> * </p> * * @param obj * @return */ public static int getType(Object obj) { if (obj == null) { return FIELD_TYPE_NULL; } else if (obj instanceof CharSequence || obj instanceof Boolean || obj instanceof Character) { return FIELD_TYPE_STRING; } else if (obj instanceof Float || obj instanceof Double) { return FIELD_TYPE_REAL; } else if (obj instanceof Number) { return FIELD_TYPE_LONG; } else if (obj instanceof Date) { return FIELD_TYPE_DATE; } else if (obj instanceof byte[]) { return FIELD_TYPE_BLOB; } else if (obj instanceof Serializable) { return FIELD_TYPE_SERIALIZABLE; } else { return FIELD_TYPE_NULL; } } public static String getSQLDataType(Field f) { Class<?> type = f.getType(); if (type == String.class) { return TEXT; } else if (type == boolean.class || type == Boolean.class) { return TEXT; } else if (type == double.class || type == Double.class) { return REAL; } else if (type == float.class || type == Float.class) { return REAL; } else if (type == long.class || type == Long.class) { return INTEGER; } else if (type == int.class || type == Integer.class) { return INTEGER; } else if (type == short.class || type == Short.class) { return INTEGER; } else if (type == byte.class || type == Byte.class) { return INTEGER; } else if (type == byte[].class || type == Byte[].class) { return BLOB; } else if (type == char.class || type == Character.class) { return TEXT; } else if (type == Date.class) { return INTEGER; } else if (Serializable.class.isAssignableFrom(f.getType())) { return BLOB; } else { return TEXT; } } /** * 将Cursor的数据注入模型 * 支持11种基本类型,见{@link ClassUtil#isBaseDataType(Class)} ()} * 同时支持序列化对象 * * @param c 数据库Cursor * @param entity 实体对象 * @throws Exception */ public static void injectDataToObject(Cursor c, Object entity, EntityTable table) throws Exception { Field f; Property p; for (int i = 0, size = c.getColumnCount(); i < size; i++) { String col = c.getColumnName(i); p = null; if (!Checker.isEmpty(table.pmap)) { p = table.pmap.get(col); } if (p == null && table.key != null && col.equals(table.key.column)) { p = table.key; } if (p == null) { if (Log.isPrint) Log.w(TAG, "数据库字段[" + col + "]已在实体中被移除"); continue; } f = p.field; f.setAccessible(true); Class<?> type = f.getType(); if (type == String.class) { f.set(entity, c.getString(i)); } else if (type == boolean.class || type == Boolean.class) { f.set(entity, Boolean.parseBoolean(c.getString(i))); } else if (type == double.class || type == Double.class) { f.set(entity, c.getDouble(i)); } else if (type == float.class || type == Float.class) { f.set(entity, c.getFloat(i)); } else if (type == long.class || type == Long.class) { f.set(entity, c.getLong(i)); } else if (type == int.class || type == Integer.class) { f.set(entity, c.getInt(i)); } else if (type == short.class || type == Short.class) { f.set(entity, c.getShort(i)); } else if (type == byte.class || type == Byte.class) { if (c.getString(i) != null) { f.set(entity, Byte.parseByte(c.getString(i))); } } else if (type == byte[].class || type == Byte[].class) { f.set(entity, c.getBlob(i)); } else if (type == char.class || type == Character.class) { String value = c.getString(i); if (!Checker.isEmpty(value)) { f.set(entity, value.charAt(0)); } } else if (type == Date.class) { f.set(entity, new Date(c.getLong(i))); } else if (c.getType(i) == Cursor.FIELD_TYPE_BLOB) { byte[] bytes = c.getBlob(i); if (bytes != null) { //序列化的对象 f.set(entity, byteToObject(bytes)); } } } } /** * byte[] 转为 对象 * * @param bytes * @return */ public static Object byteToObject(byte[] bytes) throws Exception { ObjectInputStream ois = null; try { ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); return ois.readObject(); } finally { if(ois !=null) ois.close(); } } /** * 对象 转为 byte[] * * @param obj * @return */ public static byte[] objectToByte(Object obj) throws IOException { ObjectOutputStream oos = null; try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(bos); oos.writeObject(obj); return bos.toByteArray(); } finally { if(oos != null)oos.close(); } } }