Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

Android SQLite에서 커서(Cursor)로 가져온 배열 목록이 비어 있는지 확인하는 방법

Android SQLite에서 커서 배열 목록 비어 있음 확인하기

예제를 살펴보기 전에 Android의 SQLite 데이터베이스에 대해 먼저 알아보겠습니다. SQLite는 오픈 소스 SQL 데이터베이스로, 기기 내 텍스트 파일 형태로 데이터를 저장합니다. Android에는 SQLite 데이터베이스 구현이 기본으로 내장되어 있으며, 관계형 데이터베이스의 모든 기능을 지원합니다. 또한 JDBC나 ODBC처럼 별도의 연결 설정 없이도 바로 데이터베이스에 접근할 수 있다는 점이 큰 장점입니다.

이 글에서는 Android SQLite에서 커서(Cursor)로 조회한 배열 목록(ArrayList)이 비어 있는지 확인하는 방법을 단계별 예제와 함께 설명합니다.

1단계 — 새 프로젝트 생성

Android Studio에서 File → New Project를 선택하고, 필요한 정보를 모두 입력하여 새 프로젝트를 생성합니다.

2단계 — 레이아웃 작성 (res/layout/activity_main.xml)

아래 코드를 activity_main.xml에 추가합니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">
    <EditText
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:hint="Enter Name"
        android:layout_height="wrap_content" />
    <EditText
        android:id="@+id/salary"
        android:layout_width="match_parent"
        android:inputType="numberDecimal"
        android:hint="Enter Salary"
        android:layout_height="wrap_content" />
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"><Button
        android:id="@+id/save"
        android:text="Save"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
        <Button
            android:id="@+id/refresh"
            android:text="Refresh"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <Button
            android:id="@+id/udate"
            android:text="Update"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <Button
            android:id="@+id/Delete"
            android:text="DeleteALL"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>
</LinearLayout>

위 레이아웃에는 이름(name)과 급여(salary)를 입력받는 EditText 두 개와 Save(저장), Refresh(새로고침), Update(수정), DeleteALL(전체 삭제) 버튼, 그리고 데이터를 표시할 ListView가 포함되어 있습니다. 사용자가 저장 버튼을 누르면 입력한 데이터가 SQLite 데이터베이스에 저장되고, 새로고침 버튼을 누르면 ListView에 목록이 표시됩니다.

3단계 — MainActivity 작성 (src/MainActivity.java)

아래 코드를 MainActivity.java에 추가합니다.

package com.example.andy.myapplication;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    Button save, refresh;
    EditText name, salary;
    private ListView listView;
    ArrayAdapter arrayAdapter;

    @Override
    protected void onCreate(Bundle readdInstanceState) {
        super.onCreate(readdInstanceState);
        setContentView(R.layout.activity_main);
        final DatabaseHelper helper = new DatabaseHelper(this);
        final ArrayList array_list = helper.getAllCotacts();
        name = findViewById(R.id.name);
        salary = findViewById(R.id.salary);
        listView = findViewById(R.id.listView);
        if(!array_list.isEmpty()) {
            arrayAdapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, array_list);
            listView.setAdapter(arrayAdapter);
        }
        findViewById(R.id.Delete).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (helper.delete()) {
                    Toast.makeText(MainActivity.this, "Deleted", Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(MainActivity.this, "NOT Deleted", Toast.LENGTH_LONG).show();
                }
            }
        });
        findViewById(R.id.udate).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!name.getText().toString().isEmpty() && !salary.getText().toString().isEmpty()) {
                    if (helper.update(name.getText().toString(), salary.getText().toString())) {
                        Toast.makeText(MainActivity.this, "Updated", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(MainActivity.this, "NOT Updated", Toast.LENGTH_LONG).show();
                    }
                } else {
                    name.setError("Enter NAME");
                    salary.setError("Enter Salary");
                }
            }
        });
        findViewById(R.id.refresh).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!array_list.isEmpty()) {
                    array_list.clear();
                    array_list.addAll(helper.getAllCotacts());
                    arrayAdapter.notifyDataSetChanged();
                    listView.invalidateViews();
                    listView.refreshDrawableState();
                }
            }
        });
        findViewById(R.id.save).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!name.getText().toString().isEmpty() && !salary.getText().toString().isEmpty()) {
                    if (helper.insert(name.getText().toString(), salary.getText().toString())) {
                        Toast.makeText(MainActivity.this, "Inserted", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(MainActivity.this, "NOT Inserted", Toast.LENGTH_LONG).show();
                    }
                } else {
                    name.setError("Enter NAME");
                    salary.setError("Enter Salary");
                }
            }
        });
    }
}

