안드로이드 DB이용한 도서 관리(입력, 조회)
- 자작 프로그램
- 2019. 11. 15.
학교 과제로 안드로이드 앱을 만들어오라고 했다.
어떤 DB를 이용할까 하다가 안드로이드에 내장 되어있는 SQLite라는게 있었다.
나는 그것을 이용해볼려고 한다.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="50dp">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="@+id/toolbar">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"></androidx.appcompat.widget.Toolbar>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabBackground="@android:color/background_dark"
app:tabIndicatorColor="#FFFFFF"
app:tabTextColor="#FFFFFF">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="입력" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="조회" />
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
fragment_insert.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context=".insert">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_marginTop="10dp">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="책 제목 : "
android:textSize="18sp"
android:textStyle="bold" />
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="제목"
android:inputType="textPersonName" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_marginTop="10dp"
>
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="책 저자 : "
android:textSize="18sp"
android:textStyle="bold"
android:layout_marginLeft="10dp"/>
<EditText
android:id="@+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="저자"
android:inputType="textPersonName" />
</LinearLayout>
<EditText
android:id="@+id/editText3"
android:layout_width="match_parent"
android:layout_height="606dp"
android:layout_marginTop="10dp"
android:ems="10"
android:hint="내용"
android:inputType="textMultiLine|textPersonName"
android:scrollbars="horizontal"
android:scrollHorizontally="true"
android:singleLine="true" />
<Button
android:id="@+id/buttonother"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="저장"
android:layout_marginTop="10dp"/>
</LinearLayout>
<?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"
tools:context=".check">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/imageView"
android:layout_width="171dp"
android:layout_height="146dp"
app:srcCompat="@drawable/book" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:text="TextView"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:text="TextView"
android:textSize="24sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="TextView"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
일단 디자인은 이렇게 해놓았다.
listbook.xml은 fragment_check.xml에 listView에 표시될것이다.
그리고 MainActivity.java 파일로 가서 탭 설정을 해주자.
package com.example.mybook;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.LinearLayout;
import com.google.android.material.tabs.TabLayout;
public class MainActivity extends AppCompatActivity {
LinearLayout container;
check ch;
insert in;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
container = (LinearLayout)findViewById(R.id.container);
ch = new check();
in = new insert();
getSupportFragmentManager().beginTransaction().add(R.id.container, in).commit();
TabLayout tabs = (TabLayout)findViewById(R.id.tabs);
tabs.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
int position = tab.getPosition();
if(position == 0)
getSupportFragmentManager().beginTransaction().replace(R.id.container, in).commit();
else if(position == 1)
getSupportFragmentManager().beginTransaction().replace(R.id.container, ch).commit();
}
@Override
public void onTabUnselected(TabLayout.Tab tab) { }
@Override
public void onTabReselected(TabLayout.Tab tab) { }
});
}
}
getSupportFragmentManager().beginTransaction().add(R.id.container, in).commit(); 을 이용해 첫 화면을 입력화면으로 나오게 해주었다.
그리고 TabLayout 이벤트를 이용해서 tab.getPosition()을 이용해 입력 탭이 눌러졌을때는 입력화면으로 replace 되게끔 하고
조회 버튼이 눌러졌으면 조회 화면으로 replace 되게끔 해놓았다.
그리고 이제 DB를 만들어보자 나는 SQLite DB를 이용했다.
package com.example.mybook;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class DBHelper extends SQLiteOpenHelper {
private Context context;
public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
this.context = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
StringBuffer sb = new StringBuffer();
sb.append("CREATE TABLE BOOK ( ");
sb.append(" _ID INTEGER PRIMARY KEY AUTOINCREMENT, ");
sb.append("TITLE TEXT, ");
sb.append("NAME TEXT, ");
sb.append("CONTENT TEXT) ");
db.execSQL(sb.toString());
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Toast.makeText(context, "버전이 올라갔습니다.", Toast.LENGTH_SHORT).show();
}
public void testDB() {
SQLiteDatabase db = getReadableDatabase();
Toast.makeText(context, "Table 생성완료", Toast.LENGTH_SHORT).show();
}
public long addBook(Book book) {
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("TITLE", book.getTitle());
values.put("NAME", book.getName());
values.put("CONTENT", book.getContent());
return db.insert("BOOK", null, values);
}
public List getAllBookData() {
StringBuffer sb = new StringBuffer();
sb.append("SELECT * FROM BOOK");
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery(sb.toString(), null);
List listbook = new ArrayList();
Book book = null;
while(cursor.moveToNext()) {
book = new Book();
book.set_id(cursor.getInt(0));
book.setTitle(cursor.getString(1));
book.setName(cursor.getString(2));
book.setContent(cursor.getString(3));
listbook.add(book);
}
return listbook;
}
}
DBHelper 생성자를 통해서 DB를 만들어주고 DBHelper 클래스가 실행되면 바로 테이블을 만들도록 해주었다.
StringBuffer로 테이블 생성 명령어를 집어넣어줬고 마지막에 execSQL로 실행해주었다
onUpgrade랑 testDB함수는 말 그대로이다.
addBook 함수는 입력화면에서 데이터를 가져와 데이터를 넣는 작업이다.
getAllBookData함수는 DB에 있는 데이터를 모두 가져오는 함수이다.
StringBuffer를 이용해서 Select 명령어를 넣어주고 DB를 읽기모드로 열어준다.
cursor 객체는 DB 명령어 결과를 넣어놓는 것이다.
그리고 List형으로 ArrayList를 생성해준다
Book 클래스는 나중에 보여주도록 하겠다
반복문을 통해서 DB 결과 받아 온것을 moveToNext를 통해서 Book 클래스에 하나하나 받아 온다
package com.example.mybook;
public class Book {
private int _id;
private String title;
private String name;
private String content;
public int get_id() {
return _id;
}
public void set_id(int _id) {
this._id = _id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
Book 클래스에는 그냥 getter와 setter밖에 없다.
package com.example.mybook;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class insert extends Fragment {
DBHelper dbHelper = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.fragment_insert,container,false);
Button button = (Button)rootView.findViewById(R.id.buttonother);
final EditText editText = (EditText)rootView.findViewById(R.id.editText);
final EditText editText2 = (EditText)rootView.findViewById(R.id.editText2);
final EditText editText3 = (EditText)rootView.findViewById(R.id.editText3);
if(dbHelper == null)
dbHelper = new DBHelper(getContext(), "BOOK", null, 1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String title = editText.getText().toString();
String name = editText2.getText().toString();
String content = editText3.getText().toString();
dbHelper.addBook(book);
Toast.makeText(getContext(), "Insert 완료", Toast.LENGTH_SHORT).show();
editText.setText("");
editText2.setText("");
editText3.setText("");
}
});
return rootView;
}
}
입력 화면이다
DB초기화를 해주고
저장 버튼을 누르면 editText에 있는 값들을 불러와서 DB에 넣어준다.
toast로 간단하게 db저장이 되면 insert 완료 라고 알림을 띄어준다.
package com.example.mybook;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class BookListAdapter extends BaseAdapter {
private List book;
private Context context;
public BookListAdapter(List book, Context context) {
this.book = book;
this.context = context;
}
@Override
public int getCount() {
return this.book.size();
}
@Override
public Object getItem(int position) {
return this.book.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// ViewHolder 패턴을 이용
Holder holder = null;
if(convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.listbook,null); // listbook 레이아웃 출력
holder = new Holder();
holder.iv = (ImageView)convertView.findViewById(R.id.imageView);
holder.tvTitle = (TextView)convertView.findViewById(R.id.textView);
holder.tvName = (TextView)convertView.findViewById(R.id.textView2);
holder.tvContent = (TextView)convertView.findViewById(R.id.textView3);
convertView.setTag(holder);
}else {
holder = (Holder) convertView.getTag();
}
//convertView가 있으면 홀더를 꺼냄
Book book = (Book) getItem(position);
holder.iv.setImageResource(R.drawable.book);
holder.tvTitle.setText("책 제목 : "+book.getTitle());
holder.tvName.setText("저자 : "+book.getName());
holder.tvContent.setText("책 소개 : "+book.getContent());
return convertView;
}
private class Holder {
public ImageView iv;
public TextView tvTitle;
public TextView tvName;
public TextView tvContent;
}
}
그리고 이 클래스는
리스트뷰에 뿌려줄 어댑터를 만든다.
ViewHolder 패턴을 이용해서 넣었다.
package com.example.mybook;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import java.util.List;
public class check extends Fragment {
DBHelper dbHelper = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.fragment_check,container,false);
ListView listView = (ListView)rootView.findViewById(R.id.listView);
if(dbHelper == null)
dbHelper = new DBHelper(getContext(), "BOOK", null, 1);
List listBook = dbHelper.getAllBookData(); // DB 안에 있는것을 모두 불러옴
listView.setAdapter(new BookListAdapter(listBook, getContext())); // ListView에 추가해줌
return rootView;
}
}
조회 화면에서는 DB를 초기화 시키고
ListView에다가 위에 만든 어댑터를 불러와서 자료를 모두 뿌려준다.
apk파일을 올려놨고 실행 해보고 싶은 사람은 실행 해보면 된다.