DB ํ๋ก์ ํธ
๊ทธ๋ฃน ๊ด๋ฆฌ
[์ฐธ๊ณ ] ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐฉ๋ฒ
๋ฐฉ๋ฒ | ์ค๋ช |
๊ณต์ ํ๋ ํผ๋ฐ์ค(Shared Preferences) | ํค-๊ฐ ์(key-value pair)์ผ๋ก ๋ฐ์ดํฐ ์ ์ฅ |
๋ด๋ถ ์ ์ฅ(Internal Storage) | ๋ด๋ถ ์ ์ฅ์์ ์ ์ฅ |
์ธ๋ถ ์ ์ฅ(External Storage) | ์ธ๋ถ ์ ์ฅ์์ ์ ์ฅ |
๋ฐ์ดํฐ๋ฒ ์ด์ค(Database) | ๊ตฌ์กฐํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ |
๋คํธ์ํฌ ์ฐ๊ฒฐ(Network Connection) | ๋ฐ์ดํฐ๋ฅผ ๋คํธ์ํฌ ์๋ฒ์ ์ ์ฅ |
- ๋ด๋ถ ์ ์ฅ์์ ๊ฒฝ์ฐ, ์ฌ์ฉ์๊ฐ ์ฑ ์ ๊ฑฐํ๋ฉด ํ์ผ๋ ๊ฐ์ด ์ ๊ฑฐ๋จ
- ์ธ๋ถ์ ์ฅ: SD์นด๋ ๊ฐ์ ์ธ๋ถ ์ ์ฅ์ ํ์. ๋ชจ๋ ์ฑ๋ค์ด ๋ค ์ ๊ทผํ ์ ์์(๊ณต์ ํ์ํ ํ์ผ์ ์ ํฉ)
- ๋ด๋ถ์ ์ธ๋ถ๋ฅผ ๊ตฌ๋ถํ๋ ๊ฐ์ฅ ํฐ ํน์ง: permission
- ๋ด๋ถ: permission ํ์ ์์
- ์ธ๋ถ: ๋ฐ๋์ permission ํ์(์ ๊ทผํ๊ธฐ ์ํด)
- ๋ฐ์ดํฐ๋ฒ ์ด์ค: SQLite์ ๊ฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋งํจ
- ์๋ฒ์ ํด๋ผ์ด์ธํธ ํต์ ์ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์
๋ฐ์ดํฐ ๋ฒ ์ด์ค ๊ธฐ๋ณธ ๊ฐ๋
๋ฐ์ดํฐ๋ฒ ์ด์ค
์๋ก ๊ด๋ จ๋ ๋ฐ์ดํฐ๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ๊ตฌ์กฐํํ์ฌ ์ ์ฅํ๋ ๊ฒ
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ฆฌ ์์คํ
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ฆฌ ์์คํ (DataBase Management System, DBMS)
- ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ด๋ฆฌํด์ฃผ๋ ์์คํ ๋๋ ์ํํธ์จ์ด
- ๋ฐ์ดํฐ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉ์๋ค์ด ์ดํดํ๊ธฐ ์ฝ๊ฒ ๋ฐ์ดํฐ๋ฅผ ํ ์ด๋ธ ํํ๋ก ํํํ ๊ฒ
- DBMS์๋ ์ฌ๋ฌ ๊ฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ง๋ค ์ ์์ผ๋ฉฐ, ํ๋์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์๋ ์ฌ๋ฌ ํ ์ด๋ธ์ด ๋ ผ๋ฆฌ์ ์ผ๋ก ์ฐ๊ฒฐ๋์ด ์์
๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ จ ์ฉ์ด
- DBMS : ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ด๋ฆฌํ๋ ์์คํ ๋๋ ์ํํธ์จ์ด๋ฅผ ๋งํจ
- ๋ฐ์ดํฐ๋ฒ ์ด์ค(DB) : ํ ์ด๋ธ์ด ์ ์ฅ๋๋ ์ฅ์๋ก ์ฃผ๋ก ์ํต ๋ชจ์์ผ๋ก ํํ
- ๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์๋ก ๋ค๋ฅธ ๊ณ ์ ํ ์ด๋ฆ์ด ์์ด์ผ ํจ
- ํ ์ด๋ธ : ํ ํํ๋ก ํํ๋ ๊ฒ
- ๋ฐ์ดํฐ : ํ๋ํ๋์ ๋จํธ์ ์ธ ์ ๋ณด๋ฅผ ๋ปํจ
- ์ด(์นผ๋ผ ๋๋ ํ๋) : ๊ฐ ํ ์ด๋ธ์ 1๊ฐ ์ด์์ ์ด๋ก ๊ตฌ์ฑ๋จ
- ์ด ์ด๋ฆ : ๊ฐ ์ด์ ๊ตฌ๋ถํ๋ ์ด๋ฆ, ์ด ์ด๋ฆ์ ๊ฐ ํ ์ด๋ธ ์์์๋ ์ค๋ณต๋์ง ์์์ผ ํจ
- ๋ฐ์ดํฐ ํ์ : ์ด์ ๋ฐ์ดํฐ ํ์์ ๋ปํจ
- ํ ์ด๋ธ์ ์์ฑํ ๋ ์ด ์ด๋ฆ๊ณผ ํจ๊ป ์ง์ ํด์ผ ํจ
- ํ(๋ก์ฐ) : ์ค์ ๋ฐ์ดํฐ
- SQL : ์ฌ์ฉ์์ DBMS๊ฐ ์ํตํ๊ธฐ ์ํ ์ธ์ด
SQLite์์์ ๋ฐ์ดํฐ ๋ฒ ์ด์ค ๊ตฌ์ถ
SQLite
- ์๋๋ก์ด๋ ํฐ์ ๋ด์ฅ๋์ด์๋ ๊ฐ๋ฒผ์ด ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ฆฌ ์์คํ
- ๋ชจ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์คํ ์์ ์ฌ์ฉ ๊ฐ๋ฅํ ํ์ค SQL๊ณผ ์ผ๋ถ ์ถ๊ฐ์ ๊ธฐ๋ฅ ์ ๊ณต
์๋๋ก์ด๋ ์ฑ ๊ฐ๋ฐ์ ์ํ SQLite ๋์ ๋ฐฉ์
์๋๋ก์ด๋ ์ฑ ๊ฐ๋ฐ์ ์ํ SQLite ๋์ ๋ฐฉ์
๊ฐ ํด๋์ค์์ ์ฃผ๋ก ์ฌ์ฉ๋๋ ๋ฉ์๋
SQLite GUI ํด ํ์ฉํ์ฌ ์ฑ ๊ฐ๋ฐ
DB Browser for SQLite
DB Browser for SQLite
DB Browser for SQLite The Official home of the DB Browser for SQLite Screenshot What it is DB Browser for SQLite (DB4S) is a high quality, visual, open source tool to create, design, and edit database files compatible with SQLite. DB4S is for users and dev
sqlitebrowser.org
- DB Browser์ ๋ํ ๊ฒ๋ง ์ฌ์ฉํ ์์
์ฃผ์ ๊ตฌ์ฑ
- ๊ทธ๋ฃน์ ์ด๋ฆ๊ณผ ์ธ์์ ์ ๋ ฅํ๊ณ ์กฐํํ ์ ์์ ๏ง SQLite์ ์ฌ์ฉ
1. ํ๋ฉด ์์ฑํ๊ธฐ
<?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="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="์ด๋ฆ : "
android:textSize="20dp" />
<EditText
android:id="@+id/edtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="์ธ์ : "
android:textSize="20dp" />
<EditText
android:id="@+id/edtNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<Button
android:id="@+id/btnInit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="์ด๊ธฐํ" />
<Button
android:id="@+id/btnInsert"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="์
๋ ฅ" />
<Button
android:id="@+id/btnSelect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="์กฐํ" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="8"
android:orientation="horizontal">
<EditText
android:id="@+id/edtNameResult"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#DDDDFC"
android:padding="20dp"
android:layout_weight="1" />
<EditText
android:id="@+id/edtNumberResult"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#DDDDFC"
android:padding="20dp"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
[์ฐธ๊ณ ] ์ฟผ๋ฆฌ(SQL)
์ฟผ๋ฆฌ
- SQL: ๋ฐ์ดํฐ๋ฅผ ์ ์, ์กฐ์, ์ ์ดํ๋ ์ฉ๋์ ์ธ์ด๋ก ์ฌ์ฉ
- ์ฌ์ฉํ๋ ๋ช ๋ น์ด๋ฅผ SQL ๊ตฌ๋ฌธ ๋๋ ์ฟผ๋ฆฌ(Query)๋ผ๊ณ ํจ
- ์์ฑ๊ณผ ๊ด๋ จ๋ ์ฟผ๋ฆฌ
- ๊ทธ์ธ์ ์ฟผ๋ฆฌ๋ ํ ์ด๋ธ์ ์ฝ๊ณ ์ฐ๊ณ ์์ ํ๊ณ ์ญ์ ํ๋ ๋ช ๋ น์ด
์ฟผ๋ฆฌ์ ์ข ๋ฅ
- DDL: ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ์
- DML: ๋ฐ์ดํฐ๋ฅผ ์กฐ์
ํ ์ด๋ธ ์์ฑ
CREATE TABLE ํ
์ด๋ธ ์ด๋ฆ (์ด์ด๋ฆ1 ๋ฐ์ดํฐํ์1, ์ด์ด๋ฆ2 ๋ฐ์ดํฐํ์2, ... );
→ CREATE TABLE userTable (id char(4), username char(15), email char(15) );
๋ฐ์ดํฐ ์ ๋ ฅ
INSERT INTO ํ
์ด๋ธ์ด๋ฆ VALUES(๊ฐ1, ๊ฐ2, ... );
→ INSERT INTO userTable VALUES (‘swu’, ‘Lee’, ‘lee@swu.ac.kr’ );
๋ฐ์ดํฐ ์กฐํ ๋ฐ ํ์ฉ
SELECT ์ด์ด๋ฆ1, ์ด์ด๋ฆ2, ... FROM ํ
์ด๋ธ์ด๋ฆ
SELECT ์ด์ด๋ฆ1, ์ด์ด๋ฆ2, ... FROM ํ
์ด๋ธ์ด๋ฆ WHERE ์กฐ๊ฑด;
→ SELECT * FROM userTable;
SELECT * FROM userTable WHERE id = ‘swu’;
2. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ฉํ๊ธฐ
DB ์์ฑํ๊ธฐ
- SQLiteOpenHelper ํด๋์ค์์ ์์๋ฐ์ ํด๋์ค๋ฅผ ์ ์ํ ํ ์์ฑ์ ์์
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
inner class myDBHelper(context: Context) : SQLiteOpenHelper(context, "groupDB", null, 1) {
override fun onCreate(db: SQLiteDatabase?) {
TODO("Not yet implemented")
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
TODO("Not yet implemented")
}
}
}
- SQLitePenHelper(ํด๋์ค, DB ํ์ผ๋ช , ์ปค์๋ฅผ ์ ์ฅํ๋ ๋งค๊ฐ๋ณ์(null: ํ์ค ์ปค์), DB๋ฒ์ (์์ฑ๋ DB๊ฐ ์ฒ์์ด๋ฏ๋ก 1))
- onUpgrade(db: SQLiteDatabase?, ํ์ฌ๋ฒ์ , ์๋ก๋ฐ์๋ฒ์ )
ํ ์ด๋ธ ์์ฑ ๋ฐ ๋ณ๊ฒฝํ๊ธฐ
- myDBHelper ํด๋์ค์ onCreate( )์ onUpgrade( ) ๋ฉ์๋ ์ฝ๋ฉ
- onCreate( ) ๋ฉ์๋ : ํ ์ด๋ธ์ ์์ฑ
- onUpgrade( ) ๋ฉ์๋ : ํ ์ด๋ธ์ ์ญ์ ํ ํ ๋ค์ ์์ฑ
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
inner class myDBHelper(context: Context) : SQLiteOpenHelper(context, "groupDB", null, 1) { // inner class: ๋ด๋ถ ํด๋์ค (DB๊ฐ์ฒด ์์ฑ ์ ๋ณด, DB๋ช
, ์ปค์๊ฐ, ๋ฒ์ )
override fun onCreate(db: SQLiteDatabase?) {
db!!.execSQL("CREATE TABLE groupTBL (gName CHAR(20) PRIMARY KEY, gNumber Integer);") // CREATE TABLE:ํ
์ด๋ธ ์์ฑํ๋ SQL๋ฌธ, groupTBL:๊ทธ๋ฃน๋ช
(์ด ์ด๋ฆ ๊ฐ)) // ํ๋ผ์ด๋จธ๋ฆฌ ํค๋ก ์์ฑ(์๋ณ ํค)
}
override fun onUpgrade(db: SQLiteDatabase?, p1: Int, p2: Int) {
db!!.execSQL("DROP TABLE IF EXISTS groupTBL") // ํ
์ด๋ธ ์ญ์ ํ๋ SQL๋ฌธ:DROP TABLE, IF EXISTS:ํ
์ด๋ธ์ด ์กด์ฌํ ๋๋ง ์ญ์
onCreate(db) // ์์ฑํ ๋ onCreat() ํธ์ถ
}
}
}
SQLiteOpenHelper ํด๋์ค์ ๋ฉ์๋
์ปค์ ์ธํฐํ์ด์ค
๊ฒฐ๊ณผ ์งํฉ(Result Sets)๊ณผ ์ปค์(Cursors)
- rawQuery()
- SELECT๋ฌธ์ผ๋ก ๊ฒฐ๊ณผ์งํฉ์ ๋ฆฌํดํ ๋ ์ฌ์ฉ
- ์คํ ๊ฒฐ๊ณผ์ ์์ด ๋ง์ ์ ์์ผ๋ฏ๋ก ๊ฒฐ๊ณผ์งํฉ ์์ฒด๊ฐ ๋ฆฌํด๋์ง ์์ผ๋ฉฐ ์์น๋ฅผ ๊ฐ๋ฆฌํค๋ ์ปค์๋ก ๋ฆฌํด๋จ
- ์ปค์(Cursor)
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๋ก ๋ฆฌํด๋ ๋ฐ์ดํฐ์ ์์น๋ฅผ ๋ํ๋ด๋ ์ ๋ณด
- ๋ ์ฝ๋ ์งํฉ์ ๊ฐ๋ณ ๋ ์ฝ๋์ ์ ๊ทผํ์ฌ ๊ทธ ๊ฐ์ ํ์ธํ ์ ์๋๋ก ํจ
์ปค์(Cursors) ๋ฉ์๋
3. ์์ ฏ๊ณผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๋ํ๊ธฐ
์์ ฏ ๋ณ์ ์ ์ธ
- ๋ฉ์ธ ์กํฐ๋นํฐ ํด๋์ค์ ๋ค์ ๊ฐ์ ๋ณ์๋ฅผ ์ ์ธ
- myDBHelper ํด๋์ค ๋ณ์
- ์๋ํธํ ์คํธ์ ๋์ํ ๋ณ์ 4๊ฐ (์ด๋ฆ, ์ธ์, ์ด๋ฆ๊ฒฐ๊ณผ, ์ธ์๊ฒฐ๊ณผ)
- ๋ฒํผ์ ๋์ํ ๋ณ์ 3๊ฐ (์ด๊ธฐํ, ์ ๋ ฅ, ์กฐํ)
- SQLiteDatabase ํด๋์ค ๋ณ์
- onCreate( )์์๋ ์์ ฏ ๋ณ์์ activity_main.xml์ 7๊ฐ ์์ ฏ์ ๋์
๊ทธ๋ฃน ๊ด๋ฆฌ ๊ธฐ๋ฅ ๊ตฌํํ๊ธฐ
- <์ด๊ธฐํ>๋ฅผ ํด๋ฆญํ์ ๋ ๋์ํ๋ ๋ฆฌ์ค๋ ๊ตฌํ
- <์ ๋ ฅ>์ ํด๋ฆญํ๋ฉด ์๋ํธํ ์คํธ์ ๊ฐ์ด ์ ๋ ฅ๋๋ ๋ฆฌ์ค๋ ์ฝ๋ฉ
- ์คํํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ช ๊ฑด ์ ๋ ฅํ์ ๋ ‘์ ๋ ฅ๋จ’ ๋ฉ์์ง๊ฐ ๋์ด
- <์กฐํ>๋ฅผ ํด๋ฆญํ ๋, ์ ๋ ฅ ๊ฒฐ๊ณผ๊ฐ ์ถ๋ ฅ๋๋ ๋ฆฌ์ค๋ ์ฝ๋ฉ
- ํ ์ด๋ธ์ ์ ๋ ฅ๋ ๋ด์ฉ์ด ๋ชจ๋ ์๋์ชฝ ์๋ํธํ ์คํธ์ ์ถ๋ ฅ๋๋๋ก ํจ
* : ๋ชจ๋ ๊ฐ์ ธ์ฌ ๋ ์ฌ์ฉ
class MainActivity : AppCompatActivity() {
lateinit var edtName: EditText
lateinit var edtNumber: EditText
lateinit var edtNameResult: EditText
lateinit var edtNumberResult: EditText
lateinit var btnInit: Button
lateinit var btnInsert: Button
lateinit var btnSelect: Button
lateinit var myHelper: myDBHelper // myDBHelper ํด๋์ค ๋ณ์
lateinit var sqlDB: SQLiteDatabase // SQLite์ ๋ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ณ์
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
edtName = findViewById(R.id.edtName)
edtNumber = findViewById(R.id.edtNumber)
edtNameResult = findViewById(R.id.edtNameResult)
edtNumberResult = findViewById(R.id.edtNumberResult)
btnInit = findViewById(R.id.btnInit)
btnInsert = findViewById(R.id.btnInsert)
btnSelect = findViewById(R.id.btnSelect)
myHelper = myDBHelper(this) // myDBHelper๋ก๋ถํฐ ๊ฐ์ฒด ๋ฐ์์ค๊ธฐ
btnInit.setOnClickListener {
sqlDB = myHelper.writableDatabase // myHelper ์ธ์คํด์ค๋ก๋ถํฐ ๊ฐ์ฒด ๋ฐ์์ค๊ธฐ
myHelper.onUpgrade(sqlDB, 1, 2) // ํ
์ด๋ธ ๊ฐฑ์ (DB์ ๋ณด, ํ์ฌ๋ฒ์ , ๋ฐ๋๋ฒ์ ) (๋ฒ์ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก ์๋ฌด ์ซ์ ๋ฃ์ด๋ ๋จ ex.100 200)
sqlDB.close() // DB ๋ซ๊ธฐ
}
btnInsert.setOnClickListener {
sqlDB = myHelper.writableDatabase
sqlDB.execSQL("INSERT INTO groupTBL VALUES ('" + edtName.text.toString() + "', "
+ edtNumber.text.toString() + ");") // sql ์คํ์ํฌ ์ ์๋๋ก.. groupTBL: ๋ด์ฉ์ด ์ฝ์
๋ ํ
์ด๋ธ / VALUES: ๊ฐ
sqlDB.close() // DB ๋ซ๊ธฐ
Toast.makeText(applicationContext, "์
๋ ฅ๋จ", Toast.LENGTH_SHORT).show()
}
btnSelect.setOnClickListener {
sqlDB = myHelper.readableDatabase // ์ฝ๊ธฐ์ ์ฉ์ผ๋ก ๋ฐ์์ค๊ธฐ
var cursor: Cursor // ์ปค์ ๋ณ์ ์์ฑ
cursor = sqlDB.rawQuery("SELECT * FROM groupTBL;", null) // *: gropTBL์ ์๋ ๋ชจ๋ colums ๊ฐ์ ธ์ค๊ธฐ, null: ์์ ๋งค๊ฐ๋ณ์์ ์ธ์๊ฐ์ด ์์ผ๋ฏ๋ก
// ๋ ์ฝ๋๊ฐ ๊ฐ์ ธ์ค๊ธฐ ์ํ ๋ฐฐ์ด ์ด๋ฆ๊ณผ ์ธ์ ๋ช
์
var strNames = "๊ทธ๋ฃน์ด๋ฆ" + "\r\n" + "--------" + "\r\n"
var strNumbers = "์ธ์" + "\r\n" + "--------" + "\r\n"
// while๋ฌธ์ ํตํด ์ปค์๋ฅผ ํ๋์ฉ ์ด๋์ํค๋ฉฐ ๋ ์ฝ๋๊ฐ ๊ฐ์ ธ์ค๊ธฐ
while(cursor.moveToNext()) {
strNames += cursor.getString(0) + "\r\n" // ์ปค์ 0๋ฒ์งธ
strNumbers += cursor.getString(1) + "\r\n" // ์ปค์ 1๋ฒ์งธ
}
edtNameResult.setText(strNames)
edtNumberResult.setText(strNumbers)
cursor.close()
sqlDB.close()
}
}
...
}
[์ฐธ๊ณ ] SQLite GUI ํด ํ์ฉ
DB Browser for SQLite์์ DB ๋ฐ ํ ์ด๋ธ ์์ฑ
- [ํ์ผ]-[์ ๋ฐ์ดํฐ๋ฒ ์ด์ค]๋ฅผ ์ ํ
- [์ ์ฅํ๋ ค๋ ํ์ผ๋ช ์ ๊ณ ๋ฅด์ธ์] ์ฐฝ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ผ์ด ์ ์ฅ๋ ๊ฒฝ๋ก์ ํ์ผ๋ช ์ ์ง์ ํ๊ณ ์ ์ฅ
- ํ๋(์ด) ์ถ๊ฐ → ์ด ์์ฑ ํ <OK> ๋ฒํผ ํด๋ฆญ
DB Browser for SQLite์์ ๋ฐ์ดํฐ ์ ๋ ฅ
- [๋ฐ์ดํฐ ๋ณด๊ธฐ] ํญ ํด๋ฆญ ํ <์ ๋ ์ฝ๋> ํด๋ฆญํ๊ณ ๋ฐ์ดํฐ ์ ๋ ฅ
์์ฑ๋ DB ํ์ผ ์ฌ์ฉํ๊ธฐ
- Device File Explorer๋ฅผ ์ด์ฉํ์ฌ ์ ๋ก๋ํจ
- data>data> com.example.groupapp>databases ํด๋
- DB Browser for SQLite์์ ์์ ํ์ฌ ๋ค์ Device File Explorer์ ๋ณต์ฌํ์ฌ ์ฌ์ฉํ ์ ์์(๋๊ฐ์ง ํ์ผ(groupDB, groupDB-journal) ๋ชจ๋ ์ ๊ฑฐํ๊ณ ์ฐํด๋ฆญ upload, groupDB ์ ๋ก๋)
์ต์ข
package com.example.groupapp
import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
class MainActivity : AppCompatActivity() {
lateinit var edtName: EditText
lateinit var edtNumber: EditText
lateinit var edtNameResult: EditText
lateinit var edtNumberResult: EditText
lateinit var btnInit: Button
lateinit var btnInsert: Button
lateinit var btnSelect: Button
lateinit var myHelper: myDBHelper // myDBHelper ํด๋์ค ๋ณ์
lateinit var sqlDB: SQLiteDatabase // SQLite์ ๋ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ณ์
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
edtName = findViewById(R.id.edtName)
edtNumber = findViewById(R.id.edtNumber)
edtNameResult = findViewById(R.id.edtNameResult)
edtNumberResult = findViewById(R.id.edtNumberResult)
btnInit = findViewById(R.id.btnInit)
btnInsert = findViewById(R.id.btnInsert)
btnSelect = findViewById(R.id.btnSelect)
myHelper = myDBHelper(this) // myDBHelper๋ก๋ถํฐ ๊ฐ์ฒด ๋ฐ์์ค๊ธฐ
btnInit.setOnClickListener {
sqlDB = myHelper.writableDatabase // myHelper ์ธ์คํด์ค๋ก๋ถํฐ ๊ฐ์ฒด ๋ฐ์์ค๊ธฐ
myHelper.onUpgrade(sqlDB, 1, 2) // ํ
์ด๋ธ ๊ฐฑ์ (DB์ ๋ณด, ํ์ฌ๋ฒ์ , ๋ฐ๋๋ฒ์ ) (๋ฒ์ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก ์๋ฌด ์ซ์ ๋ฃ์ด๋ ๋จ ex.100 200)
sqlDB.close() // DB ๋ซ๊ธฐ
}
btnInsert.setOnClickListener {
sqlDB = myHelper.writableDatabase
sqlDB.execSQL("INSERT INTO groupTBL VALUES ('" + edtName.text.toString() + "', "
+ edtNumber.text.toString() + ");") // sql ์คํ์ํฌ ์ ์๋๋ก.. groupTBL: ๋ด์ฉ์ด ์ฝ์
๋ ํ
์ด๋ธ / VALUES: ๊ฐ
sqlDB.close() // DB ๋ซ๊ธฐ
Toast.makeText(applicationContext, "์
๋ ฅ๋จ", Toast.LENGTH_SHORT).show()
}
btnSelect.setOnClickListener {
sqlDB = myHelper.readableDatabase // ์ฝ๊ธฐ์ ์ฉ์ผ๋ก ๋ฐ์์ค๊ธฐ
var cursor: Cursor // ์ปค์ ๋ณ์ ์์ฑ
cursor = sqlDB.rawQuery("SELECT * FROM groupTBL;", null) // *: gropTBL์ ์๋ ๋ชจ๋ colums ๊ฐ์ ธ์ค๊ธฐ, null: ์์ ๋งค๊ฐ๋ณ์์ ์ธ์๊ฐ์ด ์์ผ๋ฏ๋ก
// ๋ ์ฝ๋๊ฐ ๊ฐ์ ธ์ค๊ธฐ ์ํ ๋ฐฐ์ด ์ด๋ฆ๊ณผ ์ธ์ ๋ช
์
var strNames = "๊ทธ๋ฃน์ด๋ฆ" + "\r\n" + "--------" + "\r\n"
var strNumbers = "์ธ์" + "\r\n" + "--------" + "\r\n"
// while๋ฌธ์ ํตํด ์ปค์๋ฅผ ํ๋์ฉ ์ด๋์ํค๋ฉฐ ๋ ์ฝ๋๊ฐ ๊ฐ์ ธ์ค๊ธฐ
while(cursor.moveToNext()) {
strNames += cursor.getString(0) + "\r\n" // ์ปค์ 0๋ฒ์งธ
strNumbers += cursor.getString(1) + "\r\n" // ์ปค์ 1๋ฒ์งธ
}
edtNameResult.setText(strNames)
edtNumberResult.setText(strNumbers)
cursor.close()
sqlDB.close()
}
}
inner class myDBHelper(context: Context) : SQLiteOpenHelper(context, "groupDB", null, 1) { // inner class: ๋ด๋ถ ํด๋์ค (DB๊ฐ์ฒด ์์ฑ ์ ๋ณด, DB๋ช
, ์ปค์๊ฐ, ๋ฒ์ )
override fun onCreate(db: SQLiteDatabase?) {
db!!.execSQL("CREATE TABLE groupTBL (gName CHAR(20) PRIMARY KEY, gNumber Integer);") // CREATE TABLE:ํ
์ด๋ธ ์์ฑํ๋ SQL๋ฌธ, groupTBL:๊ทธ๋ฃน๋ช
(์ด ์ด๋ฆ ๊ฐ)) // ํ๋ผ์ด๋จธ๋ฆฌ ํค๋ก ์์ฑ(์๋ณ ํค)
}
override fun onUpgrade(db: SQLiteDatabase?, p1: Int, p2: Int) {
db!!.execSQL("DROP TABLE IF EXISTS groupTBL") // ํ
์ด๋ธ ์ญ์ ํ๋ SQL๋ฌธ:DROP TABLE, IF EXISTS:ํ
์ด๋ธ์ด ์กด์ฌํ ๋๋ง ์ญ์
onCreate(db) // ์์ฑํ ๋ onCreat() ํธ์ถ
}
}
}
์ ๋ฆฌ
- SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์๋๋ก์ด๋์ ๋ด์ฅ๋์ด ์์ด ์ฝ๊ฒ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๊ตฌ์ถํ๊ณ ์ฌ์ฉํ ์ ์์
- ํ์ค SQL ์ฌ์ฉ ๊ฐ๋ฅํจ
- SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด SQLiteOpenHelperํด๋์ค, SQLiteDatabase ํด๋์ค, Cursor ์ธํฐํ์ด์ค๋ฅผ ํ์ฉํจ
ํ๋ก์ ํธ ์์ฉ
<์์ >๊ณผ <์ญ์ > ๋ฅผ ์ถ๊ฐํ๊ธฐ - ํํธ
- ์์ SQL: UPDATE groupTBL SET gNumber = ๋ณ๊ฒฝ๋ ์ธ์ WHERE gName=“๋ณ๊ฒฝํ ๊ทธ๋ฃน ์ด๋ฆ“;
- ์ญ์ SQL: DELETE FROM groupTBL SET gName = “์ญ์ ํ ๊ทธ๋ฃน ์ด๋ฆ“;
- ์ ๋ ฅ/์์ /์ญ์ ํ ์ฆ์ ๊ฒฐ๊ณผ๊ฐ ๋ณด์ด๊ฒ ํ๋ ค๋ฉด (๋ฒํผ๋ณ์).callOnClick()์ ํธ์ถ
<?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="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="์ด๋ฆ : "
android:textSize="20dp" />
<EditText
android:id="@+id/edtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="์ธ์ : "
android:textSize="20dp" />
<EditText
android:id="@+id/edtNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<Button
android:id="@+id/btnInit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="์ด๊ธฐํ"
android:textSize="12sp" />
<Button
android:id="@+id/btnInsert"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="์
๋ ฅ" />
<Button
android:id="@+id/btnUpdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="์์ " />
<Button
android:id="@+id/btnDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="์ญ์ " />
<Button
android:id="@+id/btnSelect"
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="0dp"
android:layout_weight="8"
android:orientation="horizontal">
<EditText
android:id="@+id/edtNameResult"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#DDDDFC"
android:padding="20dp"
android:layout_weight="1" />
<EditText
android:id="@+id/edtNumberResult"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#DDDDFC"
android:padding="20dp"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
package com.example.groupapp
import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
class MainActivity : AppCompatActivity() {
lateinit var edtName: EditText
lateinit var edtNumber: EditText
lateinit var edtNameResult: EditText
lateinit var edtNumberResult: EditText
lateinit var btnInit: Button
lateinit var btnInsert: Button
lateinit var btnSelect: Button
lateinit var btnUpdate: Button
lateinit var btnDelete: Button
lateinit var myHelper: myDBHelper // myDBHelper ํด๋์ค ๋ณ์
lateinit var sqlDB: SQLiteDatabase // SQLite์ ๋ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ณ์
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
edtName = findViewById(R.id.edtName)
edtNumber = findViewById(R.id.edtNumber)
edtNameResult = findViewById(R.id.edtNameResult)
edtNumberResult = findViewById(R.id.edtNumberResult)
btnInit = findViewById(R.id.btnInit)
btnInsert = findViewById(R.id.btnInsert)
btnSelect = findViewById(R.id.btnSelect)
btnUpdate = findViewById(R.id.btnUpdate)
btnDelete = findViewById(R.id.btnDelete)
myHelper = myDBHelper(this) // myDBHelper๋ก๋ถํฐ ๊ฐ์ฒด ๋ฐ์์ค๊ธฐ
btnInit.setOnClickListener {
sqlDB = myHelper.writableDatabase // myHelper ์ธ์คํด์ค๋ก๋ถํฐ ๊ฐ์ฒด ๋ฐ์์ค๊ธฐ
myHelper.onUpgrade(sqlDB, 1, 2) // ํ
์ด๋ธ ๊ฐฑ์ (DB์ ๋ณด, ํ์ฌ๋ฒ์ , ๋ฐ๋๋ฒ์ ) (๋ฒ์ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก ์๋ฌด ์ซ์ ๋ฃ์ด๋ ๋จ ex.100 200)
sqlDB.close() // DB ๋ซ๊ธฐ
}
btnInsert.setOnClickListener {
sqlDB = myHelper.writableDatabase
sqlDB.execSQL("INSERT INTO groupTBL VALUES ('" + edtName.text.toString() + "', "
+ edtNumber.text.toString() + ");") // sql ์คํ์ํฌ ์ ์๋๋ก.. groupTBL: ๋ด์ฉ์ด ์ฝ์
๋ ํ
์ด๋ธ / VALUES: ๊ฐ
sqlDB.close() // DB ๋ซ๊ธฐ
Toast.makeText(applicationContext, "์
๋ ฅ๋จ", Toast.LENGTH_SHORT).show()
btnSelect.callOnClick() // ์กฐํ ๊ฐ์ ๋ฐ์
}
btnSelect.setOnClickListener {
sqlDB = myHelper.readableDatabase // ์ฝ๊ธฐ์ ์ฉ์ผ๋ก ๋ฐ์์ค๊ธฐ
var cursor: Cursor // ์ปค์ ๋ณ์ ์์ฑ
cursor = sqlDB.rawQuery("SELECT * FROM groupTBL;", null) // *: gropTBL์ ์๋ ๋ชจ๋ colums ๊ฐ์ ธ์ค๊ธฐ, null: ์์ ๋งค๊ฐ๋ณ์์ ์ธ์๊ฐ์ด ์์ผ๋ฏ๋ก
// ๋ ์ฝ๋๊ฐ ๊ฐ์ ธ์ค๊ธฐ ์ํ ๋ฐฐ์ด ์ด๋ฆ๊ณผ ์ธ์ ๋ช
์
var strNames = "๊ทธ๋ฃน์ด๋ฆ" + "\r\n" + "--------" + "\r\n"
var strNumbers = "์ธ์" + "\r\n" + "--------" + "\r\n"
// while๋ฌธ์ ํตํด ์ปค์๋ฅผ ํ๋์ฉ ์ด๋์ํค๋ฉฐ ๋ ์ฝ๋๊ฐ ๊ฐ์ ธ์ค๊ธฐ
while(cursor.moveToNext()) {
strNames += cursor.getString(0) + "\r\n" // ์ปค์ 0๋ฒ์งธ
strNumbers += cursor.getString(1) + "\r\n" // ์ปค์ 1๋ฒ์งธ
}
edtNameResult.setText(strNames)
edtNumberResult.setText(strNumbers)
cursor.close()
sqlDB.close()
}
btnUpdate.setOnClickListener {
sqlDB = myHelper.writableDatabase // ์์ ํ๋ ๊ฒ์ด๋ฏ๋ก ์์ ๊ฐ๋ฅํ๊ฒ ์ฐ๊ธฐ ์ ์ฉ
sqlDB.execSQL("UPDATE groupTbL SET gNumber = " + edtNumber.text + " WHERE gName = '"
+ edtName.text.toString() + "';") // (์์ ๋ฌธ, ๋ญ๊ฐ ๋ฐ๋ ๊ฒ์ธ์ง(์ธ์ ๋ฐ๋ ๊ฒ์), ์กฐ๊ฑด๋ฌธ(๋ฐ๋ ์ธ์์ ์ด๋ฆ์ด ์
๋ ฅํ ์ด๋ฆ๊ณผ ๊ฐ์์ง))
sqlDB.close()
Toast.makeText(applicationContext, "์์ ๋จ", Toast.LENGTH_SHORT).show()
btnSelect.callOnClick() // ์กฐํ ๊ฐ์ ๋ฐ์
}
btnDelete.setOnClickListener {
sqlDB = myHelper.writableDatabase // ์ญ์ ๊ฐ๋ฅํ๊ฒ ์ฐ๊ธฐ ์ ์ฉ
sqlDB.execSQL("DELETE FROM groupTBL WHERE gName = '" + edtName.text.toString() + "';") // edtName๊ณผ gName์ด ๊ฐ์ ๋ groupTBL์์ ์ญ์
sqlDB.close()
Toast.makeText(applicationContext, "์ญ์ ๋จ", Toast.LENGTH_SHORT).show()
btnSelect.callOnClick() // ์กฐํ ๊ฐ์ ๋ฐ์
}
}
inner class myDBHelper(context: Context) : SQLiteOpenHelper(context, "groupDB", null, 1) { // inner class: ๋ด๋ถ ํด๋์ค (DB๊ฐ์ฒด ์์ฑ ์ ๋ณด, DB๋ช
, ์ปค์๊ฐ, ๋ฒ์ )
override fun onCreate(db: SQLiteDatabase?) {
db!!.execSQL("CREATE TABLE groupTBL (gName CHAR(20) PRIMARY KEY, gNumber Integer);") // CREATE TABLE:ํ
์ด๋ธ ์์ฑํ๋ SQL๋ฌธ, groupTBL:๊ทธ๋ฃน๋ช
(์ด ์ด๋ฆ ๊ฐ)) // ํ๋ผ์ด๋จธ๋ฆฌ ํค๋ก ์์ฑ(์๋ณ ํค)
}
override fun onUpgrade(db: SQLiteDatabase?, p1: Int, p2: Int) {
db!!.execSQL("DROP TABLE IF EXISTS groupTBL") // ํ
์ด๋ธ ์ญ์ ํ๋ SQL๋ฌธ:DROP TABLE, IF EXISTS:ํ
์ด๋ธ์ด ์กด์ฌํ ๋๋ง ์ญ์
onCreate(db) // ์์ฑํ ๋ onCreat() ํธ์ถ
}
}
}