一、说明
Room是Android Jetpack中的一部分,是在SQLite的基础上提供了一个抽象层。本文使用Room结合LiveData,ViewModel实现了一个Demo。
二、实例
1. 添加依赖
build.gradle (Module: app)添加依赖
// Room components
dependencies {
// Room components
implementation "androidx.room:room-runtime:$rootProject.roomVersion"
annotationProcessor "androidx.room:room-compiler:$rootProject.roomVersion"
androidTestImplementation "androidx.room:room-testing:$rootProject.roomVersion"
// Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:$rootProject.archLifecycleVersion"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$rootProject.archLifecycleVersion"
// UI
implementation "com.google.android.material:material:$rootProject.materialVersion"
}
build.gradle (Project: room_java) 填写版本号,版本号从这里获取
ext {
roomVersion = '2.2.5'
archLifecycleVersion = '2.2.0'
materialVersion = '1.0.0'
}
2. Entity类
@Entity(tableName = "feizai_table")
public class Feizai {
@PrimaryKey
@NonNull
@ColumnInfo(name = "first_name")
private String firstName;
@ColumnInfo(name = "second_name")
private String secondName;
@NonNull
public String getFirstName() {
return firstName;
}
public void setFirstName(@NonNull String firstName) {
this.firstName = firstName;
}
public String getSecondName() {
return secondName;
}
public void setSecondName(String secondName) {
this.secondName = secondName;
}
}
3. Dao接口
注意,数据库DAO是一个接口。删除和修改的时候,传进来一个Feizai类,但是会根据Feizai类中对应数据库的主键进行修改和删除,即Feizai类的其它字段是什么不管,但是会根据主键对应字段的值对数据库进行操作。使用LiveData是为了监测数据库,实时刷新界面。
@Dao
public interface FeizaiDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
void insert(Feizai feizai);
@Query("SELECT * FROM feizai_table")
LiveData<List<Feizai>> getAllFeizai();
@Delete(entity = Feizai.class)
void delete(Feizai feizai);
@Update(entity = Feizai.class)
void update(Feizai feizai);
}
4. Database类
修改数据库的时候需要对数据库进行版本升级,即version+1,在addMigrations中添加数据库操作。如果是减少数据库表中字段,可以创建一张临时表,然后把数据迁移到临时表,删除旧数据库表,然后创建同旧数据库同名的数据库表,然后把临时表中的数据迁移过来新的数据库表中,再删除临时数据库表,以此来删除数据库中的字段并且把旧数据保存下来。
@Database(entities = {Feizai.class}, version = 1, exportSchema = false)
public abstract class FeizaiDatabase extends RoomDatabase {
public abstract FeizaiDao getFeizaiDao();
private static volatile FeizaiDatabase INSTANCE;
private static final int NUMBER_OF_THREADS = 4;
public static final ExecutorService databaseWriteExecutor =
Executors.newFixedThreadPool(NUMBER_OF_THREADS);
public static FeizaiDatabase getDatabase(Context context) {
if (INSTANCE == null) {
synchronized (FeizaiDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
FeizaiDatabase.class, "Feizai.db")
.addMigrations(MIGRATION_1_2)
.build();
}
}
}
return INSTANCE;
}
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE feizai_table ADD COLUMN sex STRING");
}
};
}
5. Repository类
public class FeizaiRepository {
private FeizaiDao mFeizaiDao;
private LiveData<List<Feizai>> mFeizais;
public FeizaiRepository(Application application) {
FeizaiDatabase db = FeizaiDatabase.getDatabase(application);
mFeizaiDao = db.getFeizaiDao();
mFeizais = mFeizaiDao.getAllFeizai();
}
public LiveData<List<Feizai>> getAllFeizais() {
return mFeizais;
}
public void insert(Feizai feizai) {
FeizaiDatabase.databaseWriteExecutor.execute(new Runnable() {
@Override
public void run() {
mFeizaiDao.insert(feizai);
mFeizais = mFeizaiDao.getAllFeizai();
}
});
}
public void delete(Feizai feizai) {
WordRoomDatabase.databaseWriteExecutor.execute(new Runnable() {
@Override
public void run() {
mFeizaiDao.delete(feizai);
}
});
}
public void update(Feizai feizai) {
WordRoomDatabase.databaseWriteExecutor.execute(new Runnable() {
@Override
public void run() {
mFeizaiDao.update(feizai);
}
});
}
}
6. ViewModel类
public class FeizaiViewModel extends AndroidViewModel {
private FeizaiRepository mReposity;
private LiveData<List<Feizai>> mAllFeizais;
public FeizaiViewModel (Application application) {
super(application);
mReposity = new FeizaiRepository(application);
mAllFeizais = mReposity.getAllFeizais();
}
public LiveData<List<Feizai>> getmAllFeizais() {
return mAllFeizais;
}
public void insert(Feizai feizai) {
mReposity.insert(feizai);
}
public void delete(Feizai feizai) {
mReposity.delete(feizai);
}
public void update(Feizai feizai) {
mReposity.update(feizai);
}
}
7. feizai_item.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="4dp"
style="@style/word_title">
<TextView
android:id="@+id/item_first"
android:layout_marginVertical="10dp"
android:layout_width ="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/item_second"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
8. activity_feizai.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=".FeizaiActivity">
<EditText
android:id="@+id/first_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:hint="First Name"/>
<EditText
android:id="@+id/second_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/first_name"
android:hint="Second Name"/>
<Button
android:id="@+id/btn_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/second_name"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/delete"
android:text="@string/insert"/>
<Button
android:id="@+id/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/second_name"
app:layout_constraintLeft_toRightOf="@id/btn_add"
app:layout_constraintRight_toRightOf="parent"
android:text="@string/delete"/>
<Button
android:id="@+id/btn_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/btn_add"
app:layout_constraintLeft_toLeftOf="@id/btn_add"
android:text="@string/update"/>
<Button
android:id="@+id/insert"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/delete"
app:layout_constraintLeft_toLeftOf="@id/delete"
android:text="占坑"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rc_feizai"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="6dp"
app:layout_constraintTop_toBottomOf="@id/btn_update"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
9. FeizaiListAdapter类
public class FeizaiListAdapter extends RecyclerView.Adapter<FeizaiListAdapter.FeizaiViewHolder> {
private final LayoutInflater mInflater;
private List<Feizai> mFeizais;
public FeizaiListAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
@NonNull
@Override
public FeizaiViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(R.layout.feizai_item, parent, false);
return new FeizaiViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull FeizaiViewHolder holder, int position) {
if (mFeizais != null) {
Feizai current = mFeizais.get(position);
holder.itemFirst.setText(current.getFirstName());
holder.itemSecond.setText(current.getSecondName());
} else {
holder.itemFirst.setText("没有查到肥仔");
holder.itemSecond.setText("没有查到肥仔");
}
}
@Override
public int getItemCount() {
if (mFeizais == null)
return 0;
return mFeizais.size();
}
public void setFeizai(List<Feizai> feizais) {
mFeizais = feizais;
notifyDataSetChanged();
}
class FeizaiViewHolder extends RecyclerView.ViewHolder {
private final TextView itemFirst;
private final TextView itemSecond;
private FeizaiViewHolder(View itemView) {
super(itemView);
itemFirst = itemView.findViewById(R.id.item_first);
itemSecond = itemView.findViewById(R.id.item_second);
}
}
}
10. FeizaiActivity类
public class FeizaiActivity extends AppCompatActivity {
private FeizaiViewModel mFeizaiViewModel;
private FeizaiListAdapter adapter;
RecyclerView rv;
EditText firstName, secondName;
Button add, delete, insert, update;
Feizai feizai;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_feizai);
initView();
feizai = new Feizai();
mFeizaiViewModel = new ViewModelProvider(this).get(FeizaiViewModel.class);
mFeizaiViewModel.getmAllFeizais().observe(this, feizais -> adapter.setFeizai(feizais));
}
private void initView() {
add = findViewById(R.id.btn_add);
insert = findViewById(R.id.insert);
delete = findViewById(R.id.delete);
update = findViewById(R.id.btn_update);
rv = findViewById(R.id.rc_feizai);
firstName = findViewById(R.id.first_name);
secondName = findViewById(R.id.second_name);
adapter = new FeizaiListAdapter(this);
rv.setAdapter(adapter);
rv.setLayoutManager(new LinearLayoutManager(this));
add.setOnClickListener(v -> {
if (TextUtils.isEmpty(firstName.getText().toString()) && TextUtils.isEmpty(secondName.getText().toString())) {
return;
}
feizai.setFirstName(firstName.getText().toString());
feizai.setSecondName(secondName.getText().toString());
mFeizaiViewModel.insert(feizai);
});
delete.setOnClickListener(v -> {
if (TextUtils.isEmpty(firstName.getText().toString())) {
return;
}
feizai.setFirstName(firstName.getText().toString());
feizai.setSecondName(secondName.getText().toString());
mFeizaiViewModel.delete(feizai);
});
update.setOnClickListener(v -> {
if (TextUtils.isEmpty(firstName.getText().toString())) {
return;
}
feizai.setFirstName(firstName.getText().toString());
feizai.setSecondName(secondName.getText().toString());
mFeizaiViewModel.update(feizai);
});
}
}
11. 效果图
PS:如果有初学者感到什么疑惑,可以去官网查看相关的详细资料。