如何将SQLiteOpenHelper类与MainActivity连接?

时间:2018-10-05 21:01:17

标签: java android database sqlite

我创建了3个类(1. MainActivity,DBhelper和Student类)。我是新手,他们使用简单的代码,而且始终无法将DBhelper类与MainActivity连接起来。我认为一切正常,但是在单击“ buttonAdd”后,我得到一条声明,“我的应用已停止”。 在MainActivity中,我仅使用了DBhelper的“ loadStudents”和“ addStudent”方法,因为即使在那些基本级别上我也遇到了问题。

应用程序的构想->将新的学生添加到editText,将其删除等。我知道,更好的方法是使用scrollList,但我只想知道如何首先使用SQLite。

学生类->我在“ DBhelper类”和“ MainActivity”中使用它

public class Student {

private int studentID;
private String studentName;

public Student(int id, String studentName) { //konstruktor
    this.studentID = id;
    this.studentName = studentName;
}

public int getStudentID() {
    return studentID;
}

public void setStudentID(int studentID) {
    this.studentID = studentID;
}

public String getStudentName() {
    return studentName;
}

public void setStudentName(String studentName) {
    this.studentName = studentName;
}
}

DBhelper类

public class DBhelper extends SQLiteOpenHelper {

private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "studentDB.db";
public static final String TABLE_NAME = "student";
public static final String COLUMN_ID = "studentID";
public static final String COLUMN_NAME = "studentName";
//initialize the database

public DBhelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}


@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE " + TABLE_NAME + "("
            + COLUMN_ID + "INTEGER PRIMARYKEY,"
            + COLUMN_NAME + " TEXT " + ")");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS contacts");
    onCreate(db);
}

public void addStudent(Student student) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(COLUMN_ID, student.getStudentID());
    values.put(COLUMN_NAME, student.getStudentName());
    db.insert(TABLE_NAME, null, values);
    db.close();
}

public String loadStudents() {
    String result = "";
    String query = "Select*FROM " + TABLE_NAME;
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(query, null);
    while (cursor.moveToNext()) {
        int result_0 = cursor.getInt(0);
        String result_1 = cursor.getString(1);
        result += String.valueOf(result_0) + " " + result_1 +
                System.getProperty("line.separator");
    }
    cursor.close();
    db.close();
    return result;
}

public Student findStudent(int ID, String studentName) {
    String query = "Select * FROM " + TABLE_NAME + "WHERE" + COLUMN_NAME + " 
= " + "'" + studentName + "'";
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(query, null);
    Student student = new Student(ID, studentName);
    if (cursor.moveToFirst()) {
        cursor.moveToFirst();
        student.setStudentID(Integer.parseInt(cursor.getString(0)));
        student.setStudentName(cursor.getString(1));
        cursor.close();
    } else {
        student = null;
    }
    db.close();
    return student;
}

public boolean deleteStudent(int ID, String studentName) {
    boolean result = false;
    String query = "Select*FROM" + TABLE_NAME + "WHERE" + COLUMN_ID + "= '" 
+ String.valueOf(ID) + "'";
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(query, null);
    Student student = new Student(ID, studentName);
    if (cursor.moveToFirst()) {
        student.setStudentID(Integer.parseInt(cursor.getString(0)));
        db.delete(TABLE_NAME, COLUMN_ID + "=?",
                new String[] {
            String.valueOf(student.getStudentID())
        });
        cursor.close();
        result = true;
    }
    db.close();
    return result;
}

public boolean updateStudent(int ID, String name) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues args = new ContentValues();
    args.put(COLUMN_ID, ID);
    args.put(COLUMN_NAME, name);
    return db.update(TABLE_NAME, args, COLUMN_ID + "=" + ID, null) > 0;
}
}

MainActivity

public class MainActivity extends AppCompatActivity {

Button buttonLoad;
Button buttonAdd;
Button buttonFind;
Button buttonDelete;
Button buttonUpdate;
TextView textViewStudents;
EditText editTextID;
EditText editTextName;
DBhelper myDB;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    buttonLoad = (Button) findViewById(R.id.buttonLoad);
    buttonAdd = (Button) findViewById(R.id.buttonAdd);
    buttonFind = (Button) findViewById(R.id.buttonFind);
    buttonDelete = (Button) findViewById(R.id.buttonDelete);
    buttonUpdate = (Button) findViewById(R.id.buttonUpdate);
    textViewStudents = (TextView) findViewById(R.id.textViewStudents);
    editTextID = (EditText) findViewById(R.id.editTextID);
    editTextName = (EditText) findViewById(R.id.editTextName);
    myDB = new DBhelper(this);

