Android Studio - Room Persistence Library - Обеспечение того, что первичный ключ, который вводит пользователь, уникален перед вставкой в ​​базу данных - PullRequest
0 голосов
/ 14 декабря 2018

Я учусь использовать Библиотеку комнат в Android Studio, которая в основном представляет собой слой абстракции поверх SQLite, который облегчает создание баз данных.

В моем примере приложения я разрешаюПользователь вводит основную информацию об ученике:

enter image description here

Я создал следующие три необходимых компонента для базы данных:

1.Сущность (студент)

package com.aleks.firstdatabaseproject;

import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;

/* This is one entity that will be stored in our database. A Student has a
 * unique ID, a first name, and a last name.
 */

@Entity
public class Student {

    @PrimaryKey(autoGenerate = true)
    private int id;

    @ColumnInfo(name = "first_name")
    private String firstName;

    @ColumnInfo(name = "last_name")
    private String lastName;

    @ColumnInfo(name = "email")
    private String email;

    @ColumnInfo(name="notes")
    private String notes;

    public Student() { this("", "", "", ""); }

    public Student(String firstName, String lastName, String email, String notes) {
        setFirstName(firstName);
        setLastName(lastName);
        setEmail(email);
        setNotes(notes);
    }

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

    public void setFirstName(String firstName) { this.firstName = firstName; }

    public void setLastName(String lastName) { this.lastName = lastName; }

    public int getId() { return this.id; }

    public String getFirstName() { return this.firstName; }

    public String getLastName() { return this.lastName; }

    public String getNotes() { return notes; }

    public void setNotes(String notes) { this.notes = notes; }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

2.API доступа к данным

package com.aleks.firstdatabaseproject;

import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Delete;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.Query;

import com.aleks.firstdatabaseproject.Student;

import java.util.List;

/* A Data Access Object (DAO) provides an abstracted interface that allows
 * a user program to request information from the database. The DAO provides
 * methods for insertion, deletion, and querying in the database.
 */

@Dao
public interface StudentDAO {

    @Insert
    void addStudent(Student student);

    @Delete
    void removeStudent(Student student);

    @Query("SELECT * FROM Student")
    List<Student> getAllStudents();

    @Query("SELECT * FROM Student WHERE id IS :studentID")
    Student findStudentByID(int studentID);

    @Query("SELECT * FROM Student WHERE first_name LIKE :first AND last_name LIKE :last")
    List<Student> findStudentByName(String first, String last);
}

3.База данных

package com.aleks.firstdatabaseproject;

import android.arch.persistence.room.Database;
import android.arch.persistence.room.RoomDatabase;

import com.aleks.firstdatabaseproject.Student;
import com.aleks.firstdatabaseproject.StudentDAO;

@Database(entities = {Student.class}, version = 1)
public abstract class StudentDatabase extends RoomDatabase {

    /* Used by apps to get the data access object from the database */
    public abstract StudentDAO studentDAO();
}

Для справки вот основная деятельность:

Основная деятельность

package com.aleks.firstdatabaseproject;

import android.arch.persistence.room.Room;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import org.w3c.dom.Text;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static StudentDatabase mDatabase;
    private StudentDAO mStudentDAO;
    private TextView mFirstName;
    private TextView mLastName;
    private TextView mId;
    private TextView mEmail;
    private TextView mNotes;

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

        mDatabase = Room.databaseBuilder(getApplicationContext(),
                StudentDatabase.class, "database-name").build();
        mStudentDAO = mDatabase.studentDAO();

        mFirstName = (TextView) findViewById(R.id.editText_firstName);
        mLastName = (TextView) findViewById(R.id.editText_lastName);
        mId = (TextView) findViewById(R.id.editText_id);
        mEmail = (TextView) findViewById(R.id.editText_email);
        mNotes = (TextView) findViewById(R.id.editText_notes);
    }

    /* Uses the information in the app's main fields to build and
     * return a new Student object for use by other methods.
     */
    public Student buildStudentFromFields() {
        String firstName = mFirstName.getText().toString();
        String lastName = mLastName.getText().toString();
        String email = mEmail.getText().toString();
        String notes = mNotes.getText().toString();
        return new Student(firstName, lastName, email, notes);
    }

    /* Called when the user clicks the "ADD" button. Inserts
     * the given Student into the database.
     */
    public void addStudent(View view) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                mStudentDAO.addStudent(buildStudentFromFields());
            }
        }).start();
    }

    /* Called when the user clicks the "REMOVE" button. Removes
     * the given Student from the database.
     */
    public void removeStudent(View view) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                mStudentDAO.removeStudent(buildStudentFromFields());
            }
        }).start();
    }

    /* Called when the user clicks the "FIND" button. Returns
     * information about the given Student from the database.
     */
    public void findStudent(View view) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Student student = mStudentDAO.findStudentByID(Integer.parseInt(mId.getText().toString()));
            }
        }).start();
    }
}

Что я хочу сделать

В классе сущностей вы заметите, что я включил аннотацию @PrimaryKey(autogenerate = true).Это определяет поле id в качестве первичного ключа таблицы Student, а опция autogenerate заставляет базу данных генерировать свои собственные первичные ключи вместо того, чтобы пользователь сознательно не забывал передавать уникальный ключ.Но пользователи подвержены ошибкам, и они могут случайно нажать кнопку ADD, например, дважды.

Вот проблема: я хочу разрешить пользователю передавать свой собственный идентификатор студента, как япоказано на скриншоте, но это создает проблему, если пользователь пытается (незаконно) дважды ввести один и тот же идентификатор студента - в этом случае происходит сбой приложения.

Одним из возможных решений является сохранение таблицы set / hashвсе идентификаторы, которые пользователь ввел до сих пор, и убедитесь, что введенные данные являются уникальными, прежде чем пытаться ADD Студента в базу данных.Но это просто занимает больше памяти, чем кажется необходимым (не так уж много для такого маленького приложения, но не представляется разумным хранить эту дополнительную «ненужную» информацию).

Есть ли способЯ могу учесть дубликаты первичных ключей, чтобы предотвратить сбой приложения при случайном вводе пользователем одного и того же идентификатора ученика?

1 Ответ

0 голосов
/ 14 декабря 2018

Вы можете попытаться определить OnConflictStrategy в вашем методе Insert для обработки ошибки, проверьте эту ссылку

...