首页 > 技术文章 > Room----Android数据库(SQLite)

best-hym 2020-02-01 14:40 原文

1.要想使用Room首先需要在build.grade中添加依赖

     dependencies {
       def room_version = "2.2.2"
 
       implementation "androidx.room:room-runtime:$room_version"
       annotationProcessor "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor
 
       // optional - Kotlin Extensions and Coroutines support for Room
       implementation "androidx.room:room-ktx:$room_version"
 
       // optional - RxJava support for Room
       implementation "androidx.room:room-rxjava2:$room_version"
 
       // optional - Guava support for Room, including Optional and ListenableFuture
       implementation "androidx.room:room-guava:$room_version"
 
       // Test helpers
       testImplementation "androidx.room:room-testing:$room_version"
     }
     

 

2.数据库可视化工具可以选择DB Browser for SQLite,具体请点击下方链接进行下载

http://www.sqlitebrowser.org/

具体案例(对Word实体进行增删改)

使用ViewModel,LiveData,Room等工具。

界面设计

  • 上方是一个ScrollView(数据多的时候可滑动),ScrollView内有一个TextView
  • 下方是四个按键,分别代表插入、删除、清空、修改

activity_main.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
        <androidx.constraintlayout.widget.ConstraintLayout 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=".MainActivity">
        
            <androidx.constraintlayout.widget.Guideline
                 android:id="@+id/guideline"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:orientation="horizontal"
                 app:layout_constraintGuide_percent="0.6" />
        
             <ScrollView
                 android:layout_width="0dp"
                 android:layout_height="0dp"
                 app:layout_constraintBottom_toTopOf="@+id/guideline"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toTopOf="parent">
        
                 <TextView
                     android:id="@+id/textView"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:text="TextView"
                     android:textSize="24sp" />
             </ScrollView>
        
             <Button
                 android:id="@+id/buttonInsert"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:text="insert"
                 app:layout_constraintBottom_toBottomOf="parent"
                 app:layout_constraintEnd_toStartOf="@+id/buttonUpdate"
                 app:layout_constraintHorizontal_bias="0.5"
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toTopOf="@+id/guideline"
                 app:layout_constraintVertical_bias="0.25" />
        
             <Button
                 android:id="@+id/buttonUpdate"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:text="update"
                 app:layout_constraintBottom_toBottomOf="@+id/buttonInsert"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintHorizontal_bias="0.5"
                 app:layout_constraintStart_toEndOf="@+id/buttonInsert"
                 app:layout_constraintTop_toTopOf="@+id/buttonInsert" />
        
             <Button
                 android:id="@+id/buttonClear"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:text="clear"
                 app:layout_constraintBottom_toBottomOf="@+id/buttonDelete"
                 app:layout_constraintEnd_toStartOf="@+id/buttonDelete"
                 app:layout_constraintHorizontal_bias="0.5"
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toTopOf="@+id/buttonDelete" />
        
             <Button
                 android:id="@+id/buttonDelete"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:text="delete"
                 app:layout_constraintBottom_toBottomOf="parent"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintHorizontal_bias="0.5"
                 app:layout_constraintStart_toEndOf="@+id/buttonClear"
                 app:layout_constraintTop_toBottomOf="@+id/buttonUpdate" />
         </androidx.constraintlayout.widget.ConstraintLayout>

因为是学习新的知识,所以不是太注重书写,所以一些地方不是很规范。

