Android数据库小技巧

Android数据库小技巧
 
一、执行SQL
    相对于封装过的ContentProvider,使用原生SQL执行效率高,所以建议使用rawQuery、execSQL。
 
二、代理事务
    假设继承SQLiteOpenHelper的数据库操作类为DatabaseHelper。当它有比较多的方法都需要事务操作时,可以提取这些方法为一个接口,如ITransactionHandler,之后让DatabaseHelper实现。这样即可通过代理来统一完成事务操作!
 

  1. /*  
  2.  * 代理执行需要事物处理的数据库操作方法  
  3.  *   
  4.  * 使用方式如下:  
  5.  * DatabaseHelper mHelper = new DatabaseHelper(context);  
  6.  * ITransactionHandler proxyHandler = (ITransactionHandler) TransactionHandler  
  7.  *     .newProxyInstance(mHelper);  
  8.  * proxyHandler.resetDB();  
  9.  */ 
  10. public class TransactionHandler implements InvocationHandler {  
  11.  
  12.     private static final String TAG = "TransactionHandler";  
  13.     public static final boolean LOGD = true;  
  14.  
  15.     // 数据库操作帮助类  
  16.     private DatabaseHelper mDatabaseHelper;  
  17.  
  18.     public TransactionHandler(DatabaseHelper helper) {  
  19.         this.mDatabaseHelper = helper;  
  20.     }  
  21.  
  22.     // 返回代理类的实例  
  23.     public static Object newProxyInstance(DatabaseHelper helper) {  
  24.         // 直接使用Proxy的静态方法,返回代理实例  
  25.         return Proxy.newProxyInstance(helper.getClass().getClassLoader(),  
  26.                 helper.getClass().getInterfaces(), new TransactionHandler(  
  27.                         helper));  
  28.     }  
  29.  
  30.     // 实现InvocationHandler接口方法,做自己的处理操作  
  31.     @Override 
  32.     public Object invoke(Object proxy, Method method, Object[] args)  
  33.             throws Throwable {  
  34.         long start = System.currentTimeMillis(); // 开始时间戳  
  35.         Object result = null// 方法返回结果  
  36.         SQLiteDatabase mDatabase = mDatabaseHelper.getWritableDatabase(); // 数据库操作对象  
  37.         mDatabase.beginTransaction(); // 开始事务  
  38.         try {  
  39.             // 代理执行数据库操作方法  
  40.             result = method.invoke(mDatabaseHelper, args);  
  41.             // 执行事务操作(到结束事务间不能再进行数据库操作)  
  42.             mDatabase.setTransactionSuccessful();  
  43.         } catch (Exception e) {  
  44.             e.printStackTrace();  
  45.             /*  
  46.              * 注意:这里设false是由于我每个操作数据方法都返回的是boolean。  
  47.              * 1)要增加不同的类型,可以用instanceof判断  
  48.              * 2)在invoke内出问题没返回result对象的情况,可考虑把异常分开捕获,或者判null  
  49.              */ 
  50.             result = false;  
  51.         } finally {  
  52.             mDatabase.endTransaction(); // 结束事务  
  53.         }  
  54.         long end = System.currentTimeMillis(); // 结束时间戳  
  55.         if (LOGD)  
  56.             Log.d(TAG, "==" + method.getName() + " method lasts " 
  57.                     + (end - start) + "ms==");  
  58.         return result;  
  59.     }  
  60.  
    更多代理内容,可以参看《Java 动态代理》。
 
三、文件SQL
    执行一个SQL文件,以初始化数据等。可以把sql文件放在res/raw目录内。sql文注释方式,简易为“—”开头的行或“/*”“*/”开始的两行中间。
 

  1. public class SqlUtil {  
  2.  
  3.     private final String commentPrefix = "--";  
  4.     private final String prefix = "/*";  
  5.     private final String suffix = "*/";  
  6.     private boolean isComment = false;  
  7.  
  8.     private Context mContext;  
  9.     private SQLiteDatabase db;  
  10.  
  11.     public SqlUtil(Context context, SQLiteDatabase db) {  
  12.         mContext = context;  
  13.         this.db = db;  
  14.     }  
  15.  
  16.     // 执行raw内的简易sql文件  
  17.     public void execute(int rawId) {  
  18.         BufferedReader reader = null;  
  19.         try {  
  20.             InputStream is = mContext.getResources().openRawResource(rawId);  
  21.             reader = new BufferedReader(new InputStreamReader(is));  
  22.             for (String s; (s = reader.readLine()) != null;) {  
  23.                 if (s.startsWith(commentPrefix)) {  
  24.                     continue;  
  25.                 }  
  26.                 if (s.startsWith(prefix)) {  
  27.                     isComment = true;  
  28.                     continue;  
  29.                 }  
  30.                 if (s.startsWith(suffix)) {  
  31.                     isComment = false;  
  32.                     continue;  
  33.                 }  
  34.                 if (isComment) {  
  35.                     continue;  
  36.                 }  
  37.                 db.execSQL(s);  
  38.             }  
  39.         } catch (IOException e) {  
  40.             e.printStackTrace();  
  41.         } finally {  
  42.             try {  
  43.                 if (null != reader) {  
  44.                     reader.close();  
  45.                 }  
  46.             } catch (IOException e) {  
  47.             }  
  48.         }  
  49.     }  
  50.  
 
四、后记
    其他的话,暂时应该没什么了…


     本文转自winorlose2000 51CTO博客,原文链接:http://blog.51cto.com/vaero/900853,如需转载请自行联系原作者




上一篇:Android老司机搬砖小技巧


下一篇:错误Batch update returned unexpected row count from update [0]; actual row count: 0;