저번 포스팅의 Room과 lombok을 둘 다 활용해보는 방향으로 아주아주아주 간단한 앱을 만들어 봤다.
- 사용 언어 : Java
- DB : SQLite(Room 이용)
- List는 RecyclerView로 보여준다.
: 데이터를 받아 줄 class를 생성해준다.
@Entity
@Getter @Setter @AllArgsConstructor @NoArgsConstructor @Builder
public class Todo {
@PrimaryKey(autoGenerate = true)
private int id;
// To-do의 내용
private String content;
// 완료 여부
private boolean completed;
}
정수형 변수 id를 Primary키로 설정해준다.
엔티티가 추가될 때 마다 번호를 자동으로 지정하기 위해 autoGenerate를 true로 준다.
완료 여부를 보면 boolean 타입은 사용 못하지만 사용 가능하게 해주는게 room이다! (꿀!!)
Getter Setter등은 저번 포스팅에 잘 설명이 되어있다.
: Room이 이용하여 데이터베이스의 쿼리를 실행할 수 있게 Dao를 만들어 줍니다.
-> Interface로 생성해준다.
@Query("SELECT * FROM todo ORDER BY id DESC")
List<Todo> select();
@Query("INSERT INTO todo (content) VALUES(:content)")
void insert(String content);
@Insert
void insert(Todo todo);
@Query("DELETE FROM todo WHERE id = :id")
void delete(int id);
@Delete
void delete(Todo todo);
@Query("UPDATE todo SET completed = 1 WHERE id = :id")
void complete(int id);
원래는 'INSERT INTO todo(id,content) VALUES(1,'밥먹기')' 이렇게 길게 써야하는데
이걸 간단히 해주는 아이가 '@Insert' 다.
SQL문법을 어느정도 알아야 사용하기 편하다.
SELECT * : 모든 항목을 조회하겠다.
FROM to-do : to-do 테이블에서
(Where 조건식) : 조건에 맞는 레코드만.
ORDER BY id DESC : id 내림차 순으로 정렬 ( 오름차 순은 ASC(기본값) 이다.)
: database 클래스는 abstact로, RoomDatabase를 extends 해야한다.
@Database(entities = {Todo.class}, version = 1) //마지막에 version을 꼭 써줘야함
public abstract class AppDatabase extends RoomDatabase {
public abstract TodoDao todoDao();
}
RoomDatabase 클래스는 하나만 생성해주는게 일반적이다.
만약 다른 클래스에서의 DB접근을 허용하려면 다음과 같다.
@Database(entities = {Todo.class, 또다른클래스.class}, version = 1)
// 위와 같이 다른 클래스.class 를 추가해주고
// 클래스 내에는 다음과 같이 추가해준다.
public abstract 또다른클래스 또다른클래스();
우선, recyclerview를 사용하기 위해 Dependency에 다음 두줄을 추가한다.
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.recyclerview:recyclerview-selection:1.1.0"
데이터를 보여줄 .xml(정적 리소스)을 간단히 만들어준다.
나는 간단하게 체크박스를 사용했다.
: RecyclerView 에 아이템을 붙여주는 객체 Adapter를 생성해준다.
item은 List 혹은 Array에 담겨있어야 한다. (index로 접근할 것이기 때문)
public void updateList(List<Todo> list) {
this.list = list;
notifyDataSetChanged();
}
Todo 아이템을 List로 받는다.
notifyDataSetChanged(); → Adapter가 아이템의 변경을 감지하고 뷰를 업데이트한다.
RecyclerView.Adapter를 상속받고, 거기서 선언된 추상 메서드 3개를 오버라이드한다.
onCreateViewHolder(), onBindViewHolder(), getItemCount()를 오버라이드한다. (Alt+Insert)
@Getter @Setter
public class MyViewHolder extends RecyclerView.ViewHolder{
public MyViewHolder(View view){
super(view);
이제 MainActivity에서 db를 불러오고 사용해주면 된다.
private AppDatabase db;
db = Room.databaseBuilder(this, AppDatabase.class, "todo-db")
.allowMainThreadQueries() // 메인스레드에서도 DB 실행이 가능하도록 설정
// DB 처리와 네트워크 통신(업로드,다운로드) 등의
// 대규모 데이터 처리가 필요한 경우는
// 메인스레드에서 실행을 못하게 막아놨다.
.build();
그 후, LayoutManager와 Adapter를 설정해준다.
LayoutManager : 아이템의 배치를 결정하는 객체
(LinearLayoutManager :일렬 배치 (수평/수직 둘 다 가능))
(GridLayoutManager : 격자형 배치)
(StaggeredGridLayoutManager : 크기에 구애받지 않는 격자형 배치)
Adapter : RecyclerView 에 아이템을 붙여주는 객체
mLayoutManager = new LinearLayoutManager(this);
mAdapter = new TodoRecyclerViewAdapter(db.todoDao().select());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
여기까지 하면 완성이고, 사용은 다음과 같이 하면 된다.
// 빈 Todo 객체 생성
Todo todo = new Todo();
// editText에 들어있는 입력 값을 String형으로 content 에 저장
todo.setContent(mTodoEditText.getText().toString());
// todo 객체를 DB에 insert(저장)
db.todoDao().insert(todo);
// DB 에서 Todo 객체들을 모두 조회 후, 1개의 String 으로 content들을 모은다.
// String result = getString();
// 모은 String을 결과뷰에 출력한다.
// mRecyclerView.setText(result);
mAdapter.updateList(db.todoDao().select());
app 실행결과는 다음과 같다.
목록을 DB에 저장하면 listView가 refresh 되면서 목록을 불러와 보여준다.
물론 App을 재시작하거나 Device를 재실행시켜도 데이터는 남아있다!
멋지십니당