Android Studio - Библиотека сохраняемости комнаты - Обеспечение уникальности первичного ключа, который вводит пользователь, перед вставкой в ​​базу данных

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

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

введите здесь описание изображения

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

<сильный>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.

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

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

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


person AlexH    schedule 14.12.2018    source источник


Ответы (1)


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

person z44.nelther    schedule 14.12.2018