package com.jqmobile.core.android.db.orm.base; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; import java.util.UUID; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import com.jqmobile.core.android.db.orm.BaseDBColumn; import com.jqmobile.core.android.db.orm.BaseDBTable; import com.jqmobile.core.android.db.orm.table.TableUtilFactory; import com.jqmobile.core.orm.AutoVersionControl; import com.jqmobile.core.orm.DBColumn; import com.jqmobile.core.orm.ORM; import com.jqmobile.core.orm.TableUtil; import com.jqmobile.core.orm.exception.DefferentVersionException; import com.jqmobile.core.orm.exception.ORMException; import com.jqmobile.core.orm.exception.ORMNotDBTableException; import com.jqmobile.core.orm.exception.VersionFieldTypeException; import com.jqmobile.core.utils.plain.Log; class ORMImpl<T> extends ORMSImpl implements ORM<T> { private final BaseDBTable table; private final Class<T> beanClass; /** * 初始化 * * @param conn * 数据库connection * @param c * 要操作的实体class * @throws ORMNotDBTableException * @throws ORMException */ public ORMImpl(SQLiteDatabase conn, Class<T> c) throws ORMNotDBTableException, ORMException { super(conn); this.beanClass = c; table = BaseDBTable.getInstance(c); autoValiTable(); } /** * 自动验证表 * * @throws ORMException */ private void autoValiTable() throws ORMException { TableUtil tableUtil = TableUtilFactory.instance(getConnection()); tableUtil.autoUpdateTable(beanClass); } @Override public int insert(T t) throws ORMException { getConnection().execSQL(table.getInstnerSql(), getParams(t).toArray()); return -1; } protected List<Object> getParams(T t) { List<Object> list = new ArrayList<Object>(); for (int i = 0; i < table.getMappingFields().size(); i++) { try { list.add(getParam(table.getMappingFields().get(i) .getFormatObj(t))); } catch (Exception e) { Log.getLog(getClass()).e(e); list.add(null); continue; } } return null; } @Override public int update(T t) throws ORMException { List<Object> params = getParams(t); params.add(table.getParmaryId().getFormatObj(t)); if (versionValidate(t)) { getConnection().execSQL(table.getInstnerSql(), params.toArray()); } else { try { throw new DefferentVersionException("版本不一致或不存在此记录"); } catch (DefferentVersionException e) { e.printStackTrace(); } } return -1; } @Override public int delete(String recid) throws ORMException { getConnection().execSQL(table.getDeleteSqlByPID(), new Object[] { recid }); return -1; } @Override public T find(String recid) { Cursor rs = getConnection().rawQuery(table.getFindSqlByPID(), new String[] { recid }); try { return instanceObject(rs); } catch (Exception e) { return null; } } @Override public int delete(UUID recid) throws ORMException { return delete(recid.toString()); } @Override public T find(UUID recid) { return find(recid.toString()); } // 反射放入值 /** * 反射获取返回对象结果list。数据库字段名称,必须和属性名称一致 * * @param <T> * @param c * @param rs * @return List<T> * @throws Exception */ private List<T> getList(Cursor rs) throws Exception { List<T> list = new ArrayList<T>(); List<BaseDBColumn> fields = table.getMappingFields(); for (rs.moveToFirst(); !rs.isAfterLast(); rs.moveToNext()) { list.add(instanceObject(rs, fields)); } return list; } private T instanceObject(Cursor rs, List<BaseDBColumn> fields) throws InstantiationException, IllegalAccessException { T t = beanClass.newInstance(); for (BaseDBColumn field : fields) { // if(Modifier.isFinal(field.getModifiers())){ // continue; // } // field.setAccessible(true); Object obj = field.getValue(rs); if (null == obj) { continue; } field.set(t, obj); } return t; } private T instanceObject(Cursor rs) throws Exception { if (rs.getCount() <= 0) { return null; } T t = beanClass.newInstance(); List<BaseDBColumn> fields = table.getMappingFields(); for (BaseDBColumn field : fields) { // if (Modifier.isFinal(field.getModifiers())) { // continue; // } // field.setAccessible(true); Object obj = field.getValue(rs);// getFieldValue(field, rs); if (null == obj) { continue; } field.set(t, obj); } return t; } // ===================== @Override public List<T> query(String where, Object... args) throws ORMException { Cursor rs = getConnection().rawQuery(table.getQueryRowSql(where), getParams(args)); try { return getList(rs); } catch (Exception e) { throw new ORMException(e); } finally { rs.close(); } } @Override public List<T> queryPage(String where, long startIndex, long endIndex, Object... args) throws ORMException { Cursor rs = getConnection().rawQuery( table.getQuerySql(where) + " limit " + startIndex + "," + endIndex + "", getParams(args)); try { return getList(rs); } catch (Exception e) { throw new ORMException(e); } finally { rs.close(); } } @Override public T queryFirst(String where, Object... args) throws ORMException { Cursor rs = getConnection().rawQuery(table.getQuerySql(where), getParams(args)); try { if (rs.moveToFirst()) return instanceObject(rs); return null; } catch (Exception e) { throw new ORMException(e); } finally { rs.close(); } } @Override public int queryRow(String where, Object... args) throws ORMException { Cursor rs = getConnection().rawQuery(table.getQueryRowSql(where), getParams(args)); try { if (rs.moveToFirst()) return rs.getInt(1); return 0; } catch (Exception e) { throw new ORMException(e); } finally { rs.close(); } } @Override public int update(String set, Object... args) throws ORMException { getConnection().execSQL( table.getModifySql(set), args); return -1; } @Override public int delete(String where, Object... args) throws ORMException { getConnection().execSQL( table.getDeleteSql(where), args); return -1; } @Override public List<T> getAll() throws ORMException { return query("select * from " + table.getTableName()); } /** * 版本验证 * * @param t * 实体对象 * @return */ private boolean versionValidate(T t) { boolean flag = false; // 判断是否实现版本接口 if (judgeInterface()) { // 获取类中指定的版本字段 String validateWord = getValidateWord(t); // 判断是否是日期格式 boolean isDate = isDate(validateWord); // 通过类中指定的版本字段,获取数据库中该对象对应的数据 Object dataBaseVW = getDataBaseVW(t, validateWord, isDate); // 获取对象中版本值 Object entityVW = getEntityVW(t, validateWord); // 对比比较传入的对象中的版本值和数据库读取的版本值是否一致 if (dataBaseVW != null && entityVW != null && dataBaseVW.equals(entityVW)) { return true; } } return flag; } /** * 判断是否是日期类型 * * @param validateWord * @return */ private boolean isDate(String validateWord) { Field[] fields = beanClass.getDeclaredFields(); for (Field field : fields) { if (field.getName().equals(validateWord)) { if (field.getAnnotation(DBColumn.class) != null) { return field.getAnnotation(DBColumn.class).date(); } } } return false; } /** * 获取实体对象中版本控制字段值 * * @param t * 实体对象 * @param validateWord * 指定版本字段名称 * @return */ private Object getEntityVW(T t, String validateWord) { try { Field field = beanClass.getDeclaredField(validateWord); if (field.getType() == long.class) { String entityVW = "get" + validateWord.substring(0, 1).toUpperCase() + validateWord.substring(1, validateWord.length()); Method method = beanClass.getMethod(entityVW, null); return (Object) method.invoke(t, null); } else { throw new VersionFieldTypeException("版本字段必修是long类型"); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (VersionFieldTypeException e) { e.printStackTrace(); } return null; } /** * 获取数据库中版本字段值 * * @param t * 实体对象 * @param validateWord * 指定版本字段名称 * @param isDate * @return */ private Object getDataBaseVW(T t, String validateWord, boolean isDate) { String paimaryId = getPaimaryId(t); Cursor rs = getConnection().rawQuery(table.getFindSqlByPID(), new String[] { paimaryId }); if(rs.moveToFirst()){ return rs.getLong(rs.getColumnIndex(validateWord)); } return null; } /** * 获取类中指定的版本字段 * * @param t * 实体对象 * @return */ private String getValidateWord(T t) { // TODO Auto-generated method stub try { Method method = beanClass.getMethod("getVersionWord", null); return (String) method.invoke(t, null); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } /** * 获取主键值 * * @param t * 实体对象 * @return 主键值 */ private String getPaimaryId(T t) { for (int i = 0; i < table.getMappingFields().size(); i++) { try { BaseDBColumn column = table.getMappingFields().get(i); // 判断该值是否是主键,若是主键则返回 if (column.isPaimaryId()) { String str = column.getColumnName(); String paimaryId = "get" + str.substring(0, 1).toUpperCase() + str.substring(1, str.length()); Method method = beanClass.getMethod(paimaryId, null); return (String) method.invoke(t, null); } } catch (Exception e) { Log.getLog(getClass()).e(e); continue; } } return null; } /** * 判断是否实现版本控制接口 * * @param t * 实体对象 * @return 若实现返回true,反之,返回false */ private boolean judgeInterface() { Class<?>[] classes = beanClass.getInterfaces(); for (Class<?> c : classes) { if (c.equals(AutoVersionControl.class)) { return true; } } return false; } }