如何通过SQLite Cursor同时展示用户名与COLUMN_TIMER_RESULT_FOR_4字段
问题描述
我现在对SQLite Cursor的使用有困惑,之前用RecyclerView实现功能,现在换成Cursor方式后无法展示目标字段,不知道该加什么内容。
我的数据库里有table_user和table_timer两张表:
table_user包含COLUMN_USERNAME字段table_timer包含COLUMN_TIMER_RESULT_FOR_4字段
我想同时调用这两个字段,该怎么操作?
附上相关代码片段:
Leaderboard代码
private void populateUsernamesList(){ // Create a list of strings List<String> userStrings = new ArrayList<String>(0); usernames = userList.getAllUsers(); // Enters all the usernames to the array for(int i = 0; i<usernames.size(); i++){ userStrings.add(usernames.get(i).toString()); } // Enters them to array adapter ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, R.layout.listview_element, userStrings); usernamesListView.setAdapter(arrayAdapter); }
UserList代码
public UserList(Context c) { userList = new ArrayList<User>(0); userDataSource = new UserDAO(c); userDataSource.open(); } //Methods fot userList interact with the userDAo to get, create, check, delete and return All users public User getUser(int userID){ return userDataSource.getUserById(userID); } public boolean createUser(User u){ return userDataSource.createUser(u); } public boolean checkUsername(String u){ return userDataSource.checkUsername(u); } public Boolean deleteUser(User u){ return userDataSource.deleteUser(u); } public Boolean deleteResults(User u){ return userDataSource.deleteResults(u); } public List<User> getAllUsers(){ userList = userDataSource.getAllUsers(); return userList; }
User代码
public User(int usernameId, String username, Integer level4) { this.usernameId = usernameId; this.username = username; //this.level4 = level4; } //toString method for printing the contents of a class object @Override public String toString() { return username ; } // //public int getLevel4() {return level4 ;} // Getters and setters public int getUsernameId() { return usernameId; } public void setUsernameId(int usernameId) { this.usernameId = usernameId; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; }
UserDAO代码
public List<User> getAllUsers() { List<User> userList = new ArrayList<User>(0); // Get data from the db Cursor cursor = database.query(TABLE_USERS, allColumns, null, null, null, null, null); cursor.moveToFirst(); // Loop through the cursor(result set) and create new usernames objects while (!cursor.isAfterLast()) { User user = cursorToUser(cursor); userList.add(user); cursor.moveToNext(); } return userList; }
解决方案
要同时获取两个表的字段,需要做表关联查询,同时修改数据模型和DAO层逻辑,步骤如下:
1. 完善User数据模型
把注释掉的level4字段恢复,补充完整构造方法、getter/setter和toString方法,让它能承载两个表的数据:
public User(int usernameId, String username, Integer level4) { this.usernameId = usernameId; this.username = username; this.level4 = level4; // 取消注释 } //toString方法,同时返回用户名和level4结果 @Override public String toString() { return username + " - 关卡4成绩: " + level4; } // 恢复getter方法 public int getLevel4() { return level4; } // 添加setter方法 public void setLevel4(int level4) { this.level4 = level4; } // 保留原有getter/setter public int getUsernameId() { return usernameId; } public void setUsernameId(int usernameId) { this.usernameId = usernameId; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } // 新增成员变量 private int level4;
2. 修改UserDAO的关联查询逻辑
首先确认table_timer表存在关联table_user的外键(比如user_id字段,关联table_user的主键usernameId),然后修改getAllUsers方法,执行JOIN查询,同时获取两个表的目标字段:
public List<User> getAllUsers() { List<User> userList = new ArrayList<User>(0); // 构造关联查询SQL:JOIN两个表,通过user_id关联 String sql = "SELECT u." + COLUMN_USER_ID + ", u." + COLUMN_USERNAME + ", t." + COLUMN_TIMER_RESULT_FOR_4 + " FROM " + TABLE_USERS + " u " + " LEFT JOIN " + TABLE_TIMER + " t " + " ON u." + COLUMN_USER_ID + " = t.user_id"; // 这里的user_id是table_timer里关联用户的外键,根据实际字段名调整 Cursor cursor = database.rawQuery(sql, null); cursor.moveToFirst(); while (!cursor.isAfterLast()) { User user = cursorToUser(cursor); userList.add(user); cursor.moveToNext(); } cursor.close(); // 记得关闭Cursor避免内存泄漏 return userList; } // 修改cursorToUser方法,读取level4字段 private User cursorToUser(Cursor cursor) { int userId = cursor.getInt(cursor.getColumnIndex(COLUMN_USER_ID)); String username = cursor.getString(cursor.getColumnIndex(COLUMN_USERNAME)); // 读取table_timer的字段,处理null情况(如果用户没有关卡4成绩) int level4 = cursor.isNull(cursor.getColumnIndex(COLUMN_TIMER_RESULT_FOR_4)) ? 0 : cursor.getInt(cursor.getColumnIndex(COLUMN_TIMER_RESULT_FOR_4)); return new User(userId, username, level4); }
3. 调整UI展示
你的populateUsernamesList方法不需要大改,因为User的toString已经包含了用户名和关卡4成绩,ArrayAdapter会直接显示组合后的内容。如果想要更美观的布局,可以自定义Adapter,在listview_element布局里添加两个TextView分别展示用户名和成绩,然后在Adapter里绑定数据。
内容的提问来源于stack exchange,提问作者Fatkul
相关产品推荐
相关产品推荐

