로컬 SQLite.NET 데이터베이스에 데이터 저장
이 빠른 시작에서 다음과 같은 작업을 수행하는 방법을 알아봅니다.
- 데이터를 SQLite.NET 데이터베이스에 로컬로 저장합니다.
이 빠른 시작은 Xamarin.Forms Shell 애플리케이션에서 로컬 SQLite.NET 데이터베이스에 데이터를 저장하는 방법을 안내합니다. 최종 애플리케이션은 다음과 같습니다.
필수 조건
이 빠른 시작을 시도하기 전에 이전 빠른 시작을 성공적으로 완료해야 합니다.
Visual Studio를 사용하여 앱 업데이트
Visual Studio를 시작하고 Notes 솔루션을 엽니다.
솔루션 탐색기에서 Notes 솔루션을 마우스 오른쪽 단추로 클릭하고 솔루션에 대한 NuGet 패키지 관리...를 선택합니다.
NuGet 패키지 관리자에서 찾아보기 탭을 선택하고 sqlite-net-pcl NuGet 패키지를 검색합니다.
Warning
이름이 유사한 NuGet 패키지가 많이 있습니다. 올바른 패키지에는 이러한 특성이 있습니다.
- 작성자: SQLite-net
- NuGet 링크: sqlite-net-pcl
패키지 이름에도 불구하고 이 NuGet 패키지는 .NET 표준 패키지에서 사용할 수 있습니다.
NuGet 패키지 관리자에서 올바른 sqlite-net-pcl 패키지를 선택하고 프로젝트 확인란을 선택한 다음 설치 단추를 클릭하여 솔루션에 추가합니다.
이 패키지는 데이터베이스 작업을 애플리케이션에 통합하는 데 사용되며, 솔루션의 모든 프로젝트에 추가됩니다.
Important
SQLite.NET praeclarum/sqlite-net 리포지토리에서 지원되는 타사 라이브러리입니다.
NuGet 패키지 관리자를 닫습니다.
솔루션 탐색기의 Notes 프로젝트에 있는 Models 폴더에서 Note.cs를 열고 기존 코드를 다음 코드로 바꿉니다.
using System; using SQLite; namespace Notes.Models { public class Note { [PrimaryKey, AutoIncrement] public int ID { get; set; } public string Text { get; set; } public DateTime Date { get; set; } } }
이 클래스는 애플리케이션의 각 노트에 대한 데이터를 저장하는
Note
모델을 정의합니다.ID
속성은 SQLite.NET 데이터베이스의 각Note
인스턴스가 SQLite.NET에서 제공되는 고유 ID를 갖도록PrimaryKey
및AutoIncrement
특성과 함께 표시됩니다.CTRL+S를 눌러 변경 내용을 Note.cs에 저장합니다.
Warning
다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.
솔루션 탐색기에서 Data라는 새 폴더를 Notes 프로젝트에 추가합니다.
솔루션 탐색기의 Notes 프로젝트에서 Data 폴더에 NoteDatabase라는 새 클래스를 추가합니다.
NoteDatabase.cs에서 기존 코드를 다음 코드로 바꿉니다.
using System.Collections.Generic; using System.Threading.Tasks; using SQLite; using Notes.Models; namespace Notes.Data { public class NoteDatabase { readonly SQLiteAsyncConnection database; public NoteDatabase(string dbPath) { database = new SQLiteAsyncConnection(dbPath); database.CreateTableAsync<Note>().Wait(); } public Task<List<Note>> GetNotesAsync() { //Get all notes. return database.Table<Note>().ToListAsync(); } public Task<Note> GetNoteAsync(int id) { // Get a specific note. return database.Table<Note>() .Where(i => i.ID == id) .FirstOrDefaultAsync(); } public Task<int> SaveNoteAsync(Note note) { if (note.ID != 0) { // Update an existing note. return database.UpdateAsync(note); } else { // Save a new note. return database.InsertAsync(note); } } public Task<int> DeleteNoteAsync(Note note) { // Delete a note. return database.DeleteAsync(note); } } }
이 클래스에는 데이터베이스를 만들고, 그 데이터베이스로부터 데이터를 읽고 쓰는 코드가 있습니다. 코드는 데이터베이스 작업을 백그라운드 스레드로 이동시키는 비동기 SQLite.NET API를 사용합니다. 또한
NoteDatabase
생성자는 데이터베이스 파일의 경로를 인수로 사용합니다. 이 경로는 다음 단계에서App
클래스에 의해 제공됩니다.CTRL+S를 눌러 변경 내용을 NoteDatabase.cs에 저장합니다.
Warning
다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.
솔루션 탐색기의 Notes 프로젝트에서 App.xaml을 확장하고 App.xaml.cs를 두 번 클릭하여 엽니다. 그런 다음 기존 코드를 다음 코드로 바꿉니다.
using System; using System.IO; using Notes.Data; using Xamarin.Forms; namespace Notes { public partial class App : Application { static NoteDatabase database; // Create the database connection as a singleton. public static NoteDatabase Database { get { if (database == null) { database = new NoteDatabase(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Notes.db3")); } return database; } } public App() { InitializeComponent(); MainPage = new AppShell(); } protected override void OnStart() { } protected override void OnSleep() { } protected override void OnResume() { } } }
이 코드는 새
NoteDatabase
인스턴스를 singleton으로 만들고 데이터베이스의 파일 이름을NoteDatabase
생성자에 인수로 전달하는Database
속성을 정의합니다. 데이터베이스를 싱글톤으로 노출하면 애플리케이션이 실행되는 동안 열린 상태로 유지되는 단일 데이터베이스 연결이 생성되므로 데이터베이스 작업이 수행될 때마다 데이터베이스 파일을 열거나 닫는 비용을 피할 수 있는 이점이 있습니다.CTRL+S를 눌러 변경 내용을 App.xaml.cs에 저장합니다.
Warning
다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.
솔루션 탐색기의 Notes 프로젝트에서 Views 폴더에 있는 NotesPage.xaml을 확장하고 NotesPage.xaml.cs를 엽니다. 그런 다음
OnAppearing
및OnSelectionChanged
메서드를 다음 코드로 바꿉니다.protected override async void OnAppearing() { base.OnAppearing(); // Retrieve all the notes from the database, and set them as the // data source for the CollectionView. collectionView.ItemsSource = await App.Database.GetNotesAsync(); } async void OnSelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.CurrentSelection != null) { // Navigate to the NoteEntryPage, passing the ID as a query parameter. Note note = (Note)e.CurrentSelection.FirstOrDefault(); await Shell.Current.GoToAsync($"{nameof(NoteEntryPage)}?{nameof(NoteEntryPage.ItemId)}={note.ID.ToString()}"); } }
OnAppearing
메서드는CollectionView
를 데이터베이스에 저장된 노트로 채웁니다.OnSelectionChanged
메서드는NoteEntryPage
로 이동하여 선택한Note
개체의ID
속성을 쿼리 매개 변수로 전달합니다.CTRL+S를 눌러 변경 내용을 NotesPage.xaml.cs에 저장합니다.
Warning
다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.
솔루션 탐색기에서 Views 폴더에 있는 NoteEntryPage.xaml을 확장하고 NoteEntryPage.xaml.cs를 엽니다. 그런 다음
LoadNote
,OnSaveButtonClicked
,OnDeleteButtonClicked
메서드를 다음 코드로 바꿉니다.async void LoadNote(string itemId) { try { int id = Convert.ToInt32(itemId); // Retrieve the note and set it as the BindingContext of the page. Note note = await App.Database.GetNoteAsync(id); BindingContext = note; } catch (Exception) { Console.WriteLine("Failed to load note."); } } async void OnSaveButtonClicked(object sender, EventArgs e) { var note = (Note)BindingContext; note.Date = DateTime.UtcNow; if (!string.IsNullOrWhiteSpace(note.Text)) { await App.Database.SaveNoteAsync(note); } // Navigate backwards await Shell.Current.GoToAsync(".."); } async void OnDeleteButtonClicked(object sender, EventArgs e) { var note = (Note)BindingContext; await App.Database.DeleteNoteAsync(note); // Navigate backwards await Shell.Current.GoToAsync(".."); }
NoteEntryPage
는LoadNote
메서드를 사용하여 ID가 페이지에 쿼리 매개 변수로 전달된 노트를 데이터베이스에서 검색하고, 페이지의BindingContext
에Note
개체로 저장합니다.OnSaveButtonClicked
이벤트 처리기가 실행되면Note
인스턴스가 데이터베이스에 저장되고 애플리케이션이 이전 페이지로 다시 이동합니다.OnDeleteButtonClicked
이벤트 처리기가 실행되면Note
인스턴스가 데이터베이스에서 삭제되고 애플리케이션이 이전 페이지로 다시 이동합니다.CTRL+S를 눌러 변경 내용을 NoteEntryPage.xaml.cs에 저장합니다.
각 플랫폼에서 프로젝트를 빌드하고 실행합니다. 자세한 내용은 빠른 시작 빌드를 참조하세요.
NotesPage에서 추가 단추를 눌러 NoteEntryPage로 이동하고 노트를 입력합니다. 노트를 저장한 후 애플리케이션은 NotesPage로 다시 이동합니다.
다양한 길이의 여러 노트를 입력하여 애플리케이션 동작을 관찰합니다. 애플리케이션을 닫고 다시 시작하여 입력한 노트가 데이터베이스에 저장되었는지 확인합니다.
Mac용 Visual Studio를 사용하여 앱 업데이트
Mac용 Visual Studio를 시작하고 Notes 솔루션을 엽니다.
Solution Pad에서 Notes 솔루션을 마우스 오른쪽 단추로 클릭하고 NuGet 패키지 관리...를 선택합니다.
NuGet 패키지 관리에서 찾아보기 탭을 선택하고, sqlite-net-pcl NuGet 패키지를 검색합니다.
Warning
이름이 유사한 NuGet 패키지가 많이 있습니다. 올바른 패키지에는 이러한 특성이 있습니다.
- 작성자: SQLite-net
- NuGet 링크: sqlite-net-pcl
패키지 이름에도 불구하고 이 NuGet 패키지는 .NET 표준 패키지에서 사용할 수 있습니다.
NuGet 패키지 관리 대화 상자에서 sqlite-net-pcl 패키지를 선택하고 패키지 추가 단추를 클릭하여 솔루션에 추가합니다.
이 패키지는 데이터베이스 작업을 애플리케이션에 통합하는 데 사용됩니다.
프로젝트 선택 대화 상자에서 모든 확인란이 선택되어 있는지 확인하고 확인 단추를 누릅니다.
이렇게 하면 솔루션의 모든 프로젝트에 NuGet 패키지가 추가됩니다.
Solution Pad의 Notes 프로젝트에서 Models 폴더의 Note.cs를 열고 기존 코드를 다음 코드로 바꿉니다.
using System; using SQLite; namespace Notes.Models { public class Note { [PrimaryKey, AutoIncrement] public int ID { get; set; } public string Text { get; set; } public DateTime Date { get; set; } } }
이 클래스는 애플리케이션의 각 노트에 대한 데이터를 저장하는
Note
모델을 정의합니다.ID
속성은 SQLite.NET 데이터베이스의 각Note
인스턴스가 SQLite.NET에서 제공되는 고유 ID를 갖도록PrimaryKey
및AutoIncrement
특성과 함께 표시됩니다.파일 > 저장을 선택하거나 ⌘ + S를 눌러 변경 내용을 Note.cs에 저장합니다.
Warning
다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.
Solution Pad에서 Data라는 새 폴더를 Notes 프로젝트에 추가합니다.
Solution Pad의 Notes 프로젝트에서 Data 폴더에 NoteDatabase라는 새 클래스를 추가합니다.
NoteDatabase.cs에서 기존 코드를 다음 코드로 바꿉니다.
using System.Collections.Generic; using System.Threading.Tasks; using SQLite; using Notes.Models; namespace Notes.Data { public class NoteDatabase { readonly SQLiteAsyncConnection database; public NoteDatabase(string dbPath) { database = new SQLiteAsyncConnection(dbPath); database.CreateTableAsync<Note>().Wait(); } public Task<List<Note>> GetNotesAsync() { //Get all notes. return database.Table<Note>().ToListAsync(); } public Task<Note> GetNoteAsync(int id) { // Get a specific note. return database.Table<Note>() .Where(i => i.ID == id) .FirstOrDefaultAsync(); } public Task<int> SaveNoteAsync(Note note) { if (note.ID != 0) { // Update an existing note. return database.UpdateAsync(note); } else { // Save a new note. return database.InsertAsync(note); } } public Task<int> DeleteNoteAsync(Note note) { // Delete a note. return database.DeleteAsync(note); } } }
이 클래스에는 데이터베이스를 만들고, 그 데이터베이스로부터 데이터를 읽고 쓰는 코드가 있습니다. 코드는 데이터베이스 작업을 백그라운드 스레드로 이동시키는 비동기 SQLite.NET API를 사용합니다. 또한
NoteDatabase
생성자는 데이터베이스 파일의 경로를 인수로 사용합니다. 이 경로는 다음 단계에서App
클래스에 의해 제공됩니다.파일 > 저장을 선택하거나 ⌘ + S를 눌러 변경 내용을 NoteDatabase.cs에 저장합니다.
Warning
다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.
Solution Pad의 Notes 프로젝트에서 App.xaml을 확장하고 App.xaml.cs를 두 번 클릭하여 엽니다. 그런 다음 기존 코드를 다음 코드로 바꿉니다.
using System; using System.IO; using Notes.Data; using Xamarin.Forms; namespace Notes { public partial class App : Application { static NoteDatabase database; // Create the database connection as a singleton. public static NoteDatabase Database { get { if (database == null) { database = new NoteDatabase(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Notes.db3")); } return database; } } public App() { InitializeComponent(); MainPage = new AppShell(); } protected override void OnStart() { } protected override void OnSleep() { } protected override void OnResume() { } } }
이 코드는 새
NoteDatabase
인스턴스를 singleton으로 만들고 데이터베이스의 파일 이름을NoteDatabase
생성자에 인수로 전달하는Database
속성을 정의합니다. 데이터베이스를 싱글톤으로 노출하면 애플리케이션이 실행되는 동안 열린 상태로 유지되는 단일 데이터베이스 연결이 생성되므로 데이터베이스 작업이 수행될 때마다 데이터베이스 파일을 열거나 닫는 비용을 피할 수 있는 이점이 있습니다.파일 > 저장을 선택하거나 ⌘ + S를 눌러 변경 내용을 App.xaml.cs에 저장합니다.
Warning
다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.
Solution Pad의 Notes 프로젝트에서 Views 폴더에 있는 NotesPage.xaml을 확장하고 NotesPage.xaml.cs를 엽니다. 그런 다음
OnAppearing
및OnSelectionChanged
메서드를 다음 코드로 바꿉니다.protected override async void OnAppearing() { base.OnAppearing(); // Retrieve all the notes from the database, and set them as the // data source for the CollectionView. collectionView.ItemsSource = await App.Database.GetNotesAsync(); } async void OnSelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.CurrentSelection != null) { // Navigate to the NoteEntryPage, passing the ID as a query parameter. Note note = (Note)e.CurrentSelection.FirstOrDefault(); await Shell.Current.GoToAsync($"{nameof(NoteEntryPage)}?{nameof(NoteEntryPage.ItemId)}={note.ID.ToString()}"); } }
OnAppearing
메서드는CollectionView
를 데이터베이스에 저장된 노트로 채웁니다.OnSelectionChanged
메서드는NoteEntryPage
로 이동하여 선택한Note
개체의ID
속성을 쿼리 매개 변수로 전달합니다.파일 > 저장을 선택하거나 ⌘ + S를 눌러 변경 내용을 NotesPage.xaml.cs에 저장합니다.
Warning
다음 단계에서 수정될 오류로 인해 지금은 애플리케이션이 빌드되지 않습니다.
Solution Pad에서 Views 폴더에 있는 NoteEntryPage.xaml을 확장하고 NoteEntryPage.xaml.cs를 엽니다. 그런 다음
LoadNote
,OnSaveButtonClicked
,OnDeleteButtonClicked
메서드를 다음 코드로 바꿉니다.async void LoadNote(string itemId) { try { int id = Convert.ToInt32(itemId); // Retrieve the note and set it as the BindingContext of the page. Note note = await App.Database.GetNoteAsync(id); BindingContext = note; } catch (Exception) { Console.WriteLine("Failed to load note."); } } async void OnSaveButtonClicked(object sender, EventArgs e) { var note = (Note)BindingContext; note.Date = DateTime.UtcNow; if (!string.IsNullOrWhiteSpace(note.Text)) { await App.Database.SaveNoteAsync(note); } // Navigate backwards await Shell.Current.GoToAsync(".."); } async void OnDeleteButtonClicked(object sender, EventArgs e) { var note = (Note)BindingContext; await App.Database.DeleteNoteAsync(note); // Navigate backwards await Shell.Current.GoToAsync(".."); }
NoteEntryPage
는LoadNote
메서드를 사용하여 ID가 페이지에 쿼리 매개 변수로 전달된 노트를 데이터베이스에서 검색하고, 페이지의BindingContext
에Note
개체로 저장합니다.OnSaveButtonClicked
이벤트 처리기가 실행되면Note
인스턴스가 데이터베이스에 저장되고 애플리케이션이 이전 페이지로 다시 이동합니다.OnDeleteButtonClicked
이벤트 처리기가 실행되면Note
인스턴스가 데이터베이스에서 삭제되고 애플리케이션이 이전 페이지로 다시 이동합니다.파일 > 저장을 선택하거나 ⌘ + S를 눌러 변경 내용을 NoteEntryPage.xaml.cs에 저장합니다.
각 플랫폼에서 프로젝트를 빌드하고 실행합니다. 자세한 내용은 빠른 시작 빌드를 참조하세요.
NotesPage에서 추가 단추를 눌러 NoteEntryPage로 이동하고 노트를 입력합니다. 노트를 저장한 후 애플리케이션은 NotesPage로 다시 이동합니다.
다양한 길이의 여러 노트를 입력하여 애플리케이션 동작을 관찰합니다. 애플리케이션을 닫고 다시 시작하여 입력한 노트가 데이터베이스에 저장되었는지 확인합니다.
다음 단계
이 빠른 시작에서는 다음과 같은 방법을 배웠습니다.
- 데이터를 SQLite.NET 데이터베이스에 로컬로 저장합니다.
XAML 스타일을 사용하여 애플리케이션의 스타일을 지정하려면 다음 빠른 시작으로 진행합니다.