反射类:获取bean的属性和属性的对应值
public class ReflectUtil {
public static String[] getFields(Class clz) {
Field[] fields = clz.getDeclaredFields();
String[] names = new String[fields.length];
for (int i = 0; i < fields.length; i++) {
names[i] = fields[i].getName();
}
return names;
}
public static <T> Map<String, String> getFieldsAndValue(Class<T> clz, T data) throws Exception {
Map<String, String> map = new HashMap<String, String>();
Field[] fields = clz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
String name = fields[i].getName();
fields[i].setAccessible(true);
if (fields[i].get(data) == null) {
map.put(name, null);
} else {
map.put(name, fields[i].get(data).toString());
}
fields[i].setAccessible(false);
}
return map;
}
}
public class SqliteUtil {
public static final String DB_NAME="abc.db";
public static final int DB_VERSION = 3;
public static final String TABLE_AA = "aa";
private static DatabaseHelper dbHelper;
private static boolean isRun; //标识是否需要使用db
public static void createDatabase(Context context) {
dbHelper = new DatabaseHelper(context);
useDB();
}
public static void useDB() {
isRun = true;
}
public static void releaseDB() {
isRun = false;
}
/**
* insert 和 update
* @param table
* @param clz
* @param data
*/
public static synchronized <T> void update(String table, Class<T> clz, T data) {
if (!isRun) return;
dbHelper.getWritableDatabase().close();
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
try {
Map<String, String> map = ReflectUtil.getFieldsAndValue(clz, data);
for (String key : map.keySet()) {
values.put(key, map.get(key));
}
db.beginTransaction();
db.replace(table, null, values);//记录中有则update,无则insert
db.setTransactionSuccessful();
} catch (Exception e) {
e.printStackTrace();
} finally {
db.endTransaction();
db.close();
}
}
public static synchronized void delete(String table, String whereClause, String[] whereArgs) {
dbHelper.getWritableDatabase().close();
SQLiteDatabase db = dbHelper.getWritableDatabase();
try {
db.beginTransaction();
db.delete(table, whereClause, whereArgs);
db.setTransactionSuccessful();
} catch (Exception e) {
e.printStackTrace();
} finally {
db.endTransaction();
db.close();
}
}
public static synchronized <T> List<T> query(String table, Class<T> clz, String selection, String[] selectionArgs) {
List<T> list = new ArrayList<T>();
if (!isRun) return list;
SQLiteDatabase db = dbHelper.getReadableDatabase();
T instance = null;
try {
Constructor<T> constructor = clz.getConstructor();
Cursor cursor = db.query(table, null, selection, selectionArgs, null, null, null);
while (cursor.moveToNext()) {
instance = constructor.newInstance();
Field[] fields = clz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
String value = cursor.getString(cursor.getColumnIndex(fields[i].getName()));
fields[i].setAccessible(true);
fields[i].set(instance, value);
fields[i].setAccessible(false);
}
list.add(instance);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
db.close();
}
return list;
}
public static class DatabaseHelper extends SQLiteOpenHelper{
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// db.execSQL("DROP TABLE IF EXISTS aa");
String execSql = "CREATE TABLE " + TABLE_AA + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, ";
String[] fields = ReflectUtil.getFields(DataAA.class);
for (int i = 0; i <fields.length; i++) {
execSql += fields[i] + " VARCHAR,"; //默认可以为空
}
execSql = execSql.substring(0, execSql.length() - 1) + ")"; //建表
db.execSQL(execSql);
execSql = "CREATE UNIQUE INDEX unique_index_aa ON "+TABLE_AA+" (url)"; //建唯一索引
db.execSQL(execSql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < 3) {
db.execSQL("alter table " + TABLE_AA + " add col1 VARCHAR null");
db.execSQL("alter table " + TABLE_AA + " add col2 VARCHAR null");
}
}
}
}
—————————————————————
自己手写了下,用在项目里了。在此备注下
关于isRun属性:可能退出程序后,db还在被循环执行时,或者说在一个线程中被不断执行时,需要停止db操作
可能db没有正确close,所以每次操作先close下
onUpdate中 执行更新版本的操作:添加列、移除表等等
每次传table名,是有点好麻烦的:可在javabean中加个注解表名,反射时传入class<T>,拿到表名
db的开关,耗资源的:所以对于CRUD操作应该都有 操作一条数据和多条数据的方法,这里缺失了一些...