detail:使用room框架,做一个增删查改的android版本sqlite
step1: C:\Users\HHL\AndroidStudioProjects\MyApplication8\app\src\main AppDatabase
package com.example.myapplication;
import androidx.room.Database;
import androidx.room.RoomDatabase;
/**
* @author acampbell
*/
@Database(exportSchema = false, entities = {Note.class, Category.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public static final String DB_NAME = "app_db";
public abstract NoteDao getNoteDao();
public abstract CategoryDao getCategoryDao();
}
step2: Category
package com.example.myapplication;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
/**
* @author acampbell
*/
@Entity(tableName = "category")
public class Category {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
private long id;
@ColumnInfo(name = "name")
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
step3: CategoryAdapter
package com.example.myapplication;
import android.content.Context;
import android.widget.ArrayAdapter;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.List;
/**
* @author acampbell
*/
public class CategoryAdapter extends ArrayAdapter<Category> {
private final List<Category> categories;
public CategoryAdapter(@NonNull Context context,
@LayoutRes int resource,
List<Category> categories) {
super(context, resource, categories);
this.categories = categories;
}
@Override
public int getCount() {
return super.getCount() + 1;
}
@Nullable
@Override
public Category getItem(int position) {
if (position == 0) {
Category category = new Category();
category.setId(0);
category.setName(getContext().getString(R.string.create_new_category));
return category;
}
return super.getItem(position - 1);
}
public int getCategoryPosition(@Nullable Long categoryId) {
if (categoryId != null) {
for (int i = 0; i < categories.size(); i++) {
if (categoryId == categories.get(i).getId()) {
return i + 1;
}
}
}
return -1;
}
}
step4: CategoryDao
package com.example.myapplication;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import java.util.List;
/**
* @author acampbell
*/
@Dao
public interface CategoryDao {
@Insert
long insert(Category category);
@Query("SELECT * FROM category")
List<Category> getAll();
@Delete
void deleteAll(Category categories);
}
step5: CategoryNote
package com.example.myapplication;
public class CategoryNote extends Note {
private String categoryName;
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
}
step6: EditNoteActivity
package com.example.myapplication;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.room.Room;
import java.util.List;
public class EditNoteActivity extends AppCompatActivity implements View.OnClickListener, AdapterView.OnItemSelectedListener {
public static final String EXTRA_NOTE_ID = "EXTRA_NOTE_ID";
private AppDatabase db;
private TextView title;
private TextView description;
private TextView category;
private Spinner categorySpinner;
private CategoryAdapter adapter;
private Long noteId;
private Note note;
public static Bundle newInstanceBundle(long noteId) {
Bundle bundle = new Bundle();
bundle.putLong(EXTRA_NOTE_ID, noteId);
return bundle;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_note);
Intent intent = getIntent();
if (intent.hasExtra(EXTRA_NOTE_ID)) {
noteId = intent.getLongExtra(EXTRA_NOTE_ID, -1);
}
db = Room.databaseBuilder(this, AppDatabase.class, AppDatabase.DB_NAME).build();
title = (TextView) findViewById(R.id.title);
description = (TextView) findViewById(R.id.description);
category = (TextView) findViewById(R.id.category);
findViewById(R.id.save).setOnClickListener(this);
categorySpinner = (Spinner) findViewById(R.id.category_spinner);
categorySpinner.setOnItemSelectedListener(this);
}
@Override
protected void onResume() {
super.onResume();
loadCategories();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.save:
saveNote();
break;
}
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (position == 0) {
category.setVisibility(View.VISIBLE);
} else {
category.setVisibility(View.GONE);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
private void loadNote() {
new AsyncTask<Long, Void, CategoryNote>() {
@Override
protected CategoryNote doInBackground(Long... params) {
return db.getNoteDao().getCategoryNote(params[0]);
}
@Override
protected void onPostExecute(CategoryNote note) {
setNote(note);
}
}.execute(noteId);
}
private void setNote(Note note) {
this.note = note;
title.setText(note.getTitle());
description.setText(note.getDescription());
int categoryPosition = adapter.getCategoryPosition(note.getCategoryId());
if (categoryPosition > 0) {
categorySpinner.setSelection(categoryPosition);
}
}
private void loadCategories() {
new AsyncTask<Void, Void, List<Category>>() {
@Override
protected List<Category> doInBackground(Void... params) {
return db.getCategoryDao().getAll();
}
@Override
protected void onPostExecute(List<Category> adapterCategories) {
setCategories(adapterCategories);
if (noteId != null) {
loadNote();
}
}
}.execute();
}
private void setCategories(List<Category> categories) {
adapter = new CategoryAdapter(this, android.R.layout.simple_list_item_1, categories);
categorySpinner.setAdapter(adapter);
}
private void saveNote() {
if (note == null) {
note = new Note();
}
note.setTitle(title.getText().toString().trim());
note.setDescription(description.getText().toString().trim());
final String categoryName = category.getText().toString().trim();
Category selectedCategory = adapter.getItem(categorySpinner.getSelectedItemPosition());
final Long selectedCategoryId = (selectedCategory == null || selectedCategory.getId() <= 0) ? null : selectedCategory.getId();
new AsyncTask<Note, Void, Void>() {
@Override
protected Void doInBackground(Note... params) {
Note saveNote = params[0];
if (selectedCategoryId != null) {
saveNote.setCategoryId(selectedCategoryId);
} else if (categoryName.length() > 0) {
Category category = new Category();
category.setName(categoryName);
long categoryId = db.getCategoryDao().insert(category);
saveNote.setCategoryId(categoryId);
} else {
note.setCategoryId(null);
}
if (saveNote.getId() > 0) {
db.getNoteDao().updateAll(saveNote);
} else {
db.getNoteDao().insertAll(saveNote);
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
setResult(RESULT_OK);
finish();
}
}.execute(note);
}
}
step7: Note
package com.example.myapplication;
import androidx.annotation.Nullable;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
/**
* @author acampbell
*/
@Entity(tableName = "note")
public class Note {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
private long id;
@ColumnInfo(name = "title")
private String title;
@ColumnInfo(name = "description")
private String description;
@ColumnInfo(name = "category_id")
private Long categoryId;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Nullable
public Long getCategoryId() {
return categoryId;
}
public void setCategoryId(@Nullable Long categoryId) {
this.categoryId = categoryId;
}
}
step8: NoteAdapter
package com.example.myapplication;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
/**
* @author acampbell
*/
public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.ViewHolder> {
private List<CategoryNote> notes = new ArrayList<>();
private final ActionCallback callback;
public NoteAdapter(@NonNull ActionCallback callback) {
this.callback = callback;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_note, parent, false);
final ViewHolder viewHolder = new ViewHolder(view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callback.onEdit(notes.get(viewHolder.getAdapterPosition()));
}
});
return viewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
CategoryNote note = notes.get(position);
holder.title.setText(note.getTitle());
holder.id.setText(String.valueOf(note.getId()));
holder.description.setText(note.getDescription());
holder.category.setText(note.getCategoryName());
}
@Override
public int getItemCount() {
return notes.size();
}
public CategoryNote getNote(int position) {
return notes.get(position);
}
public void setNotes(@NonNull List<CategoryNote> notes) {
this.notes = notes;
notifyDataSetChanged();
}
public interface ActionCallback {
void onEdit(CategoryNote note);
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView title, description, category, id;
ViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
id = (TextView) itemView.findViewById(R.id.id);
description = (TextView) itemView.findViewById(R.id.description);
category = (TextView) itemView.findViewById(R.id.category);
}
}
}
step9: NoteDao
package com.example.myapplication;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
/**
* @author acampbell
*/
@Dao
public interface NoteDao {
@Insert
void insertAll(Note Notes);
@Update
void updateAll(Note Notes);
@Query("SELECT * FROM Note")
List<Note> getAll();
@Query("SELECT Note.id, Note.title, Note.description, category.name as categoryName " +
"FROM Note " +
"LEFT JOIN category ON Note.category_id = category.id")
List<CategoryNote> getCategoryNotes();
@Query("SELECT Note.id, Note.title, Note.description, Note.category_id " +
"FROM Note " +
"LEFT JOIN category ON Note.category_id = category.id " +
"WHERE Note.id = :NoteId")
CategoryNote getCategoryNote(long NoteId);
@Delete
void deleteAll(Note... Notes);
}
step10: TextActivity
package com.example.myapplication;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import androidx.cardview.widget.CardView;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.room.Room;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import java.util.List;
public class TextActivity extends AppCompatActivity
implements NoteAdapter.ActionCallback, View.OnClickListener {
FloatingActionButton mFloatingActionButton;
ConstraintLayout mConstraintLayout;
TextInputEditText mTextInputEditText;
CardView mCardView;
TextInputLayout mTextInputLayout;
private NoteAdapter adapter;
private AppDatabase db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = Room.databaseBuilder(this, AppDatabase.class, AppDatabase.DB_NAME).build();
findViewById(R.id.add).setOnClickListener(this);
adapter = new NoteAdapter(this);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
deleteNote(adapter.getNote(viewHolder.getAdapterPosition()));
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recyclerView);
}
@Override
protected void onResume() {
super.onResume();
loadNotes();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.add:
startActivity(new Intent(this, EditNoteActivity.class));
break;
}
}
private void loadNotes() {
new AsyncTask<Void, Void, List<CategoryNote>>() {
@Override
protected List<CategoryNote> doInBackground(Void... params) {
return db.getNoteDao().getCategoryNotes();
}
@Override
protected void onPostExecute(List<CategoryNote> notes) {
adapter.setNotes(notes);
}
}.execute();
}
@SuppressLint("StaticFieldLeak")
private void deleteNote(Note note) {
new AsyncTask<Note, Void, Void>() {
@Override
protected Void doInBackground(Note... params) {
db.getNoteDao().deleteAll(params);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
loadNotes();
}
}.execute(note);
}
@Override
public void onPointerCaptureChanged(boolean hasCapture) {
}
@Override
public void onEdit(CategoryNote note) {
Intent intent = new Intent(this, EditNoteActivity.class);
intent.putExtras(EditNoteActivity.newInstanceBundle(note.getId()));
startActivity(intent);
}
}
step11: build 引用
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
end