Room数据库按用户名删除用户失败问题求助
问题:Room按用户名删除用户失败
使用Room持久化库开发用户与库存管理应用,已实现用户数据查询并展示到RecyclerView,但按用户名删除用户时,能检测到目标用户存在,却无法完成删除操作。
删除用户相关代码
String usrNam = edtTxtUsrNam2.getText().toString(); // Get all users from database + log List<Users> users = LoginMenu.mainDatabase.dao().getUsers(); Log.d(LoginMenu.TAG, "Searching for " + usrNam); boolean userFound = false; // Check for User from text entry for (Users usr : users) { // User is successfully found if (usr.getName().equals(usrNam)) { userFound = true; break; } } if (!userFound) { Toast.makeText(getBaseContext(), "User not found", Toast.LENGTH_SHORT).show(); Log.d(LoginMenu.TAG, " User " + usrNam + " Not found"); edtTxtUsrNam2.getText().clear(); } else { // Build Messagebox Confirmation builder.setTitle("User " + usrNam + " found!"); builder.setMessage("Confirm user deletion?"); // Selecting yes in Alert builder.setPositiveButton("Yes", (dialogInterface, i) -> { // Delete User from database Users activeUser = new Users(); activeUser.setName(usrNam); LoginMenu.mainDatabase.dao().delUser(activeUser); // Toast message + Log Toast.makeText(getApplicationContext(),"User " + usrNam + " successfully deleted!",Toast.LENGTH_SHORT).show(); Log.d(LoginMenu.TAG,"User " + usrNam + " Successfully deleted"); edtTxtUsrNam2.getText().clear(); dialogInterface.dismiss(); }); // Selecting no in Alert builder.setNegativeButton("No", (dialogInterface, i) -> dialogInterface.dismiss()); // Create Alert Dialog AlertDialog alert = builder.create(); alert.show(); }
DAO代码
@androidx.room.Dao public interface Dao { // Add Users to Database @Insert void AddUsers(Users usr); // Request all users from DB @Query("SELECT * FROM Users") List<Users> getUsers(); // Delete user from DB @Delete void delUser (Users usr); }
User实体类代码
@Entity(tableName = "Users") public class Users { // Set User Entries for Database @ColumnInfo (name = "ID") @PrimaryKey (autoGenerate = true) private int id; @ColumnInfo(name = "EmployeeId") private String employeeId; @ColumnInfo(name = "Name") private String name; @ColumnInfo(name = "Password") private String password; @ColumnInfo(name = "DateOfBirth") private String dateOfBirth; @ColumnInfo(name = "ContactNumber") private String contactNumber; @ColumnInfo(name = "Address") private String address; // 需补充所有字段的getter/setter方法,Room依赖这些方法访问字段 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } // 其他字段的getter/setter省略,需自行补充 }
问题原因及解决方案
核心原因
Room的@Delete注解默认通过实体的主键匹配数据库记录。你新建的activeUser仅设置了name,未设置主键id,Room无法找到对应主键的记录,因此删除操作无效。
方案一:使用完整用户对象删除
遍历用户列表时,保存找到的完整Users对象,删除时传入该真实对象:
// 修改遍历逻辑,保存目标用户对象 Users targetUser = null; for (Users usr : users) { if (usr.getName().equals(usrNam)) { userFound = true; targetUser = usr; // 保存完整的用户对象 break; } } // 在确认删除的回调中使用targetUser builder.setPositiveButton("Yes", (dialogInterface, i) -> { if (targetUser != null) { LoginMenu.mainDatabase.dao().delUser(targetUser); // 后续提示、日志操作不变 } });
方案二:自定义@Query删除语句(更高效)
直接在DAO中添加按用户名删除的方法,无需查询所有用户:
@Dao public interface Dao { // 保留原有方法,新增按用户名删除的方法 @Query("DELETE FROM Users WHERE Name = :userName") void deleteUserByName(String userName); }
删除回调中直接调用该方法:
builder.setPositiveButton("Yes", (dialogInterface, i) -> { LoginMenu.mainDatabase.dao().deleteUserByName(usrNam); // 后续提示、日志操作不变 });
此方案无需查询全表,直接执行删除SQL,性能更优。
额外注意
确保Users实体类包含所有字段的getter和setter方法,Room需要通过这些方法访问实体字段,否则可能出现数据匹配异常。
内容的提问来源于stack exchange,提问作者Ethan Cunningham
相关产品推荐
相关产品推荐