创建实体(Entity)

 package com.example.roombasic;
 
 import androidx.room.ColumnInfo;
 import androidx.room.Entity;
 import androidx.room.PrimaryKey;
 
 @Entity
 public class Word {
    @PrimaryKey(autoGenerate = true)
     private int id;
     @ColumnInfo(name = "english_word")
     private String word;
     @ColumnInfo(name = "chinese_meaning")
     private String chineseMeaning;
 
     public Word(String word, String chineseMeaning) {
         this.word = word;
         this.chineseMeaning = chineseMeaning;
     }
 
     public int getId() {
         return id;
     }
 
     public void setId(int id) {
         this.id = id;
     }
 
     public String getWord() {
         return word;
     }
 
     public void setWord(String word) {
         this.word = word;
     }
 
     public String getChineseMeaning() {
         return chineseMeaning;
     }
 
     public void setChineseMeaning(String chineseMeaning) {
         this.chineseMeaning = chineseMeaning;
     }
 }
  • 必须在类前使用注解 @Entity 来声明。

  • 表结构中必须有一个主键,主键的声明为 @PrimaryKey ,而主键递增则在其后添加 (autoGenerate = true)。

  • 列名的注解使用 @ColumnInfo ,可以定义表结构中的列名,如 (name = "english_word") 。

创建Dao

 package com.example.roombasic;
 
 import androidx.lifecycle.LiveData;
 import androidx.room.Dao;
 import androidx.room.Delete;
 import androidx.room.Insert;
 import androidx.room.Query;
 import androidx.room.Update;
 
 import java.util.List;
 
 @Dao
 public interface WordDao {
     @Insert
     void insertWords(Word... words);
 
     @Update
     void updateWords(Word... words);
 
     @Delete
     void deleteWords(Word... words);
 
     @Query("DElETE FROM WORD")
     void deleteAllWords();
 
     @Query("SELECT * FROM WORD ORDER BY ID DESC ")
     LiveData<List<Word>> getAllWordsLive();
 }
  • 需要使用注解来声明 @Dao 。
  • 每种接口需要使用注解来声明,如@Insert、@Update、@Delete。
  • @Query("select * from word order by id desc") 是查询语句。
  • 接口不需要自己来实现,room已经帮我们写出了具体的代码。
  • Word... words 表明可以传进多个参数。类名... 对象名s 代表可以传递多个参数。

创建database

 package com.example.roombasic;
 
 import android.content.Context;
 
 import androidx.room.Database;
 import androidx.room.Room;
 import androidx.room.RoomDatabase;
 
 @Database(entities = {Word.class}, version = 1, exportSchema = false)
 public abstract class WordDataBase extends RoomDatabase {
     private static WordDataBase INSTANCE;
 
     static synchronized WordDataBase getDatabase(Context context) {
         if (INSTANCE == null) {
             INSTANCE = Room.databaseBuilder(context.getApplicationContext(), WordDataBase.class, "word_database").build();
         }
         return INSTANCE;
     }
     public abstract WordDao getWordDao();
 }
  • 使用注解来声明 @Database(entities = {Word.class},version = 1,exportSchema = false)

    • entities = {Word.class}的{}中来填写entity,可添加多个。

    • version 是当前数据库版本。

  • synchronized为java中的锁机制,多线程防止出错。

  • Room.databaseBuilder(context.getApplicationContext(),WordDatabase.class,"word_database").build

    • 第一个参数是activity,第二个参数为database的映射,第三个参数为数据库名称。

