2011/05/30 0 コメント

Android - SQLiteでの複数レコード挿入

複数のレコードを追加するためのメソッドを作成しました。
conflictAlgorithm には, SQLiteDatabase.CONFLICT_NONE, SQLiteDatabase.CONFLICT_REPLACE などの, コンフリクトが発生した場合の処理を指定します。
また, transaction を true にした場合は, トランザクション処理を併用します。

  1. /** 
  2.  * insert a lot of data 
  3.  * 
  4.  * @param nullColumnHack  
  5.  * @param valueList 値のリスト 
  6.  * @param conflictAlgorithm コンフリクト発生時の処理 
  7.  * @param transaction トランザクション処理を併用するか否か 
  8.  * @return Boolean 成功 or 失敗 
  9.  */  
  10. public Boolean insertMany(SQLiteDatabase db , String table , String nullColumnHack, List<ContentValues> valueList, int conflictAlgorithm, Boolean transaction) {  
  11.       
  12.     if(valueList != null && valueList.size() > 0){  
  13.         String[] CONFLICT_VALUES = new String[]{""" OR ROLLBACK "" OR ABORT "" OR FAIL "" OR IGNORE "" OR REPLACE "};  
  14.   
  15.         // At first, create sql statement  
  16.         ContentValues initialValues = valueList.get(0);  
  17.           
  18.         // Measurements show most sql lengths <= 152  
  19.         StringBuilder sql_build = new StringBuilder(152);  
  20.         sql_build.append("INSERT");  
  21.         sql_build.append(CONFLICT_VALUES[conflictAlgorithm]);  
  22.         sql_build.append(" INTO ");  
  23.         sql_build.append(table);  
  24.         // Measurements show most values lengths < 40  
  25.         StringBuilder values = new StringBuilder(40);  
  26.   
  27.         Set<Map.Entry<String, Object>> entrySet = null;  
  28.           
  29.         if (initialValues != null && initialValues.size() > 0) {  
  30.             entrySet = initialValues.valueSet();  
  31.             Iterator<Map.Entry<String, Object>> entriesIter = entrySet.iterator();  
  32.             sql_build.append('(');  
  33.   
  34.             boolean needSeparator = false;  
  35.             while (entriesIter.hasNext()) {  
  36.                 if (needSeparator) {  
  37.                     sql_build.append(", ");  
  38.                     values.append(", ");  
  39.                 }  
  40.                 needSeparator = true;  
  41.                 Map.Entry<String, Object> entry = entriesIter.next();  
  42.                 sql_build.append(entry.getKey());  
  43.                 values.append('?');  
  44.             }  
  45.             sql_build.append(')');  
  46.         } else {  
  47.             sql_build.append("(" + nullColumnHack + ") ");  
  48.             values.append("NULL");  
  49.         }  
  50.   
  51.         sql_build.append(" VALUES(");  
  52.         sql_build.append(values);  
  53.         sql_build.append(");");  
  54.         String sql = sql_build.toString();  
  55.           
  56.         SQLiteStatement statement = null;  
  57.           
  58.         // if transaction id true, beginTransaction()  
  59.         if(transaction){  
  60.             db.beginTransaction();  
  61.         }  
  62.         try {  
  63.             for(int i=0,length=valueList.size(); i<length; i++){  
  64.                 statement = db.compileStatement(sql);  
  65.                 initialValues = valueList.get(i);  
  66.                 entrySet = initialValues.valueSet();  
  67.                   
  68.                 // Bind the values  
  69.                 if (entrySet != null) {  
  70.                     int size = entrySet.size();  
  71.                     Iterator<Map.Entry<String, Object>> entriesIter = entrySet.iterator();  
  72.                     for (int j = 0; j < size; j++) {  
  73.                         Map.Entry<String, Object> entry = entriesIter.next();  
  74.                         DatabaseUtils.bindObjectToProgram(statement, j + 1, entry.getValue());  
  75.                     }  
  76.                 }  
  77.                 // Run the program and then cleanup  
  78.                 statement.execute();  
  79.                 statement.close();  
  80.             }  
  81.               
  82.             // if transaction id true, setTransactionSuccessful()  
  83.             if(transaction){  
  84.                 db.setTransactionSuccessful();  
  85.                 db.endTransaction();  
  86.                 transaction = false;  
  87.             }  
  88.             return true;  
  89.         } catch (SQLiteDatabaseCorruptException e) {  
  90.             throw e;  
  91.         } finally {  
  92.             if (statement != null) {  
  93.                 statement.close();  
  94.             }  
  95.             // if transaction id true, endTransaction()  
  96.             if(transaction){  
  97.                 db.endTransaction();  
  98.             }  
  99.         }  
  100.     }  
  101.     return false;  
  102. }  
2011/05/10 0 コメント

Android - SQLite 文字列ソート

SQLiteの文字列ソートにおいて (SQLiteに限らず) , かな, 英字, 数字, 記号 の順番を群単位で変えたい場合は, そのためのフィールドを追加するのが一番簡単っぽい。というより、これしか思い浮かばなかった。

デフォルトだと<数字, 英字 .... >という順番だったが, ワードの頭文字に対して<かな, 記号(その他), 数字, 英語> という順番にソートしたかった。そこで, sortgroupというフィールドを目的のテーブルに作成する。

sortgroupの値は, 半角カナ → 1, 記号(その他) → 2, 数字 → 3, 英字 → 4 とする。

こうすれば, SELECT * FROM table ORDER BY sortgroup ASC みたいにすれば取ってこれるよね。

で、頭文字がどのタイプのものかを判別するためのプログラムは以下

  1. public class CheckWordType {  
  2.     // 文字列が 半角カタカナ(1), その他(2), 数字(3), アルファベット(4)のどれかを調べる  
  3.     public int checkCharType(char c){  
  4.         if(c >= 0xff66 && c <= 0xff9d){ // 半角カタカナ (1) http://ash.jp/code/unitbl1.htm 参照  
  5.             return 1;  
  6.         }else if(Character.isLetter(c)){ // アルファベット (4)  
  7.             return 4;  
  8.         }else if(Character.isDigit(c)){ // 数字 (3)  
  9.             return 3;  
  10.         }else// その他 (2)  
  11.             return 2;  
  12.         }  
  13.     }  
  14. }  

まぁ、まとめるほどの事でもないんだけど、書く記事がなかったんでw
 
;