前面兩篇已經把用戶表和羣組表創建完成,由於一個羣組包含多個用戶,一個用戶擁有多個羣組,所以他們是多對多的關係。ROOM數據庫除了支持多對多的關係,還支持一對多,一對一的關係。可以使用Relation關鍵字處理。
- 注意:一對一的關係是2.2.0版本開始支持,之前的版本不支持,另外文檔沒有寫這回事,只有版本更新裏面提到過這個事情。
由於羣組和用戶的多對多關係,所以需要創建中間表用來保存他們的關係,中間表結構如下:
中間關係表
package com.room.test.model;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.room.Index;
/**
* 多對多關係中,需要使用索引,爲了避免警告,同時也是爲了提高查詢效率
*/
@Entity(tableName = "team_user_join",
primaryKeys = { "teamId","userId"},
foreignKeys = {@ForeignKey(entity = TeamModel.class,
parentColumns = "teamId",
childColumns = "teamId"),
@ForeignKey(entity = UserModel.class,
parentColumns = "userId",
childColumns = "userId")
},indices = {@Index(value = "teamId",unique = true),@Index(value = "userId",unique = true)})
public class TeamUserJoinModel {
@ColumnInfo(name = "teamId")
@NonNull
private String teamId;
@ColumnInfo(name = "userId")
@NonNull
private String userId = "";
@NonNull
public String getTeamId() {
return teamId;
}
public void setTeamId(@NonNull String teamId) {
this.teamId = teamId;
}
@NonNull
public String getUserId() {
return userId;
}
public void setUserId(@NonNull String userId) {
this.userId = userId;
}
}
數據操作接口(DAO類)
package com.room.test.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.RoomWarnings;
import com.room.test.model.TeamModel;
import com.room.test.model.UserModel;
import com.room.test.model.TeamUserJoinModel;
import java.util.List;
@Dao
public interface TeamUserJoinDao {
/**
* 多對多的關係查詢中,如果返回所有數據時候,會返回額外的字段(作爲條件查詢的字段),這時候會出現警告,解決警告的方式有兩種
* 1、返回確定的字段
* 2、採用註解,本例使用的該方式
* 如果不是多對多的關係,那麼可能是映射的字段寫錯了。
*/
@SuppressWarnings(RoomWarnings.CURSOR_MISMATCH)
@Query("SELECT * FROM user_table INNER JOIN team_user_join ON team_user_join.userId = user_table.userId WHERE team_user_join.teamId = :teamId")
LiveData<List<UserModel>> getAlphabetizedUser(String teamId);
@Insert(onConflict = OnConflictStrategy.IGNORE)
void insert(TeamUserJoinModel word);
@Insert
void insert(List<TeamUserJoinModel> playlistSongJoinList);
@SuppressWarnings(RoomWarnings.CURSOR_MISMATCH)
@Query("SELECT * FROM team_table " +
"INNER JOIN team_user_join " +
"ON team_table.teamId = team_user_join.teamId " +
"WHERE team_user_join.userId = :userId")
LiveData<List<TeamModel>> getTeamForUser(String userId);
}
數據庫
package com.room.test.db;
import android.content.Context;
import android.text.TextUtils;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import com.room.test.dao.TeamUserJoinDao;
import com.room.test.dao.UserDao;
import com.room.test.dao.TeamDao;
import com.room.test.model.UserModel;
import com.room.test.model.TeamModel;
import com.room.test.model.TeamUserJoinModel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Database(entities = {
TeamUserJoinModel.class,
UserModel.class,
TeamModel.class},
version = 1, exportSchema = false)
public abstract class UserDatabase extends RoomDatabase {
public abstract TeamDao userDao();
public abstract UserDao cardDao();
public abstract TeamUserJoinDao userCardJoinDao();
private static volatile UserDatabase INSTANCE;
private static final int NUMBER_OF_THREADS = 4;
public static final ExecutorService databaseWriteExecutor =
Executors.newFixedThreadPool(NUMBER_OF_THREADS);
public static UserDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (UserDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
UserDatabase.class, "user_database")//數據庫名
.build();
}
}
}
return INSTANCE;
}
}
中心倉庫
package com.room.test.repository;
import android.app.Application;
import androidx.lifecycle.LiveData;
import com.room.test.dao.TeamUserJoinDao;
import com.room.test.db.UserDatabase;
import com.room.test.model.TeamUserJoinModel;
import com.room.test.model.UserModel;
import java.util.List;
public class TeamCardRepository {
private TeamUserJoinDao uCardDao;
private LiveData<List<UserModel>> mAllUser;
public TeamCardRepository(Application application) {
UserDatabase db = UserDatabase.getDatabase(application);
uCardDao = db.userCardJoinDao();
}
public LiveData<List<UserModel>> getUserForTeam(String teamId) {
return uCardDao.getAlphabetizedUser(teamId);
}
public void insert(final TeamUserJoinModel user) {
UserDatabase.databaseWriteExecutor.execute(new Runnable() {
@Override
public void run() {
uCardDao.insert(user);
}
});
}
}
數據處理中心
package com.room.test.viewmodel;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import com.room.test.model.TeamUserJoinModel;
import com.room.test.model.UserModel;
import com.room.test.repository.TeamCardRepository;
import java.util.List;
public class TeamCardViewModel extends AndroidViewModel{
private TeamCardRepository mRepository;
public TeamCardViewModel(@NonNull Application application) {
super(application);
mRepository = new TeamCardRepository(application);
}
public LiveData<List<UserModel>> getUserForTeam(String teamId) {
return mRepository.getUserForTeam(teamId);
}
public void insert(TeamUserJoinModel user) { mRepository.insert(user); }
}
ROOM版本更新記錄: https://developer.android.com/jetpack/androidx/releases/room