利用反射,注解获取建表的sql

前言:因为项目很老,还是用的原生sqlite,因为建表还是手动构建sql,cursor转bean或者list都不灵活,特此用反射注解做了优化处理

首先创建我们的标注,有TableName,Primary,NotNull,DefaultText,DefaultInt,DefaultDecimal,Autoincrement

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName {
    public String tableName();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Primary {
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotNull {
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DefaultText {
    public String defaultVal();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DefaultInt {
    public int defaultVal();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DefaultDecimal {
    public double defaultVal();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autoincrement {
}

然后创建我们的Book类

@TableName(tableName = "book")
public class Book {

    @DefaultText(defaultVal = "世纪创奇")
    private String name;

    @Primary
    @Autoincrement
    private int id;

    @DefaultInt(defaultVal = 2)
    private int pages;

    @DefaultDecimal(defaultVal = 2.24)
    private double price;

    @NotNull
    private String mem;

    private long date;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getPages() {
        return pages;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getMem() {
        return mem;
    }

    public void setMem(String mem) {
        this.mem = mem;
    }

    public long getDate() {
        return date;
    }

    public void setDate(long date) {
        this.date = date;
    }
}

最后创建DbUtil类

public class DbUtil {
    private static final String TAG = "DbUtil";
    public static final Map<Class<?>, String> TYPES;

    static {
        //基本类型
        TYPES = new HashMap<Class<?>, String>();
        TYPES.put(byte.class, "BYTE");
        TYPES.put(boolean.class, "INTEGER");
        TYPES.put(short.class, "SHORT");
        TYPES.put(int.class, "INTEGER");
        TYPES.put(long.class, "LONG");
        TYPES.put(String.class, "TEXT");
        TYPES.put(byte[].class, "BLOB");
        TYPES.put(float.class, "FLOAT");
        TYPES.put(double.class, "DOUBLE");

        //包装类型
        TYPES.put(Byte.class, "BYTE");
        TYPES.put(Boolean.class, "INTEGER");
        TYPES.put(Short.class, "SHORT");
        TYPES.put(Integer.class, "INTEGER");
        TYPES.put(Long.class, "LONG");
        TYPES.put(String.class, "TEXT");
        TYPES.put(byte[].class, "BLOB");
        TYPES.put(Float.class, "FLOAT");
        TYPES.put(Double.class, "DOUBLE");

    }

    /**
     * 根据类结构构造表。
     */
    public static String getTableBuildingSQL(Class<?> clazz) {
        StringBuilder strBuilder = new StringBuilder("create table if not exists ");

        if (clazz.isAnnotationPresent(TableName.class)) {
            String tableName = clazz.getAnnotation(TableName.class).tableName();
            strBuilder.append(tableName);
        } else {
            strBuilder.append(clazz.getSimpleName());
        }
        strBuilder.append("(");
        // getDeclaredFields():获取该类文件中声明的字段
        // getFields():获取该类public声明字段
        Field[] arrField = clazz.getDeclaredFields();
        for (int i = arrField.length - 1; i >= 0; i--) {
            Field f = arrField[i];
            String type = TYPES.get(f.getType());
            if (type == null) {
                continue;
            } else {
                strBuilder.append(f.getName() + " " + type);

                if (f.isAnnotationPresent(Primary.class)) {
                    strBuilder.append(" primary key ");
                }
                if (f.isAnnotationPresent(DefaultText.class)) {
                    String val = f.getAnnotation(DefaultText.class).defaultVal();
                    strBuilder.append(" DEFAULT \"" + val + "\"");
                }
                if (f.isAnnotationPresent(DefaultInt.class)) {
                    Object val = f.getAnnotation(DefaultInt.class).defaultVal();
                    strBuilder.append(" DEFAULT " + val);
                }
                if (f.isAnnotationPresent(DefaultDecimal.class)) {
                    Object val = f.getAnnotation(DefaultDecimal.class).defaultVal();
                    strBuilder.append(" DEFAULT " + val);
                }
                if (f.isAnnotationPresent(Autoincrement.class)) {
                    strBuilder.append(" AUTOINCREMENT");
                }
                if(f.isAnnotationPresent(NotNull.class)){
                    strBuilder.append(" NOT NULL");
                }

                if (i > 0) {
                    strBuilder.append(",");
                }
            }
        }
        strBuilder.append(")");
        return strBuilder.toString();
    }

    /**
     * 构造插入Contvalues
     *
     * @param bean
     * @return
     */
    public static ContentValues translate2ContentValues(Object bean) {
        ContentValues cv = new ContentValues();
        Field[] arrField = bean.getClass().getDeclaredFields();
        try {
            for (Field f : arrField) {
                if (f.isAccessible() == false) {
                    f.setAccessible(true);
                }
                //排除自動增長的字段
                if (f.isAnnotationPresent(Autoincrement.class)) {
                    continue;
                }

                String name = f.getName();
                Object value = f.get(bean);

                if (value instanceof Byte) {
                    cv.put(name, (Byte) value);
                } else if (value instanceof Short) {
                    cv.put(name, (Short) value);
                } else if (value instanceof Integer) {
                    cv.put(name, (Integer) value);
                } else if (value instanceof Long) {
                    cv.put(name, (Long) value);
                } else if (value instanceof String) {
                    cv.put(name, (String) value);
                } else if (value instanceof byte[]) {
                    cv.put(name, (byte[]) value);
                } else if (value instanceof Boolean) {
                    cv.put(name, (Boolean) value);
                } else if (value instanceof Float) {
                    cv.put(name, (Float) value);
                } else if (value instanceof Double) {
                    cv.put(name, (Double) value);
                }
            }
        } catch (Exception e) {
            Log.e(TAG,"translate2ContentValues error:" + e.getMessage());
        }
        return cv;
    }

    /**
     * 从cursor中提取bean
     *
     * @param cursor
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> T cursorToBean(Cursor cursor, Class<T> cls) {
        T bean = null;
        if (cursor != null && cursor.getCount() > 0) {
            Field[] fields = cls.getDeclaredFields();
            String[] columns = cursor.getColumnNames();
            try {
                while (cursor.moveToNext()) {
                    bean = cls.newInstance();
                    for (String column : columns) {
                        Field field = findFieldByName(fields, column);
                        if (field != null) {
                            String letter = column.substring(0, 1).toUpperCase();
                            String setter = "set" + letter + column.substring(1);
                            Method setMethod = cls.getMethod(setter, new Class[]{field.getType()});
                            setMethod.invoke(bean, getValueByField(cursor, column, field));
                        }

                    }
                }
            } catch (Exception e) {
                Log.e(TAG,"cursorToBean error:" + e.getMessage());
            }finally {
                cursor.close();
            }
        }
        return bean;
    }

    /**
     * 从cursor中提取bean 列表
     *
     * @param cursor
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> List<T> cursorToBeans(Cursor cursor, Class<T> cls) {
        List<T> beans = new ArrayList<T>();
        if (cursor != null && cursor.getCount() > 0) {
            Field[] fields = cls.getDeclaredFields();
            String[] columns = cursor.getColumnNames();
            try {
                while (cursor.moveToNext()) {
                    T bean = cls.newInstance();
                    for (String column : columns) {
                        Field field = findFieldByName(fields, column);
                        if (field != null) {
                            String letter = column.substring(0, 1).toUpperCase();
                            String setter = "set" + letter + column.substring(1);
                            Method setMethod = cls.getMethod(setter, new Class[]{field.getType()});
                            setMethod.invoke(bean, getValueByField(cursor, column, field));
                        }

                    }
                    beans.add(bean);
                }
            } catch (Exception e) {
                Log.e(TAG,"cursorToBeans error:" + e.getMessage());
            }finally {
                cursor.close();
            }
        }
        return beans;
    }

    /**
     * 根据字段取出值
     *
     * @param cursor
     * @param columnName
     * @param field
     * @return
     */
    private static Object getValueByField(Cursor cursor, String columnName, Field field) {
        int index = cursor.getColumnIndex(columnName);
        if (index == -1) return null;// 如果不存在此列则返回null
        Class fieldClass = field.getType();
        // 根据属性类型从Cursor中获取值
        if (fieldClass == String.class) return cursor.getString(index);

        else if (fieldClass == int.class || fieldClass == Integer.class)
            return cursor.getInt(index);
        else if (fieldClass == Long.class || fieldClass == long.class)
            return cursor.getLong(index);

        else if (fieldClass == Double.class || fieldClass == double.class)
            return cursor.getDouble(index);

        else if (fieldClass == Float.class || fieldClass == float.class)
            return cursor.getFloat(index);

        else if (fieldClass == Short.class || fieldClass == short.class)
            return cursor.getShort(index);

        return null;
    }

    private static Field findFieldByName(Field[] fields, String name) {
        for (Field field : fields) {
            if (field.getName().equals(name)) {
                return field;
            }
        }
        return null;
    }
}

注释已经解释了每个方法的作用。demo可以通过这个链接下载,http://download.csdn.net/download/hanshengjian/9771886,这是个module

猜你喜欢

转载自blog.csdn.net/hanshengjian/article/details/60578632