https://developer.android.com/training/data-storage/sqlite?hl=ko
스키마 변경시, API에서 제공하는 헬퍼 클래스를 사용하며 된다
하지만 테이블 안에 사용자가 저장한 데이터가 있을 때는 그 데이터가 삭제되거나 수정되어야 할 수도 있어서 민감하다
이미 사용하고 있는 상태인지를 구별한 다음 처리해야한다
SQLiteOpenHelper 클래스는 데이터베이스를 만들거나 열기 위해 필요한 작업들을 도와주는 역할을 한다
new 연산자로 만들며, 3개의 파라미터가 들어간다
데이터베이스 파일이 만들어지도록 하려면 getReadableDatabase 또는 getWritableDatabase 메소드를 호출해야한다
이 메소드는 데이터베이스를 만들거나 업그레이드할 때 콜백 메소드가 호출된다
따라서 데이터베이스 생성, 업그레이드 등 여러가지 상황에 따라 콜백 메소드를 다시 정의하면 각각의 상태에 맞게 처리할수 있다
현재의 데이터베이스 버전이 이미 사용하고 있는 SQLiteDatabase 파일의 버전과 다를 경우에 자동으로 호출되는 onUpgrade 메소드가 있다
이 메소드는 SQLiteDatabase 객체와 함께 기존 버전 정보를 담고 있는 oldVersion, 현져 버전 정보를 담고 있는 newVersion 파라미터가 전달된다
activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPersonName" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="데이터베이스 만들기" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="textPersonName" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="테이블 만들기" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp" />
</LinearLayout>
</ScrollView>
</LinearLayout>
DatabaseHelper.java
package com.example.a61_sample_database_sqliteopenhelper;
import android.content.Context;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class DatabaseHelper extends SQLiteOpenHelper {
public static String NAME = "testDB";
public static int VERSION = 1;
public DatabaseHelper(Context context) {
// 첫번재 파라미터 - Context 객체, 액티비티 안에서 만들 경우 this로 지정 가능
// 두번째 파라미터 - 데이터베이스의 이름
// 세번째 파라미터 - 데이터 조회 시에 반환하는 커서를 만들어 낼 CoursorFactory
// 네번째 파라미터 - 정수 타입의 버전 정보, 데이터베이스 업그레이드를 위해 사용하며,
// 기존에 생성되어 있는 데이터베이스의 버전 정보와 다르게 지정하여, 데이터베이스의 스키마나 데이터를 바꿀 수 있다
super(context, NAME, null, VERSION);
}
public DatabaseHelper(Context context, int VERSION) {
super(context, NAME, null, VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
println("onCreate 호출");
String sql = "create table if not exists testTABLE (_id integer primary key autoincrement, name text, age integer, mobile text)";
// onCreate 메소드 안에서 sql문 실행
db.execSQL(sql);
}
@Override
public void onOpen(SQLiteDatabase db) {
println("onOpen 호출");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
println("onUpdate 호출 : " + oldVersion + " -> " + newVersion);
if (newVersion > oldVersion) {
db.execSQL("drop table if exists testTABLE");
}
}
public void println(String data) {
Log.d("DatabaseHelper", data);
}
}
MainActivity
package com.example.a61_sample_database_sqliteopenhelper;
import androidx.appcompat.app.AppCompatActivity;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
EditText editText;
EditText editText2;
TextView textView;
SQLiteDatabase database;
String tableName;
DatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = findViewById(R.id.editText);
editText2 = findViewById(R.id.editText2);
textView = findViewById(R.id.textView);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String databaseName = editText.getText().toString();
createDatabase(databaseName);
}
});
Button button2 = findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tableName = editText2.getText().toString();
createTable(tableName);
insertRecord();
}
});
}
// private void createDatabase(String databaseName) {
// println("createDatabase 호출됨");
//
// database = openOrCreateDatabase(databaseName, MODE_PRIVATE, null);
//
// println("데이터베이스 생성함 : " + databaseName);
// }
private void createDatabase(String databaseName) {
println("createDatabase 호출됨");
// dbHelper = new DatabaseHelper(this);
dbHelper = new DatabaseHelper(this, 2);
database = dbHelper.getWritableDatabase();
println("데이터베이스 생성함");
}
private void createTable(String tableName) {
println("createTable 호출됨");
if (database == null) {
println("데이터베이스를 먼저 생성하세요");
return;
}
// execSQL 메소드는 안드로이드 SQLite 객체에서 가장 중요한 메소드이다
// 데이터베이스가 만들어지고 나면, execSQL 메소드는 SQL문을 실행할때 사용한다
// 테이블을 만드는 것뿐만 아니라 레코드 추가처럼 표준 SQL을 사용하는 여러가지 데이터 처리가 가능하다
//
// id의 경우, 안드로이드에서는 앞에 '_'를 붙여 '_id'로 만드는 방법을 권장한다
database.execSQL("create table if not exists " + tableName + " (_id integer PRIMARY KEY autoincrement, name text, age integer, mobile text)");
println("테이블 생성함 : " + tableName);
}
private void insertRecord() {
println("insertRecord 호출됨");
if (database == null) {
println("데이터베이스를 먼저 생성하세요");
return;
}
if (tableName == null) {
println("테이블을 먼저 생성하세요");
}
database.execSQL("insert into " + tableName + " (name, age, mobile) values ('John', 20, '010-1000-1000')");
println("레코드 추가함");
}
private void println(String data) {
textView.append(data + "\n");
}
}
버전 업그레이드가 감지되어 onUpgrade 호출 시, 테이블을 드랍하도록 해놓았다
이전에 만들어둔, 기존의 DB가 있는 상황
이전에 만들어뒀을 때 버전 정보는 있지않다
// private void createDatabase(String databaseName) {
// println("createDatabase 호출됨");
//
// database = openOrCreateDatabase(databaseName, MODE_PRIVATE, null);
//
// println("데이터베이스 생성함 : " + databaseName);
// }
private void createDatabase(String databaseName) {
println("createDatabase 호출됨");
dbHelper = new DatabaseHelper(this);
// dbHelper = new DatabaseHelper(this, 2);
database = dbHelper.getWritableDatabase();
println("데이터베이스 생성함");
}
onCreate와 onOpen이 호출되고 onUpgare는 호출되지 않았다
테이블도 그대로 있다
버전 2로 생성
private void createDatabase(String databaseName) {
println("createDatabase 호출됨");
// dbHelper = new DatabaseHelper(this);
dbHelper = new DatabaseHelper(this, 2);
database = dbHelper.getWritableDatabase();
println("데이터베이스 생성함");
}
onUpdate 메소드가 호출되었다
테이블도 드랍되었다
이전에 openOrCreateDatabase로 생성 시, 버전 정보 없이 데이터베이스 객체가 생성되지만,
SQLiteOpenHelper 클래스로 새로 생성 하면서 버전 값을 정해주면, 기존 데이터베이스의 객체에 버전 값이 넘겨지는게 확인되었다
'안드로이드' 카테고리의 다른 글
내용 제공자 (0) | 2021.10.30 |
---|---|
데이터 조회하기 (0) | 2021.10.30 |
Database Inspector (0) | 2021.10.29 |
안드로이드 SQLite (0) | 2021.10.29 |
영화 정보 가져와 보여주기 (0) | 2021.10.28 |