Write By xyx IN csdn @包罗万码 In Guangzhou
转载请注明出处:https://blog.csdn.net/a316375/article/details/83057528
Android Room官方Demo详解:
四个步骤带你秒懂Android数据库的Room使用方式:
附加优化了自己添加的真删改査使用代码
Room采用DAO模式,
新建一个O对象
@Entity(tableName = "word_table")
public class Word {
@PrimaryKey(autoGenerate = true)
private int point;
@NonNull
@ColumnInfo(name = "word")
private String mWord;
public Word(@NonNull String word) {
this.mWord = word;
}
@NonNull
public void setPoint(int point) {
this.point = point;
}
@NonNull
public int getPoint() {
return this.point;
}
@NonNull
public String getWord() {
return this.mWord;
}
}
新建一个DAO对象
@Dao
public interface WordDao {
@Query("UPDATE word_table SET word = :changword WHERE point = :Id")
void updateWord(int Id,String changword);
@Update
void update(Word entity);
@Query("SELECT * FROM word_table WHERE word LIKE :first AND "
+ "word LIKE :last LIMIT 1")
Word findByName(String first, String last);
// LiveData is a data holder class that can be observed within a given lifecycle.
// Always holds/caches latest version of data. Notifies its active observers when the
// data has changed. Since we are getting all the contents of the database,
// we are notified whenever any of the database contents have changed.
@Query("SELECT * from word_table ORDER BY word ASC")
LiveData<List<Word>> getAlphabetizedWords();
// We do not need a conflict strategy, because the word is our primary key, and you cannot
// add two items with the same primary key to the database. If the table has more than one
// column, you can use @Insert(onConflict = OnConflictStrategy.REPLACE) to update a row.
@Insert
void insert(Word word);
@Query("DELETE FROM word_table")
void deleteAll();
//根据名字删除
@Query("DELETE FROM word_table where word=:word")
void deleteFormName(String word);
//根据名字+索引删除
@Query("DELETE FROM word_table where word=:word and point=:point")
void deleteFormName(String word,int point);
}
新建一个RoomDatabase对象
(以上记忆为三步骤Obj(数据库表的列设置)-->DAO(数据库增删改査语法)-->RoomDatabase(数据库操作类))
@Database(entities = {Word.class}, version = 2 )
public abstract class WordRoomDatabase extends RoomDatabase {
public abstract WordDao wordDao();
// marking the instance as volatile to ensure atomic access to the variable
private static volatile WordRoomDatabase INSTANCE;
static WordRoomDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (WordRoomDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
WordRoomDatabase.class, "word_database")
// Wipes and rebuilds instead of migrating if no Migration object.
// Migration is not part of this codelab.
.fallbackToDestructiveMigration()
.addCallback(sRoomDatabaseCallback)
.build();
}
}
}
return INSTANCE;
}
/**
* Override the onOpen method to populate the database.
* For this sample, we clear the database every time it is created or opened.
*
* If you want to populate the database only when the database is created for the 1st time,
* override RoomDatabase.Callback()#onCreate
*/
private static RoomDatabase.Callback sRoomDatabaseCallback = new RoomDatabase.Callback() {
@Override
public void onOpen(@NonNull SupportSQLiteDatabase db) {
super.onOpen(db);
// If you want to keep the data through app restarts,
// comment out the following line.
new PopulateDbAsync(INSTANCE).execute();
}
};
/**
* Populate the database in the background.
* If you want to start with more words, just add them.
*/
private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {
private final WordDao mDao;
PopulateDbAsync(WordRoomDatabase db) {
mDao = db.wordDao();
}
@Override
protected Void doInBackground(final Void... params) {
// Start the app with a clean database every time.
// Not needed if you only populate on creation.
//mDao.deleteAll();
Word word = new Word("Hello");
mDao.insert(word);
word = new Word("World");
mDao.insert(word);
return null;
}
}
}
注意:Room不能运行在UI界面,所以数据采用仓储模式Repository
class WordRepository {
private WordDao mWordDao;
private LiveData<List<Word>> mAllWords;
// Note that in order to unit test the WordRepository, you have to remove the Application
// dependency. This adds complexity and much more code, and this sample is not about testing.
// See the BasicSample in the android-architecture-components repository at
// https://github.com/googlesamples
WordRepository(Application application) {
WordRoomDatabase db = WordRoomDatabase.getDatabase(application);
mWordDao = db.wordDao();
mAllWords = mWordDao.getAlphabetizedWords();
}
// Room executes all queries on a separate thread.
// Observed LiveData will notify the observer when the data has changed.
LiveData<List<Word>> getAllWords() {
return mAllWords;
}
// You must call this on a non-UI thread or your app will crash.
// Like this, Room ensures that you're not doing any long running operations on the main
// thread, blocking the UI.
void insert(Word word) {
new insertAsyncTask(mWordDao).execute(word);
}
private static class insertAsyncTask extends AsyncTask<Word, Void, Void> {
private WordDao mAsyncTaskDao;
insertAsyncTask(WordDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final Word... params) {
mAsyncTaskDao.insert(params[0]);
mAsyncTaskDao.updateWord(1,"Changed"+params[0].getWord());
return null;
}
}
}
如果是Activity要获取数据并且获取数据库实现更新,借助一个ViewModel
public class WordViewModel extends AndroidViewModel {
private WordRepository mRepository;
// Using LiveData and caching what getAlphabetizedWords returns has several benefits:
// - We can put an observer on the data (instead of polling for changes) and only update the
// the UI when the data actually changes.
// - Repository is completely separated from the UI through the ViewModel.
private LiveData<List<Word>> mAllWords;
public WordViewModel(Application application) {
super(application);
mRepository = new WordRepository(application);
mAllWords = mRepository.getAllWords();
}
LiveData<List<Word>> getAllWords() {
return mAllWords;
}
void insert(Word word) {
mRepository.insert(word);
}
}
这是一个熟悉的Recycleview.Adatper,
public class WordListAdapter extends RecyclerView.Adapter<WordListAdapter.WordViewHolder> {
class WordViewHolder extends RecyclerView.ViewHolder {
private final TextView wordItemView;
private WordViewHolder(View itemView) {
super(itemView);
wordItemView = itemView.findViewById(R.id.textView);
}
}
private final LayoutInflater mInflater;
private List<Word> mWords = Collections.emptyList(); // Cached copy of words
WordListAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
@Override
public WordViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(R.layout.recyclerview_item, parent, false);
return new WordViewHolder(itemView);
}
@Override
public void onBindViewHolder(WordViewHolder holder, int position) {
Word current = mWords.get(position);
holder.wordItemView.setText(current.getWord());
}
void setWords(List<Word> words) {
mWords = words;
notifyDataSetChanged();
}
@Override
public int getItemCount() {
return mWords.size();
}
}
下面两个Activity去实现
public class MainActivity extends AppCompatActivity {
public static final int NEW_WORD_ACTIVITY_REQUEST_CODE = 1;
private WordViewModel mWordViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
RecyclerView recyclerView = findViewById(R.id.recyclerview);
final WordListAdapter adapter = new WordListAdapter(this);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
// Get a new or existing ViewModel from the ViewModelProvider.
mWordViewModel = ViewModelProviders.of(this).get(WordViewModel.class);
// Add an observer on the LiveData returned by getAlphabetizedWords.
// The onChanged() method fires when the observed data changes and the activity is
// in the foreground.
mWordViewModel.getAllWords().observe(this, new Observer<List<Word>>() {
@Override
public void onChanged(@Nullable final List<Word> words) {
// Update the cached copy of the words in the adapter.
adapter.setWords(words);
}
});
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, NewWordActivity.class);
startActivityForResult(intent, NEW_WORD_ACTIVITY_REQUEST_CODE);
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == NEW_WORD_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
Word word = new Word(data.getStringExtra(NewWordActivity.EXTRA_REPLY));
mWordViewModel.insert(word);
} else {
Toast.makeText(
getApplicationContext(),
R.string.empty_not_saved,
Toast.LENGTH_LONG).show();
}
}
}
第二个Activity按钮实现:
public class NewWordActivity extends AppCompatActivity {
public static final String EXTRA_REPLY = "com.example.android.wordlistsql.REPLY";
private EditText mEditWordView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_word);
mEditWordView = findViewById(R.id.edit_word);
final Button button = findViewById(R.id.button_save);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent replyIntent = new Intent();
if (TextUtils.isEmpty(mEditWordView.getText())) {
setResult(RESULT_CANCELED, replyIntent);
} else {
String word = mEditWordView.getText().toString();
replyIntent.putExtra(EXTRA_REPLY, word);
setResult(RESULT_OK, replyIntent);
}
finish();
}
});
}
}
附带编译遇到的坑:https://mp.csdn.net/postedit/83057354
另带配置导入设置
将以下代码添加到依赖项块末尾的build.gradle
(Module:app)文件中。
// Room components
implementation "android.arch.persistence.room:runtime:$rootProject.roomVersion"
annotationProcessor "android.arch.persistence.room:compiler:$rootProject.roomVersion"
androidTestImplementation "android.arch.persistence.room:testing:$rootProject.roomVersion"
// Lifecycle components
implementation "android.arch.lifecycle:extensions:$rootProject.archLifecycleVersion"
annotationProcessor "android.arch.lifecycle:compiler:$rootProject.archLifecycleVersion"
在您的工程Project 的 build.gradle
文件中,末尾添加以下代码,如下面的代码所示。
ext {
roomVersion = '1.1.1'
archLifecycleVersion = '1.1.1'
}