将游标中的值保存到变量中

Saving value from cursor into a variable

我有一个 android studio 应用程序,它使用 sqlite 保存用户数据,例如用户名、密码等。在用户输入其登录凭据后的登录页面中,用户单击一个按钮调用来自 DatabaseHelper java class 的以下函数检查信息是否正确:

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。

基本上你只需要

cursor.getInt([column position])  

cursor.getString([column position])

从数据库的列中检索数据。我举了一个例子,希望对你有帮助。有些情况我对编程语言不是很熟悉所以我不能再争论了。

public class User {
        private int id;
        private String name;
        private String password;
        private boolean  isLogged = false;

        public User() {
        }

        public void setId(int id) {
            this.id = id;
        }

        public int getId() {
            return id;
        }

        public boolean isLogged() {
            return isLogged;
        }

        public void setLogged(boolean x) {
            this.isLogged = x;
        }
    }

检索 Id 的方法要求您可以创建一个字符串或其他内容..

    public User 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.moveToFirst() || cursor.getCount() > 0) {

            User user = new User();
            user.setId(cursor.getInt(0));//if you created a primary key should be the first column
            user.setLogged(true);
            
            cursor.close();// * Closes the Cursor, releasing all of its resources and making it completely invalid.
            db.close(); // * Releases a reference to the object, closing the object if the last reference* was released.
            return user;
        } else {
            return null;
        }
    }

如果 user/password 组合不存在,我建议返回一个 int 而不是布尔值,long 是 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 ....
}

I want to save the row ID that matches this user so I can use it in the future and I was thinking of saving the ID into a variable that I will then send to different activities using an intent.

这是一个示例,它执行此操作并将 id 发送到另一个 Activity(下一个 Activity),然后 returns(完成)从 activity 写入登录的用户名和密码。

首先是数据库助手 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 使用单个 class 变量,因此只需要 1 个 getWriteableDatabase。它还通过在构造函数中包含 db = this.getWriteableDatabase(); 来强制在构造时打开数据库。
  • 注意添加的方法 getUserById(ing userId) 方法 returns 根据 userId 的 Cursor。
  • 请注意,在创建 table 时会添加一个演示用户。

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);
    }
}

终于下一个Activity:-

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