본문 바로가기
안드로이드 스튜디오

[안드로이드 스튜디오] 메모장 어플 만들어보기 - 2 : ROOM을 이용한 데이터베이스

by JM0121 2021. 1. 17.

 

 

vnfmadl234.tistory.com/8

 

[안드로이드 스튜디오] 메모장 어플 만들어보기

안드로이드 스튜디오 공부를 시작하면서 내가 처음으로 만들 수 있는 것이 무엇이 있을까 하고 생각하던 중, 평소 할 일들을 종종 까먹거나 놓치는 나에게 할 일을 적어 놓을 수 있는 메모앱을

vnfmadl234.tistory.com

 

 

지난 글에서 리사이클러뷰를 통한 데이터 입력과 저장을 해보았다, 하지만 단순이 어답터를 통해 입력하고 저장하는건 가능하지만 어플을 종료했다가 다시 키면 정보가 사라지게 된다. 메모장 어플는 내가 쓴 정보를 저장하는 것이 목적이므로 데이터를 담을 수 있는 데이터베이스를 추가할 것이다.

 

 

데이터베이스는 여러 종류가 있지만 Room 라이브러리를 이용할 것이다. Room 라이브러리는 SQLite에 추상화 계층을 제공해 SQLite의 기능들을 사용하면서 더 견고한 데이터베이스 액세스를 가능하게 한다고한다. SQLite에 비해 더 편리하고 다양한 기능들을 제공해서 Room을 사용했다.

 

 

ROOM의 구성 요소

Room은 3가지 구성 요소를 가지며 특징은 아래와 같습니다.

Database

Database 접근 지점을 제공하며 DAO를 관리합니다.
Annotation내에 사용할 Entity목록을 작성해야 합니다.

DAO(Data Access Object)

Database에 접근하는 메소드들을 포함하며 Annotation으로 관리됩니다.
LiveData를 이용하면 Observable query를 이용할 수 있습니다.

Entity

테이블을 의미합니다.

 

 

 

출처: gus0000123.medium.com/mvvm-aac-room%EC%82%AC%EC%9A%A9%EB%B2%95-1-%EA%B0%9C%EB%85%90%ED%8E%B8-59ad680ea6fe

 

 

 

 

 

 

 

 

Memo.java(참조 코드)

package com.example.notebook3;

import android.os.Parcel;
import android.os.Parcelable;

import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;

import java.util.List;

//테이블의 이름을 지정
@Entity(tableName = "memoTable")
public class Memo implements Parcelable{

	//기본 키 값을 자동으로 생성
    @PrimaryKey(autoGenerate = true)
    //테이블 컴럼 명 지정
    @ColumnInfo(name = "memo_id")
    private int id;
    @ColumnInfo(name = "memo_title")
    private String title;
    @ColumnInfo(name = "memo_content")
    private String content;

    public Memo(String title, String content) {
        this.title = title;
        this.content = content;
    }

    protected Memo(Parcel in) {
        id = in.readInt();
        title = in.readString();
        content = in.readString();
    }

    public static final Creator<Memo> CREATOR = new Creator<Memo>() {
        @Override
        public Memo createFromParcel(Parcel in) {
            return new Memo(in);
        }

        @Override
        public Memo[] newArray(int size) {
            return new Memo[size];
        }
    };

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {

        dest.writeInt(id);
        dest.writeString(title);
        dest.writeString(content);
    }
}

 

 

Entity에 해당하는 클래스로 노트작성에 필요한 각 항목들을 선언해줍니다.

 

 

 

 

 

 

 

MemoDao.java(참조 코드)

package com.example.notebook3;


import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;

import java.util.List;

@Dao
public interface MemoDao {

    @Query("SELECT * FROM memoTable")
    List<Memo> getAll();

    @Query("DELETE FROM memoTable")
    void deleteAll();

    @Query("UPDATE memoTable SET memo_title = :t, memo_content = :d WHERE memo_id =:id")
    void update(String t, String d, int id);

    @Insert
    void insert(Memo memo);

    @Update
    void update(Memo memo);

    @Delete
    void delete(Memo memo);
}

 

 

Dao객체에는 데이터의 삽입, 삭제, 수정 등 메소드를 추가해줍니다.

 

 

 

 

 

 

 

MemoDatabase.java(참조 코드)

package com.example.notebook3;


import android.content.Context;

import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;

@Database(entities = {Memo.class}, version = 2, exportSchema = false)
public abstract class MemoDatabase extends RoomDatabase {
	
    //데이터베이스는 매번 생성하면 리소스를 많이 먹으니 싱글톤으로 생성

    public abstract MemoDao memoDao();
    private static MemoDatabase instance = null;


