首页 > 解决方案 > 将光标中的值保存到变量中

问题描述

我有一个 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。

标签: javaandroid-studioandroid-sqlite

解决方案


如果用户/密码组合不存在,我建议返回一个 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

推荐阅读