    //load
    buttonLoad.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            textViewStudents.setText(myDB.loadStudents());
            editTextID.setText("");
            editTextName.setText("");
        }
    });

    buttonAdd.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int id = Integer.parseInt(editTextID.getText().toString());
            String name = editTextName.getText().toString();
            Student student = new Student(id, name);
            myDB.addStudent(student);
            editTextID.setText("");
            editTextName.setText("");
        }
    });
}
// Maybe it will be better to use the methos under the onCreate method but I 
//don't know what should I write as a paramether instead of "view" when I 
//will use this method in the onCreate
//    public void addStudent() {
//        DBhelper myDB = new DBhelper(this);
//        int id = Integer.parseInt(editTextID.getText().toString());
//        String name = editTextName.getText().toString();
//        Student student = new Student(id, name);
//        myDB.addStudent(student);
//        editTextID.setText("");
//        editTextName.setText("");
//    }
}

1 个答案:

答案 0 :(得分:0)

loadStudents 方法中,您有String query = "Select*FROM " + TABLE_NAME; 这将导致语法错误,因为SELECT与*和*与FROM之间没有空格。

这应该是 String query = "Select * FROM " + TABLE_NAME;

由于您省略了数字,因此需要检查代码中是否缺少空格。

  • 列名和类型之间的空格,以及PRIMARY和KEY之间的空格,因此,studentID将不是 rowid 列的别名,因此将为null而不是自动生成的唯一ID。 **如果未解决此问题(不会导致错误),则会导致find / delete / update / Students方法无法正常工作。

  • WHERE 关键字之前,TABLE_NAME + "WHERE"还有一个空格。

  • 在deleteStudent方法中复制了相同的初始错误Select*FROM

  • 注意 可能还有其他语法错误,以上内容仅通过直观的代码即可发现。 < / p>

我建议进行所有修改,然后删除该应用程序的数据或卸载该应用程序或增加分配给DATABASE_VERSION的值,然后重新运行该应用程序。

您还应该在“日志停止工作”之后检查日志,该日志将详细说明遇到的错误。

其他

以下是经过测试的代码,还包含一些建议,例如仅使用学生的ID来查找学生。

DBhelper.java类(为方便起见,已使用DBhelper2类):-

public class DBhelper2 extends SQLiteOpenHelper { //<<<<<<<<<< Change DBhelper2 to DBhelper

    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "studentDB.db";
    public static final String TABLE_NAME = "student";
    public static final String COLUMN_ID = "studentID";
    public static final String COLUMN_NAME = "studentName";    //initialize the database

    public DBhelper2(Context context) { //<<<<<<<<<< Change DBhelpe2 to DBhelper
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + TABLE_NAME + "("
                + COLUMN_ID + " INTEGER PRIMARY KEY,"
                + COLUMN_NAME + " TEXT " + ")");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS contacts");
        onCreate(db);
    }

    public void addStudent(Student student) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(COLUMN_ID, student.getStudentID());
        values.put(COLUMN_NAME, student.getStudentName());
        db.insert(TABLE_NAME, null, values);
        db.close();
    }

    //<<<<<<<<<< ADDED add student allowing ID to be auto generated
    //!!!NOTE!!! ideally long should be used for ID and thus should return long not int
    //              won't be an issue with a small number of Students
    public int addNewStudent(String studentName) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(COLUMN_NAME,studentName);
        return (int) db.insert(TABLE_NAME,null,values);
    }

    public String loadStudents() {
        String result = "";
        String query = "Select * FROM " + TABLE_NAME; //<<<<<<<<<< ADDED SPACES
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(query, null);
        while (cursor.moveToNext()) {
            int result_0 = cursor.getInt(0);
            String result_1 = cursor.getString(1);
            result += String.valueOf(result_0) + " " + result_1 +
                    System.getProperty("line.separator");
        }
        cursor.close();
        db.close();
        return result;
    }

    //<<<<<<<<<< Get all Students as an ArrayList of Student objects
    //<<<<<<<<<< Alternative to loadStudents
    public ArrayList<Student> getAllStudents() {
        ArrayList<Student> result = new ArrayList<>();
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor csr = db.query(TABLE_NAME,null,null,null,null,null,null);
        while (csr.moveToNext()) {
            result.add(
                    new Student(
                            csr.getInt(csr.getColumnIndex(COLUMN_ID)),
                            csr.getString(csr.getColumnIndex(COLUMN_NAME)
                            )
                    )
            );
        }
        csr.close();
        db.close();
        return result;
    }

    public Student findStudent(int ID, String studentName) {
        String query = "Select * FROM " + TABLE_NAME + " WHERE " + COLUMN_NAME + //<<<<<<<<<< ADDED SPACES
                " = " + "'" + studentName + "'"; //<<<<<<<<<< ADDED missing double quote
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(query, null);
        Student student = new Student(ID, studentName);
        if (cursor.moveToFirst()) {
            cursor.moveToFirst(); //<<<<<<<<<< NOT NEEDED as already at first
            student.setStudentID(Integer.parseInt(cursor.getString(0)));
            student.setStudentName(cursor.getString(1));
            cursor.close();
        } else {
            student = null;
        }
        db.close();
        return student;
    }

    //<<<<<<<<<< alternative get student just by id
    //          uses the convenience query method rather than rawQuery
    //          recommended to use COLUMN NAMES not column offsets
    public Student findStudent(int studentID) {
        Student result = null;
        String whereclause = COLUMN_ID + "=?";
        String[] whereargs = new String[]{String.valueOf(studentID)};
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor csr = db.query(TABLE_NAME,null,whereclause,whereargs,null,null,null);
        if (csr.moveToFirst()) {
            result = new Student(
                    csr.getInt(csr.getColumnIndex(COLUMN_ID)),
                    csr.getString(csr.getColumnIndex(COLUMN_NAME)
                    )
            );
        }
        csr.close();
        db.close();
        return result;
    }


    //      Deleting just by id (see findStudent above) could/should be implemented
    public boolean deleteStudent(int ID, String studentName) {
        boolean result = false;
        String query = "Select * FROM " + TABLE_NAME + " WHERE " + COLUMN_ID + "= '" //<<<<<<<<<< ADDED SPACES
                + String.valueOf(ID) + "'";
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(query, null);
        Student student = new Student(ID, studentName);
        if (cursor.moveToFirst()) {
            student.setStudentID(Integer.parseInt(cursor.getString(0)));
            db.delete(TABLE_NAME, COLUMN_ID + "=?",
                    new String[] {
                            String.valueOf(student.getStudentID())
                    });
            cursor.close();
            result = true;
        }
        db.close();
        return result;
    }

    //      Updating just by id (see findStudent above) could/should be implemented
    public boolean updateStudent(int ID, String name) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues args = new ContentValues();
        args.put(COLUMN_ID, ID);
        args.put(COLUMN_NAME, name);
        return db.update(TABLE_NAME, args, COLUMN_ID + "=" + ID, null) > 0;
    }
}
  • 请参考上面代码中的注释

