前面两篇已经把用户表和群组表创建完成,由于一个群组包含多个用户,一个用户拥有多个群组,所以他们是多对多的关系。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