创建ViewModel绑定数据

 package com.example.roombasic;

 import android.app.Application;
 import android.os.AsyncTask;
 
 import androidx.annotation.NonNull;
 import androidx.lifecycle.AndroidViewModel;
 import androidx.lifecycle.LiveData;
 
 import java.util.List;
 
 public class WordViewModel extends AndroidViewModel {
     private WordDao wordDao;
     private LiveData<List<Word>> allWordsLive;
 
     public WordViewModel(@NonNull Application application) {
         super(application);
         WordDataBase wordDataBase = WordDataBase.getDatabase(application);
         wordDao = wordDataBase.getWordDao();
         allWordsLive = wordDao.getAllWordsLive();
     }
 
     public LiveData<List<Word>> getAllWordsLive() {
         return allWordsLive;
     }
 
     void insertWords(Word... words) {
         new InsertAsyncTask(wordDao).execute(words);
     }
 
     void updateWords(Word... words) {
         new UpdateAsyncTask(wordDao).execute(words);
     }
 
     void deleteWords(Word... words) {
         new DeleteAsyncTask(wordDao).execute(words);
     }
 
     void deleteAllWords(Word... words) {
         new DeleteAllAsyncTask(wordDao).execute();
     }
 
     static class InsertAsyncTask extends AsyncTask<Word, Void, Void> {
         private WordDao wordDao;
 
         public InsertAsyncTask(WordDao wordDao) {
             this.wordDao = wordDao;
         }
 
         @Override
         protected Void doInBackground(Word... words) {
             wordDao.insertWords(words);
             return null;
         }
     }
 
     static class UpdateAsyncTask extends AsyncTask<Word, Void, Void> {
         private WordDao wordDao;
 
         public UpdateAsyncTask(WordDao wordDao) {
             this.wordDao = wordDao;
         }
 
         @Override
         protected Void doInBackground(Word... words) {
             wordDao.updateWords(words);
             return null;
         }
     }
 
     static class DeleteAsyncTask extends AsyncTask<Word, Void, Void> {
         private WordDao wordDao;
 
         public DeleteAsyncTask(WordDao wordDao) {
             this.wordDao = wordDao;
         }
 
         @Override
         protected Void doInBackground(Word... words) {
             wordDao.deleteWords(words);
             return null;
         }
     }
 
     static class DeleteAllAsyncTask extends AsyncTask<Void, Void, Void> {
         private WordDao wordDao;
 
         public DeleteAllAsyncTask(WordDao wordDao) {
             this.wordDao = wordDao;
        }
 
         @Override
         protected Void doInBackground(Void... voids) {
             wordDao.deleteAllWords();
             return null;
         }
     }
 }

在MainActivity.java中添加按键监听

 package com.example.roombasic;
 
 import android.os.Bundle;
 import android.view.View;
import android.widget.Button;
import android.widget.TextView;
 
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.lifecycle.Observer;
 import androidx.lifecycle.ViewModelProviders;
 
 import java.util.List;
 
 public class MainActivity extends AppCompatActivity {
     TextView textView;
     Button buttonInsert, buttonDelete, buttonUpdate, buttonClear;
     WordViewModel wordViewModel;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         wordViewModel = ViewModelProviders.of(this).get(WordViewModel.class);
         textView = findViewById(R.id.textView);
         wordViewModel.getAllWordsLive().observe(this, new Observer<List<Word>>() {
             @Override
             public void onChanged(List<Word> words) {
                 StringBuilder text = new StringBuilder();
                 for (int i = 0; i < words.size(); i++) {
                     Word word = words.get(i);
                     text.append(word.getId()).append(":").append(word.getWord()).append("=").append(word.getChineseMeaning()).append("\n");
                 }
                 textView.setText(text.toString());
             }
         });
 
         buttonInsert = findViewById(R.id.buttonInsert);
         buttonClear = findViewById(R.id.buttonClear);
         buttonDelete = findViewById(R.id.buttonDelete);
         buttonUpdate = findViewById(R.id.buttonUpdate);
 
         buttonInsert.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 Word word1 = new Word("Hello", "你好!");
                 Word word2 = new Word("World", "世界!");
                 wordViewModel.insertWords(word1,word2);
             }
         });
 
         buttonClear.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 wordViewModel.deleteAllWords();
             }
         });
 
         buttonUpdate.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 Word word = new Word("Hi", "你好啊!");
                 word.setId(9);
                 wordViewModel.updateWords(word);
             }
         });
 
         buttonDelete.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 Word word = new Word("Hi", "你好啊!");
                 word.setId(7);
                 wordViewModel.deleteWords(word);
             }
         });
     }
 }

该实例中修改与删除使用主键进行的,以后会进行修改与完善 。

暂时只学习了一点皮毛,后续会增加一些新的内容。

推荐阅读