	/DB 객체 생성
    public static synchronized MemoDatabase getInstance(Context context){
        if(instance == null){
            instance =  Room.databaseBuilder(context.getApplicationContext(),
                    MemoDatabase.class, "memo_Database")
                    .fallbackToDestructiveMigration()
                    .allowMainThreadQueries()
                    .build();
        }
        return instance;
    }
}

 

 

 

사실 SQLite를 배운지 얼마 안되고 나서 ROOM를 배워서 사용해보겠다고 열심히 구글링을 통해 찾아보다가 결국 깔끔하고 정리가 잘 된 예제를 하나 찾게되어 이 블로그를 참고하게되었다. (ROOM 코드부분은 여기와 매우 비슷함)

 

 

mynamewoon.tistory.com/17?category=833237

 

 

#4. 나만의 메모장 만들기 / Database에 저장된 내용 리사이클러뷰에 넣기 / Dialog + editText

싱글톤 오류를 찾아 내고 나서 10일만에 포스팅이네요. 14일에 쏘마 시험이 있어서 그거 준비하느라 안드로이드 공부를 못했습니다. 쏘마 제발 통과시켜주세요... 어쨌든 오늘 할 내용은 로컬 데

mynamewoon.tistory.com

 

 

 


 

 

 

MainActivity.java(참조 코드)

   //RecyclerView 사용
    private void init() {
        RecyclerView recyclerView = findViewById(R.id.recyclerView);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);

        adapter = new RecyclerAdapter();
        recyclerView.setAdapter(adapter);

        memos = MemoDatabase.getInstance(this).memoDao().getAll();
        int size = memos.size();
        for (int i = 0; i < size; i++) {
            adapter.addItem(memos.get(i));

        }
    }


    //DB로부터 값 전달
    @Override
    public void onStart() {
        memos = MemoDatabase.getInstance(this).memoDao().getAll();
        adapter.addItems((ArrayList) memos);
        super.onStart();
    }

}

 

 

DB를 통해 리사이클러뷰에 작성한 데이터들을 가져와 보여주게된다.

 

 

 


 

 

+추가로 

내가 참고한 예제 블로그에 내가 생각했던 기능을 사용하고 있어 이 부분까지 코드를 참고했다.

바로 메모하나를 꾹 눌렀을 때 정보를 수정할 수 있는 창으로 전환하는 것이다.

 

 

 

 

 

RecyclerAdapter.java(참조 코드)

       void onBind(Memo memo, int position) {
            textView1.setText(memo.getTitle());
            textView2.setText(memo.getContent());

            //길게 클릭 시 수정화면
            itemView.setOnLongClickListener(v -> {
                Intent intent = new Intent(itemView.getContext(), MemoDetailActivity.class);
                intent.putExtra("data", memo);
                itemView.getContext().startActivity(intent);
                return false;
            });

        }

 

 

아답터에서 onBind 부분의 setOnLongClickListener를 통해 메모를 수정할 수 있는 화면으로 넘어가게되고,

 

 

 

 

 

 

MemoDetailActivity.java(참조코드)

package com.example.notebook3;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.room.Database;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

public class MemoDetailActivity extends AppCompatActivity {

    private EditText detailTitle;
    private EditText detailContent;
    private MemoDatabase db;

    private int id;
    private String title;
    private String content;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_memo_detail);

        detailTitle = findViewById(R.id.titleDetail);
        detailContent = findViewById(R.id.contentDetail);
        db = MemoDatabase.getInstance(this);

        init();


        // 수정
        ImageButton writeDetail = (ImageButton) findViewById(R.id.writeDetail);
        writeDetail.setOnClickListener(v -> {
            title = detailTitle.getText().toString();
            content = detailContent.getText().toString();
            db.memoDao().update(title, content, id);
            finish();
        });

        ImageButton cancelDetail = (ImageButton) findViewById(R.id.cancelDetail);
        cancelDetail.setOnClickListener(v -> {
            finish();
        });
    }

    private void init() {
        Memo detail = getIntent().getParcelableExtra("data");

        id = detail.getId();
        title = detail.getTitle();
        content = detail.getContent();

        detailTitle.setText(title);
        detailContent.setText(content);
    }
}

 

(화면은 노트 작성레이아웃과 동일하게 구성함)

 

MemoDetailActivity에서 메모를 다시 작성하여 DB를 수정하는식 으로 진행된다. 

 

 

이렇게 데이터베이스를 통해 데이터를 추가하고 수정하는 코드를 만들었는데, 처음이라 어렵기도하고 막 시도를 먼저 한 뒤, 잘 안되는 부분들은 다른 여러 코드를 참고하면서 해결하니 배우는 점이 참 많다. 

 

아직 처음 만들어보는 어플이라 다른 블로그들을 많이 따라하게되서 아쉽지만 열심히 배워서 직접 나만의 코드로 만든 어플을 만들 수 있도록 노력해야겠다.

 

 

 

github주소: github.com/m3k0813/NoteBook

참고 블로그: mynamewoon.tistory.com/20?category=833237