测试

在活动的onCreate方法中,以下代码用于测试上述内容:-

    mDBStudents = new DBhelper2(this);

    //Delete all students for testing purposes only
    mDBStudents.getWritableDatabase().delete(DBhelper2.TABLE_NAME,null,null);

    // Load some data and test methods
    mDBStudents.addStudent(new Student(1,"Fred"));
    mDBStudents.addStudent(new Student(2,"Mary"));
    Log.d("STUDENTS",mDBStudents.loadStudents());
    Student a_student_found = mDBStudents.findStudent(1,"Fred");
    Log.d("STUDENTFOUND", a_student_found.getStudentName());
    mDBStudents.updateStudent(1,"Bert");
    a_student_found = mDBStudents.findStudent(1,"Bert");
    Log.d("STUDENtFOUND",a_student_found.getStudentName());
    mDBStudents.deleteStudent(2,"Mary");
    Log.d("STUDENTS",mDBStudents.loadStudents());

    //Test alternative suggested methods
    mDBStudents.addNewStudent("Harold");
    mDBStudents.addNewStudent("Susan");
    ArrayList<Student> all_students = mDBStudents.getAllStudents();
    boolean after_first_row = false;
    StringBuilder sb = new StringBuilder("Students are :-");
    for (Student s: mDBStudents.getAllStudents()) {
        sb.append("\n\t")
                .append("Student ID is ")
                .append(String.valueOf(s.getStudentID()))
                .append(" Student name is ")
                .append(s.getStudentName());
    }
    Log.d("STUDENTS",sb.toString());
    Student another = mDBStudents.findStudent(3);
    Log.d("STUDENT 3","Student with an ID of 3 is " + another.getStudentName());

结果(在日志中)

以下是测试生成的日志的输出:-

2018-10-06 08:49:27.410 2382-2382/so52598847.so52598847 D/STUDENTS: 1 Fred
    2 Mary
2018-10-06 08:49:27.411 2382-2382/so52598847.so52598847 D/STUDENTFOUND: Fred
2018-10-06 08:49:27.418 2382-2382/so52598847.so52598847 D/STUDENtFOUND: Bert
2018-10-06 08:49:27.426 2382-2382/so52598847.so52598847 D/STUDENTS: 1 Bert
2018-10-06 08:49:27.444 2382-2382/so52598847.so52598847 D/STUDENTS: Students are :-
        Student ID is 1 Student name is Bert
        Student ID is 2 Student name is Harold
        Student ID is 3 Student name is Susan
2018-10-06 08:49:27.445 2382-2382/so52598847.so52598847 D/STUDENT 3: Student with an ID of 3 is Susan

结果符合预期。那是

  1. 弗雷德学生的ID为1
  2. 为玛丽学生添加的ID为2
  3. 列出了弗雷德和玛丽学生。
  4. 学生1(弗雷德)的名称已更新为Bert。
  5. 找到了学生1(现在是Bert)
  6. 列出了学生伯特。
  7. 学生2(玛丽)被删除。
  8. 添加了学生Harold和Susan(使用其他方法,即 addNewStudent )。
  9. 通过 getAllStudents 方法获得的所有学生都被列出。
  10. 通过替代的 findStudent 方法(仅通过id检索学生3),因此名称更改(例如Fred到Bert的姓名更改不会影响获取学生)并列出。