java - 将光标中的值保存到变量中
问题描述
我有一个 android studio 应用程序,它使用 sqlite 来保存用户数据,例如用户名、密码等。在用户输入登录凭据后的登录页面中,用户单击一个按钮,该按钮从DatabaseHelper java 类调用以下函数来检查信息是否正确:
public boolean checkLogin(String username, String password){
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM user WHERE username=? AND password=? ",
new String[] {username, password});
if (cursor.getCount() > 0){
return true;
}
else {
return false;
}
}
我想保存与该用户匹配的行 ID,以便将来可以使用它,并且我正在考虑将 ID 保存到一个变量中,然后我将使用意图发送到不同的活动。问题是我不知道如何从查询中保存 ID。
解决方案
如果用户/密码组合不存在,我建议返回一个 int 而不是 boolean 长的 id 或 -1 。所以 :-
public int checkLogin(String username, String password){
int rv = -1;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM user WHERE username=? AND password=? ",
new String[] {username, password});
if (cursor.moveToFirst()) {
rv = cursor.getInt(cursor.getColumnIndex("id"));
}
cursor.close();
return rv;
}
而不是使用类似的东西: -
if (checkLogin("the_user","the_password")) {
logged in code ....
} else {
not logged in code ....
}
你可以使用类似的东西: -
private int current_userid = -1; // probably declared as a class variable
....
if ((current_userid = db.checkLogin("the_user","the_password")) > 0 ) {
logged in OK code ....
} else {
not logged in code ....
}
我想保存与该用户匹配的行 ID,以便将来可以使用它,并且我正在考虑将 ID 保存到一个变量中,然后我将使用意图发送到不同的活动。
这是一个执行此操作并将 id 发送到另一个活动 (NextActivity) 的示例,然后在将用户名和密码写入日志后从该活动返回(完成)。
首先是数据库助手DBHelper:-
class DBHelper extends SQLiteOpenHelper {
SQLiteDatabase db;
public DBHelper(@Nullable Context context) {
super(context, "mydb", null, 1);
db = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS user (" +
"id INTEGER PRIMARY KEY, " +
"username TEXT UNIQUE, " +
"password TEXT " +
")");
ContentValues cv = new ContentValues();
cv.put("username","fred");
cv.put("password","password_for_fred");
db.insert("user",null,cv);
}
@Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) { }
public int checkLogin(String username, String password){
int rv = -1;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM user WHERE username=? AND password=? ",
new String[] {username, password});
if (cursor.moveToFirst()) {
rv = cursor.getInt(cursor.getColumnIndex("id"));
}
cursor.close();
return rv;
}
public Cursor getUserById(int userId) {
return db.query("user",null,"id=?",new String[]{String.valueOf(userId)},null,null,null);
}
}
- 请注意,这对 SQLiteDatabase 使用单个类变量,因此只需要 1 个 getWriteableDatabase。它还通过包含
db = this.getWriteableDatabase();
在构造函数中来强制数据库在构造时打开。 - 注意添加的方法
getUserById(ing userId)
method,它根据userId返回一个Cursor。 - 请注意,在创建表时会将演示用户添加到表中。
MainActivity(有点过于复杂,因为它展示了失败的登录尝试(第一次)以及成功的登录尝试(作为处理失败尝试的一部分)):-
public class MainActivity extends AppCompatActivity {
public static final String INTENT_EXTRA_CURRENT_USERID = "current_userid";
DBHelper db;
private int current_userid = -1;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new DBHelper(this);
Log.d("LOGIN1","Attempting to Login"); // Will purposefully fail login
if ((current_userid = db.checkLogin("the_user","the_password")) > 0 ) {
Log.d("LOGIN2","Successfully Logged in to user with ID = " + String.valueOf(current_userid));
gotoNextActivity();
} else {
Toast.makeText(this,"Invalid Login, please try again",Toast.LENGTH_SHORT).show();
Log.d("LOGIN1","First attempt to login failed");
// Make 2nd attempt (will work as username and password are correct)
Log.d("LOGIN2","Attemtping to Login (2nd) ");
if((current_userid = db.checkLogin("fred","password_for_fred")) > 0 ) {
Log.d("LOGIN2","Successfully Logged in to user with ID = " + String.valueOf(current_userid));
gotoNextActivity();
}
}
}
private void gotoNextActivity() {
intent = new Intent(this,NextActivity.class);
intent.putExtra(INTENT_EXTRA_CURRENT_USERID,current_userid);
startActivity(intent);
}
}
最后下一个活动:-
public class NextActivity extends AppCompatActivity {
private int current_userid;
private String current_username, current_password;
private DBHelper db;
Cursor csr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_next);
db = new DBHelper(this);
current_userid = this.getIntent().getIntExtra(MainActivity.INTENT_EXTRA_CURRENT_USERID,-1);
csr = db.getUserById(current_userid);
if (csr.moveToFirst()) {
current_username = csr.getString(csr.getColumnIndex("username"));
current_password = csr.getString(csr.getColumnIndex("password"));
}
if (current_userid > 0) {
Log.d("NEXTACTIVTY","Valid user ID - Username = " + current_username + " password is " + current_password);
} else {
Log.d("NEXTACTIVITY","No Valid userid?");
}
// Finish the Activity and hence return to MainActivity
// Hence it is unlikely that the NextActivity will even be noticed.
finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (!csr.isClosed()) {
csr.close();
Log.d("NEXTACTIVITY","Closing Cursor in onDestroy method");
}
}
}
结果
运行日志包括:-
2021-07-17 12:19:37.201 D/LOGIN1: Attempting to Login
2021-07-17 12:19:37.211 D/LOGIN1: First attempt to login failed
2021-07-17 12:19:37.211 D/LOGIN2: Attemtping to Login (2nd)
2021-07-17 12:19:37.212 D/LOGIN2: Successfully Logged in to user with ID = 1
2021-07-17 12:19:37.392 D/NEXTACTIVTY: Valid user ID - Username = fred password is password_for_fred
2021-07-17 12:19:37.745 D/NEXTACTIVITY: Closing Cursor in onDestroy method
推荐阅读
- java - 不间断运行的线程
- postgresql - 即使在postgres中使用listen_addresses ='*',远程登录也不起作用
- gradle - 将 gradle 从 4.4 更新到 5.4 导致 joda-time 依赖问题
- c# - 将 FTP 上的本地和远程文件与 WinSCP lib 进行比较
- python - 有没有办法在 python 网络应用程序中使用预训练的 R ML 模型?
- python - 为什么名字和姓氏字段没有输入数据库,而只是我创建的 customUser 中的电子邮件和密码?
- sql - 对列的前一个值求和的新列
- python - 不在python中导入形状
- office-ui-fabric - DetailsList 是否公开回调以向列表中添加更多项目(分页)
- call - 如何处理 IncallService 中的呼叫等待