핵심 부분은 다음 코드입니다. getAllCotacts() 메서드로 가져온 ArrayList에 대해 isEmpty()를 호출하여 목록이 비어 있는지 검사한 후, 비어 있지 않을 때만 어댑터를 생성해 ListView에 연결합니다.

if(!array_list.isEmpty()) {
    arrayAdapter = new ArrayAdapter(MainActivity.this,
        android.R.layout.simple_list_item_1, array_list);
    listView.setAdapter(arrayAdapter);
}

이렇게 하면 데이터베이스에 저장된 데이터가 하나도 없을 때 빈 어댑터로 인한 오류나 불필요한 화면 갱신을 방지할 수 있습니다.

4단계 — DatabaseHelper 작성 (src/DatabaseHelper.java)

아래 코드를 DatabaseHelper.java에 추가합니다.

package com.example.andy.myapplication;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;

import java.io.IOException;
import java.util.ArrayList;

class DatabaseHelper extends SQLiteOpenHelper {
    public static final String DATABASE_NAME = "salaryDatabase6";
    public static final String CONTACTS_TABLE_NAME = "SalaryDetails";
    public DatabaseHelper(Context context) {
        super(context,DATABASE_NAME,null,1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        try {
            db.execSQL(
                "create table "+ CONTACTS_TABLE_NAME +"(id INTEGER PRIMARY KEY, name text,salary int,datetime default current_timestamp )"
            );
        } catch (SQLiteException e) {
            try {
                throw new IOException(e);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS "+CONTACTS_TABLE_NAME);
        onCreate(db);
    }

    public boolean insert(String s, String s1) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues contentValues = new ContentValues();
        contentValues.put("name", s);
        contentValues.put("salary", s1);
        db.replace(CONTACTS_TABLE_NAME, null, contentValues);
        return true;
    }

    public ArrayList getAllCotacts() {
        SQLiteDatabase db = this.getReadableDatabase();
        ArrayList<String> array_list = new ArrayList<String>();
        Cursor res = db.rawQuery( "select (id ||' : '||name || ' : ' || salary || ' : '|| datetime) as fullname from "+CONTACTS_TABLE_NAME, null );
        res.moveToFirst();

        while(res.isAfterLast() == false) {
            array_list.add(res.getString(res.getColumnIndex("HighestNumber")));
            res.moveToNext();
        }
        return array_list;
    }

    public boolean update(String s, String s1) {
        SQLiteDatabase db = this.getWritableDatabase();
        db.execSQL("UPDATE "+CONTACTS_TABLE_NAME+" SET name = "+"'"+s+"', "+ "salary = "+"'"+s1+"'");
        return true;
    }

    public boolean delete() {
        SQLiteDatabase db = this.getWritableDatabase();
        db.execSQL("DELETE from "+CONTACTS_TABLE_NAME);
        return true;
    }
}

DatabaseHelper 클래스는 SQLiteOpenHelper를 상속하며, 테이블 생성·데이터 삽입(insert)·조회(getAllCotacts)·수정(update)·삭제(delete) 기능을 담당합니다. 특히 getAllCotacts() 메서드는 rawQuery로 Cursor를 얻은 뒤, 커서를 처음으로 이동시키고(moveToFirst()) 마지막 행까지 반복하면서(isAfterLast(), moveToNext()) 각 행의 값을 ArrayList에 담아 반환합니다. 반환된 리스트가 비어 있는지 여부는 앞서 본 isEmpty()로 확인하면 됩니다.

애플리케이션 실행하기

이제 애플리케이션을 실행해 보겠습니다. 실제 Android 스마트폰을 컴퓨터에 연결했다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤 툴바의 Run 아이콘을 클릭하고, 실행 기기로 자신의 모바일 기기를 선택하세요. 그러면 모바일 기기에 아래와 같은 기본 화면이 표시됩니다.

Android SQLite에서 커서(Cursor)로 가져온 배열 목록이 비어 있는지 확인하는 방법