package com.salama.android.datacore; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; import com.salama.android.util.SSLog; import android.util.Log; import MetoXML.XmlDeserializer; import MetoXML.Base.XmlParseException; import MetoXML.Util.PropertyDescriptor; public class DBDataUtil { private SqliteUtil _sqliteUtil; private static final String DataTableSettingName = "DataTableSetting"; /** * 构造函数 * @param sqlUtil SqliteUtil实例 * @throws SqliteUtilException */ public DBDataUtil(SqliteUtil sqlUtil) throws SqliteUtilException { this._sqliteUtil = sqlUtil; checkDataTableSetting(); } private void checkDataTableSetting() throws SqliteUtilException { if(!isTableExists(DataTableSettingName)) { createTableDirectly(DataTableSetting.class, "tableName"); } } /** * 取得SqliteUtil实例 * @return SqliteUtil实例 */ public SqliteUtil getSqliteUtil() { return this._sqliteUtil; } /** * 关闭数据库连接 */ public void close() { try { _sqliteUtil.close(); _sqliteUtil = null; } catch(Exception e) { } } /** * 表是否存在 * @param tableName 表名 * @return true:存在 false:不存在 */ public boolean isTableExists(String tableName) { int count = this._sqliteUtil .executeIntScalar("select count(1) from sqlite_master where type='table' and upper(name) = '" + tableName.toUpperCase() + "'; "); if (count > 0) { return true; } else { return false; } } /** * 删除表 * @param tableName 表名 */ public void dropTable(String tableName) { dropTableDirectly(tableName); deleteDataTableSetting(tableName); } private void dropTableDirectly(String tableName) { _sqliteUtil.executeUpdate("drop table if exists " + tableName); } /** * 创建表 * @param tableCls 表对应的data类型 * @param primaryKeys 主键信息。格式为逗号分隔多个主键。 * @throws SqliteUtilException */ public void createTable(Class<?> tableCls, String primaryKeys) throws SqliteUtilException { createTableDirectly(tableCls, primaryKeys); insertDataTableSetting(tableCls.getSimpleName(), primaryKeys); } private void createTableDirectly(Class<?> tableCls, String primaryKeys) throws SqliteUtilException { String tableName = tableCls.getSimpleName(); List<PropertyDescriptor> propertyList = PropertyInfoUtil.getPropertyInfoList(tableCls); StringBuilder sql = new StringBuilder(); sql.append("create table "); sql.append(tableName); sql.append(" ( "); PropertyDescriptor propDesc = null; String dbType = ""; Class<?> colClass = null; for (int i = 0; i < propertyList.size(); i++) { propDesc = propertyList.get(i); colClass = propDesc.getPropertyType(); if(colClass == String.class) { dbType = "TEXT"; } else if(colClass.isPrimitive()) { if(colClass == int.class || colClass == Integer.class || colClass == long.class || colClass == Long.class || colClass == short.class || colClass == Short.class || colClass == byte.class || colClass == Byte.class ) { dbType = "INTEGER"; } else { dbType = "REAL"; } } else { dbType = "TEXT"; } if (i != 0) { sql.append(","); } sql.append(propDesc.getDisplayName()).append(" ").append(dbType); } if (primaryKeys != null && !"".equals(primaryKeys)) { sql.append(",").append(" primary key ") .append(" ( ").append(primaryKeys).append(")"); } sql.append(")"); _sqliteUtil.executeUpdate(sql.toString()); } public void createTable(TableDesc tableDesc) throws SqliteUtilException { createTableDirectly(tableDesc); insertDataTableSetting(tableDesc.getTableName(), tableDesc.getPrimaryKeys()); } private void createTableDirectly(TableDesc tableDesc) { String tableName = tableDesc.getTableName(); StringBuilder sql = new StringBuilder(); sql.append("create table "); sql.append(tableName); sql.append(" ( "); ColDesc colDesc = null; String colType = null; String dbType = ""; for (int i = 0; i < tableDesc.getColDescList().size(); i++) { colDesc = tableDesc.getColDescList().get(i); colType = colDesc.getColType().toLowerCase(); if(colType.equals("text")) { dbType = "TEXT"; } else if (colType.equals("real")) { dbType = "REAL"; } else { dbType = "INTEGER"; } if (i != 0) { sql.append(","); } sql.append(colDesc.getColName()).append(" ").append(dbType); } if (tableDesc.getPrimaryKeys() != null && tableDesc.getPrimaryKeys().length() > 0) { sql.append(",").append(" primary key ") .append(" ( ").append(tableDesc.getPrimaryKeys()).append(")"); } sql.append(")"); _sqliteUtil.executeUpdate(sql.toString()); } /** * 插入记录 * @param tableName 表名 * @param data 数据实例 * @return 1:正常 0:出错 * @throws SqliteUtilException */ public int insertData(String tableName, Object data) throws SqliteUtilException { List<String> propertyList; Object propertyValue = null; propertyList = PropertyInfoUtil.getPropertyNameList(data.getClass()); StringBuilder sql = new StringBuilder(); sql.append("insert into "); sql.append(tableName); sql.append(" ( "); for (int i = 0; i < propertyList.size(); i++) { if (i != 0) { sql.append(","); } sql.append(propertyList.get(i)); } sql.append(") "); sql.append("values"); sql.append(" ( "); for (int i = 0; i < propertyList.size(); i++) { if (i != 0) { sql.append(", "); } sql.append("'"); propertyValue = getPropertyValue(data, propertyList.get(i)); sql.append(SqliteUtil.encodeQuoteChar(SqliteUtil.convertObjectToString(propertyValue))); sql.append("'"); } sql.append(")"); return _sqliteUtil.executeUpdate(sql.toString()); } /** * 插入数据 * @param tableName 表名 * @param dataCls 对应的数据类型 * @param dataXml 记录的Xml内容 * @return 1:正常 0:出错 * @throws IOException * @throws XmlParseException * @throws InvocationTargetException * @throws IllegalAccessException * @throws InstantiationException * @throws NoSuchMethodException * @throws SqliteUtilException */ public int insertData(String tableName, Class<?> dataCls, String dataXml) throws IOException, XmlParseException, InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException, SqliteUtilException { Object data = XmlDeserializer.stringToObject(dataXml, dataCls); return insertData(tableName, data); } /** * 插入或更新记录(记录已存在时更新) * @param tableName 表名 * @param data 数据实例 * @return 1:正常 0:出错 * @throws SqliteUtilException */ public int insertOrUpdateDataByPK(String tableName, Object data) throws SqliteUtilException { int success = 0; try { success = insertData(tableName, data); } catch (SqliteUtilException e) { } if(success == 0) { try { success = updateDataByPK(tableName, data); } catch (SqliteUtilException e) { Log.e("DBDataUtil", "", e); } } return success; } /** * 根据主键更新记录 * @param tableName 表名 * @param data 数据实例 * @return 1:正常 0:出错 * @throws SqliteUtilException */ public int updateDataByPK(String tableName, Object data) throws SqliteUtilException { Object propertyValue = null; String[] primaryKeysArray = getPrimaryKeySet(tableName); List<String> propertyList = PropertyInfoUtil.getPropertyNameList(data.getClass()); StringBuilder sql = new StringBuilder(); sql.append("update "); sql.append(tableName); sql.append(" set "); int index = 0; for (int i = 0; i < propertyList.size(); i++) { if(isInPrimaryKey(primaryKeysArray, propertyList.get(i))) { continue; } if (index != 0) { sql.append(", "); } sql.append(propertyList.get(i)).append(" = ").append("'"); propertyValue = getPropertyValue(data, propertyList.get(i)); sql.append(SqliteUtil.encodeQuoteChar(SqliteUtil.convertObjectToString(propertyValue))); sql.append("'"); index++; } if (primaryKeysArray.length > 0) { sql.append(" where "); for (int i = 0; i < primaryKeysArray.length; i++) { if (i != 0) { sql.append(" and "); } sql.append(primaryKeysArray[i]).append(" = ").append("'"); propertyValue = getPropertyValue(data, primaryKeysArray[i]); sql.append(SqliteUtil.encodeQuoteChar(SqliteUtil.convertObjectToString(propertyValue))); sql.append("'"); } } return _sqliteUtil.executeUpdate(sql.toString()); } /** * 根据主键更新记录 * @param dataCls 数据类型 * @param tableName 表名 * @param dataXml 数据Xml内容 * @return 1:正常 0:出错 * @throws SqliteUtilException */ public int updateDataByPK(Class<?> dataCls, String tableName, String dataXml) throws SqliteUtilException { try { Object data = XmlDeserializer.stringToObject(dataXml, dataCls); return updateDataByPK(tableName, data); } catch (IOException e) { throw new SqliteUtilException(e); } catch (XmlParseException e) { throw new SqliteUtilException(e); } catch (InvocationTargetException e) { throw new SqliteUtilException(e); } catch (IllegalAccessException e) { throw new SqliteUtilException(e); } catch (InstantiationException e) { throw new SqliteUtilException(e); } catch (NoSuchMethodException e) { throw new SqliteUtilException(e); } } /** * 根据主键删除数据 * @param tableName 表名 * @param data 数据实例 * @return 1:正常 0:出错 * @throws SqliteUtilException */ public int deleteDataByPK(String tableName, Object data) throws SqliteUtilException { Object propertyValue = null; String[] primaryKeysArray = getPrimaryKeySet(tableName); StringBuilder sql = new StringBuilder(); sql.append("delete "); sql.append(" from "); sql.append(tableName); if (primaryKeysArray.length > 0) { sql.append(" where "); for (int i = 0; i < primaryKeysArray.length; i++) { if (i != 0) { sql.append(" and "); } sql.append(primaryKeysArray[i]).append(" = ").append("'"); propertyValue = getPropertyValue(data, primaryKeysArray[i]); sql.append(SqliteUtil.encodeQuoteChar(SqliteUtil.convertObjectToString(propertyValue))); sql.append("'"); } } return _sqliteUtil.executeUpdate(sql.toString()); } /** * 根据主键删除记录 * @param dataCls 数据类型 * @param tableName 表名 * @param dataXml 数据Xml内容 * @return 1:正常 0:出错 * @throws SqliteUtilException */ public int deleteDataByPK(Class<?> dataCls, String tableName, String dataXml) throws SqliteUtilException { try { Object data = XmlDeserializer.stringToObject(dataXml, dataCls); return deleteDataByPK(tableName, data); } catch (IOException e) { throw new SqliteUtilException(e); } catch (XmlParseException e) { throw new SqliteUtilException(e); } catch (InvocationTargetException e) { throw new SqliteUtilException(e); } catch (IllegalAccessException e) { throw new SqliteUtilException(e); } catch (InstantiationException e) { throw new SqliteUtilException(e); } catch (NoSuchMethodException e) { throw new SqliteUtilException(e); } } /** * 删除所有记录 * @param tableName 表名 * @return 1:正常 0:出错 */ public int deleteAllData(String tableName) { StringBuilder sql = new StringBuilder(); sql.append("delete ").append(" from ").append(tableName); return _sqliteUtil.executeUpdate(sql.toString()); } /** * 根据主键查询 * @param tableName 表名 * @param data 数据实例(只需包含主键信息) * @return 查询结果数据实例 * @throws SqliteUtilException */ public Object findDataByPK(String tableName, Object data) throws SqliteUtilException { Object propertyValue = null; //List<String> propertyList = PropertyInfoUtil.getPropertyNameList(data.getClass()); String[] primaryKeysArray = getPrimaryKeySet(tableName); StringBuilder sql = new StringBuilder(); sql.append("select * "); /* for (int i = 0; i < propertyList.size(); i++) { if (i != 0) { sql.append(", "); } sql.append(propertyList.get(i)); } */ sql.append(" from "); sql.append(tableName); if (primaryKeysArray.length > 0) { sql.append(" where "); for (int i = 0; i < primaryKeysArray.length; i++) { if (i != 0) { sql.append(" and "); } sql.append(primaryKeysArray[i]).append(" = ").append("'"); propertyValue = getPropertyValue(data, primaryKeysArray[i]); //SSLog.d("DBDataUtil", "findDataByPK() pk:" + primaryKeysArray[i]); sql.append(SqliteUtil.encodeQuoteChar(SqliteUtil.convertObjectToString(propertyValue))); sql.append("'"); } } return _sqliteUtil.findData(sql.toString(), data.getClass()); } /** * 根据主键查询 * @param dataCls 数据类型 * @param tableName 表名 * @param dataXml 数据Xml内容 * @return 查询结果数据实例 * @throws SqliteUtilException */ public Object findDataByPK(Class<?> dataCls, String tableName, String dataXml) throws SqliteUtilException { try { Object data = XmlDeserializer.stringToObject(dataXml, dataCls); return findDataByPK(tableName, data); } catch (IOException e) { throw new SqliteUtilException(e); } catch (XmlParseException e) { throw new SqliteUtilException(e); } catch (InvocationTargetException e) { throw new SqliteUtilException(e); } catch (IllegalAccessException e) { throw new SqliteUtilException(e); } catch (InstantiationException e) { throw new SqliteUtilException(e); } catch (NoSuchMethodException e) { throw new SqliteUtilException(e); } } /** * 根据主键查询数据 * @param tableName 表名 * @param data 数据实例 * @return 数据Xml内容 * @throws SqliteUtilException */ public String findDataXmlByPK(String tableName, Object data) throws SqliteUtilException { Object propertyValue = null; //List<String> propertyList = PropertyInfoUtil.getPropertyNameList(data.getClass()); String[] primaryKeysArray = getPrimaryKeySet(tableName); StringBuilder sql = new StringBuilder(); sql.append("select * "); /* for (int i = 0; i < propertyList.size(); i++) { if (i != 0) { sql.append(", "); } sql.append(propertyList.get(i)); } */ sql.append(" from "); sql.append(tableName); if (primaryKeysArray.length > 0) { sql.append(" where "); for (int i = 0; i < primaryKeysArray.length; i++) { if (i != 0) { sql.append(" and "); } sql.append(primaryKeysArray[i]).append(" = ").append("'"); propertyValue = getPropertyValue(data, primaryKeysArray[i]); sql.append(SqliteUtil.encodeQuoteChar(SqliteUtil.convertObjectToString(propertyValue))); sql.append("'"); } } return _sqliteUtil.findDataXml(sql.toString(), data.getClass()); } /** * 根据主键查询 * @param dataCls 数据类型 * @param tableName 表名 * @param dataXml 数据Xml内容(只需包含主键信息) * @return 数据Xml内容 * @throws SqliteUtilException */ public String findDataXmlByPK(Class<?> dataCls, String tableName, String dataXml) throws SqliteUtilException { try { Object data = XmlDeserializer.stringToObject(dataXml, dataCls); return findDataXmlByPK(tableName, data); } catch (IOException e) { throw new SqliteUtilException(e); } catch (XmlParseException e) { throw new SqliteUtilException(e); } catch (InvocationTargetException e) { throw new SqliteUtilException(e); } catch (IllegalAccessException e) { throw new SqliteUtilException(e); } catch (InstantiationException e) { throw new SqliteUtilException(e); } catch (NoSuchMethodException e) { throw new SqliteUtilException(e); } } /** * 查询所有数据 * @param tableCls 数据类型 * @return 数据列表 * @throws SqliteUtilException */ public List<?> findAllData(Class<?> tableCls) throws SqliteUtilException { StringBuilder sql = new StringBuilder(); sql.append("select * from ").append(tableCls.getSimpleName()); return _sqliteUtil.findDataList(sql.toString(), tableCls); } /** * 查询所有数据 * @param tableCls 数据类型 * @return 数据列表Xml内容 */ public String findAllDataXml(Class<?> tableCls) { StringBuilder sql = new StringBuilder(); sql.append("select * from ").append(tableCls.getSimpleName()); return _sqliteUtil.findDataListXml(sql.toString(), tableCls); } /** * 查询更新时间晚于指定时间的数据 * @param tableCls 数据类型 * @param updateTime 指定的时间 * @return 数据列表 * @throws SqliteUtilException */ public List<?> findDataAfterUpdateTime(Class<?> tableCls, long updateTime) throws SqliteUtilException { StringBuilder sql = new StringBuilder(); sql.append("select * "); sql.append(" from "); sql.append(tableCls.getSimpleName()); sql.append(" where updateTime = '").append(String.valueOf(updateTime)).append("'"); return _sqliteUtil.findDataList(sql.toString(), tableCls); } /** * 查询更新时间晚于指定时间的数据 * @param tableCls 数据类型 * @param updateTime 指定的时间 * @return 数据列表Xml内容 * @throws SqliteUtilException */ public String findDataXmlAfterUpdateTime(Class<?> tableCls, long updateTime) throws SqliteUtilException { StringBuilder sql = new StringBuilder(); sql.append("select * "); sql.append(" from "); sql.append(tableCls.getSimpleName()); sql.append(" where updateTime = '").append(String.valueOf(updateTime)).append("'"); return _sqliteUtil.findDataListXml(sql.toString(), tableCls); } /** * 获取表定义 * @param tableName 表名 * @return 表定义 * @throws SqliteUtilException */ public DataTableSetting getDataTableSetting(String tableName) throws SqliteUtilException { String sql = "select * from DataTableSetting where tableName = '" + tableName + "'"; return (DataTableSetting) _sqliteUtil.findData(sql, DataTableSetting.class); } private void insertDataTableSetting(String tableName, String primaryKeys) throws SqliteUtilException { DataTableSetting tableSetting = new DataTableSetting(); tableSetting.setTableName(tableName); tableSetting.setTableType(DataTableSetting.DATA_TABLE_TYPE_CUSTOMIZE); tableSetting.setPrimaryKeys(primaryKeys); insertData(DataTableSettingName, tableSetting); } private void deleteDataTableSetting(String tableName) { StringBuilder sql = new StringBuilder(); sql.append(" delete DataTableSetting from where tableName = '").append(tableName).append("'"); _sqliteUtil.executeUpdate(sql.toString()); } private String[] getPrimaryKeySet(String tableName) { StringBuilder sql = new StringBuilder(); sql.append(" select "); sql.append(" primaryKeys "); sql.append(" from "); sql.append(" DataTableSetting "); sql.append(" where tableName = ").append(" '").append(tableName).append("'"); String primaryKeys = _sqliteUtil.executeStringScalar(sql.toString()); return primaryKeys.split(","); } private boolean isInPrimaryKey(String[] primaryKeysArray, String colName) { for(int i = 0; i < primaryKeysArray.length; i++) { if(primaryKeysArray[i].equalsIgnoreCase(colName)) { return true; } } return false; } private Object getPropertyValue(Object data, String properyName) throws SqliteUtilException { Method getMethod = null; Object value = null; PropertyDescriptor pd; try { pd = new PropertyDescriptor(properyName, data.getClass()); getMethod = pd.getReadMethod(); } catch (NoSuchMethodException e1) { return null; } try { if (getMethod != null) { value = getMethod.invoke(data); } } catch (IllegalArgumentException e) { throw new SqliteUtilException(e); } catch (IllegalAccessException e) { throw new SqliteUtilException(e); } catch (InvocationTargetException e) { throw new SqliteUtilException(e); } return value; } }