【AndroidでSQLiteを制する】SQLiteDatabase#insertを使用してデータをインサートする
SQLデータベース内のテーブルにデータを挿入します。
今回はSQLiteDatabaseに定義されているインサートを行うコンビニエンスメソッドを使用します。
SQLiteを使用するActivityを実装する
今回の一連の記事で使用するActivityを実装します。public class SQLiteActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } }
DTOをContentValuesに変換するメソッドを実装する
テーブルのデータを挿入、更新する場合はContentValuesを使用します。そこで、BookDTOをContentValuesに変換するメソッドを定義します。
カラムにnullを設定する場合はカラム名を入れないようにしましょう。
BookDAO
public static ContentValues convertContentValues(BookDTO bookDTO) { ContentValues contentValues = new ContentValues(); if(bookDTO.getId() != 0) { contentValues.put(LoadToSQLiteMasterContract.Book._ID, bookDTO.getId()); } if(bookDTO.getTitle() != null) { contentValues.put(LoadToSQLiteMasterContract.Book.COLUMN_NAME_TITLE, bookDTO.getTitle()); } if(bookDTO.getSubtitle() != null) { contentValues.put(LoadToSQLiteMasterContract.Book.COLUMN_NAME_SUBTITLE, bookDTO.getSubtitle()); } return contentValues; }
SQLiteDatabase#insertを使用する
SQLiteDatabase#insertはデータベース内のテーブルにデータを挿入するコンビニエンスメソッドです。String table | データベース内のテーブル名を指定します。 |
String nullColumnHack |
SQLでは完全に空の行を挿入することは許されていません。
この引数は第3引数に空のContentValuesを指定された場合に意味を持ちます。
このメソッドはContentValuesが空の場合はインサート文を作成することができないため、この引数に適当なカラム名を指定します。
下記のようなSQLが生成されます。 INSERT INTO [table名] ([nullColumnHack]) VALUES (NULL); |
ContentValues values |
ContentValuesを使用してインサートするデータを設定して渡します。 ContentValues#putの第1引数にテーブルのカラム名を、第2引数にはデータを設定します。 |
BookDAOにinsertを実装する
また、BookDTOをContentValuesに変換するメソッドを実装します。
public static long insert(Context context , BookDTO bookDTO){ SQLiteDatabase sqLiteDatabase = getSqLiteDatabase(context,true); long rowId = sqLiteDatabase.insert( LoadToSQLiteMasterContract.Book.TABLE_NAME, COLUMN_NAME_SUBTITLE, convertContentValues(bookDTO) ); return rowId; }
SQLiteActivityにBookDAO.insertを使用するinsertBookを実装する。
このinsertBookを二回呼び出すことで制約エラーを発生させます。
しかし、特に例外は発生せず-1が戻ってきます。
@Override protected void onResume() { super.onResume(); insertBook(); insertBook(); } private void insertBook() { BookDTO book = new BookDTO(); book.setTitle("SQLiteの勉強本"); book.setSubtitle("サブタイトル : " + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime())); long rowId = BookDAO.insert(getApplicationContext() , book); Toast.makeText(this, "rowId:" + rowId , Toast.LENGTH_SHORT).show(); }
SQLiteDatabase#insertOrThrowBookを使用する
SQLiteDatabase#insertOrThrowBookはデータベース内のテーブルにデータを挿入するコンビニエンスメソッドです。String table | データベース内のテーブル名を指定します。 |
String nullColumnHack |
SQLでは完全に空の行を挿入することは許されていません。
この引数は第3引数に空のContentValuesを指定された場合に意味を持ちます。
このメソッドはContentValuesが空の場合はインサート文を作成することができないため、この引数に適当なカラム名を指定します。
下記のようなSQLが生成されます。 INSERT INTO [table名] ([nullColumnHack]) VALUES (NULL); |
ContentValues values |
ContentValuesを使用してインサートするデータを設定して渡します。 ContentValues#putの第1引数にテーブルのカラム名を、第2引数にはデータを設定します。 |
BookDAOにinsertOrThrowを実装する
public static long insertOrThrow(Context context , BookDTO bookDTO){ SQLiteDatabase sqLiteDatabase = getSqLiteDatabase(context,true); long rowId = sqLiteDatabase.insertOrThrow( LoadToSQLiteMasterContract.Book.TABLE_NAME , COLUMN_NAME_SUBTITLE, convertContentValues(bookDTO) ); return rowId; }
SQLiteActivityにBookDAO.insertOrThrowを使用するinsertOrThrowBookを実装する。
このinsertOrThrowBookを2回呼び出すことで制約エラーを発生させます。
2回目の呼び出しで一意制約違反が発生し例外が発生します。
@Override protected void onResume() { super.onResume(); insertOrThrowBook(); // 二回目は制約違反でエラーが発生するので例外終了します。 insertOrThrowBook(); } private void insertOrThrowBook() { BookDTO book = new BookDTO(); book.setId(1); book.setTitle("SQLiteの勉強本"); book.setSubtitle("サブタイトル : " + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime())); long rowId = BookDAO.insertOrThrow(getApplicationContext() , book); Toast.makeText(this, "rowId:" + rowId , Toast.LENGTH_SHORT).show(); }
SQLiteDatabase#insertWithOnConflictBookを使用する
SQLiteDatabase#insertWithOnConflictBookはデータベース内のテーブルにデータを挿入するコンビニエンスメソッドです。String table | データベース内のテーブル名を指定します。 | ||||||||||||
String nullColumnHack |
SQLでは完全に空の行を挿入することは許されていません。
この引数は第3引数に空のContentValuesを指定された場合に意味を持ちます。
このメソッドはContentValuesが空の場合はインサート文を作成することができないため、この引数に適当なカラム名を指定します。
下記のようなSQLが生成されます。 INSERT INTO [table名] ([nullColumnHack]) VALUES (NULL); |
||||||||||||
ContentValues values |
ContentValuesを使用してインサートするデータを設定して渡します。 ContentValues#putの第1引数にテーブルのカラム名を、第2引数にはデータを設定します。 |
||||||||||||
int conflictAlgorithm |
SQLiteには制約違反が発生した場合の解消アルゴリズムが複数実装されています。
この引数にはSQLiteDatabaseに定義されています。
|
BookDAOにinsertWithOnConflictを実装する。
今回はSQLiteDatabase.CONFLICT_REPLACEを使用して制約違反の原因のデータとこれから挿入するデータの置き換えを行います。
public static long insertWithOnConflict(Context context , BookDTO bookDTO){ SQLiteDatabase sqLiteDatabase = getSqLiteDatabase(context,true); long rowId = sqLiteDatabase.insertWithOnConflict( LoadToSQLiteMasterContract.Book.TABLE_NAME , COLUMN_NAME_SUBTITLE, convertContentValues(bookDTO), SQLiteDatabase.CONFLICT_REPLACE ); return rowId; }
SQLiteActivityにBookDAO.insertWithOnConflictを使用するinsertWithOnConflictBookを実装する。
このinsertWithOnConflictBookを二回呼び出すことで制約エラーを発生させます。
@Override protected void onResume() { super.onResume(); insertWithOnConflictBook(); } private void insertWithOnConflictBook() { BookDTO book = new BookDTO(); book.setId(1); book.setTitle("SQLiteの勉強本"); book.setSubtitle("サブタイトル : " + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime())); long rowId = BookDAO.insertWithOnConflict(getApplicationContext() , book); Toast.makeText(this, "rowId:" + rowId , Toast.LENGTH_SHORT).show(); }