SQLite с внешним ключом + модели Android Studio CRUD - PullRequest
0 голосов
/ 31 августа 2018

Извините за мой английский

Я построю простой пример:


Таблица T_User

id_user integer primary key autoincrement,

email_user text not null,

pass_user text not null,

id_person integer foreign key(id_person) references T_Person(id_person)

Таблица T_Person

id_person integer primary key autoincrement,

name_person text not null,

cel_person text not null

Android Studio:

User.java

public static final String TAG = User.class.getSimpleName();

1) Здесь мне нужно поставить то же имя таблицы?

public static final String TABLE = "T_User"; 

2) Здесь мне нужно разместить все столбцы моей таблицы? как "id_user"

public static final int KEY_ID_USER = "id_user";
public static final String KEY_EMAIL_USER = "email_user";
public static final String KEY_PASS_USER= "pass_user";
public static final int KEY_ID_PERSON = "id_person";

private int id;
private String email;
private String pass;
private Person person;
//constructor
//getters & setters

UserRepo.java

    public static String createTable(){
        return "CREATE TABLE " + User.TABLE  + "("
                + User.KEY_ID_USER + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                + User.KEY_EMAIL_USER + " TEXT,"
                + User.KEY_PASS_USER + " TEXT,"
                + User.KEY_ID_PERSON  + " INTEGER)";
    }
    public void insert(User user) {
        SQLiteDatabase db = DatabaseManager.getInstance().openDatabase();
        ContentValues values = new ContentValues();

3) Мне не нужна эта строка, верно? (из-за автоинкремента)

        values.put(User.KEY_ID_USER, user.getId());


        values.put(User.KEY_EMAIL_USER, user.getEmail());
        values.put(User.KEY_PASS_USER, user.getPass());

4) Вот как получить идентификатор от человека?

        values.put(User.KEY_ID_PERSON , user.person.getId());


        db.insert(User.TABLE, null, values);
        DatabaseManager.getInstance().closeDatabase();
    }

5) Как я могу обновить и выбрать

1 Ответ

0 голосов
/ 02 сентября 2018

Вот рабочий пример, основанный на вашем дизайне с обновлением и выбором методов.

Он состоит из 2 классов Java и запускающего действия MainActivity.java и подкласса класса SQLiteOpenHelper, часто называемого DBHelper, следовательно, он DBHelper.java

DBHelper.java

public class DBHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;

    public static final String TB_USER = "T_User";
    public static final String TB_PERSON = "T_Person";

    public static final String COl_USER_ID = BaseColumns._ID;
    public static final String COl_USER_EMAIL = "email_user";
    public static final String COL_USER_PASS = "pass_user";
    public static final String COl_USER_PERSON = "id_person";

    public static final String COL_PERSON_ID = BaseColumns._ID;
    public static final String COl_PERSON_NAME = "name_person";
    public static final String COL_PERSON_CEL = "cel_person";

    SQLiteDatabase mDB;
    public DBHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB  = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String crtpersonsql = "CREATE TABLE IF NOT EXISTS " + TB_PERSON + "(" +
                COL_PERSON_ID + " INTEGER PRIMARY KEY, " +
                COl_PERSON_NAME + " TEXT NOT NULL," +
                COL_PERSON_CEL + " TEXT NOT NULL " +
                ")";
        String crtusersql = "CREATE TABLE If NOT EXISTS " + TB_USER + "(" +
                COl_USER_ID + " INTEGER PRIMARY KEY, " +
                COl_USER_EMAIL + " TEXT NOT NULL, " + //perhaps make unique
                COL_USER_PASS + " TEXT NOT NULL, " +
                COl_USER_PERSON + " INTEGER REFERENCES " + TB_PERSON + "(" +
                COL_PERSON_ID +
                ")" +
                ")";
        db.execSQL(crtpersonsql);
        db.execSQL(crtusersql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int i, int i1) {

    }

    public long insertPerson(String name, String cel) {
        ContentValues cv = new ContentValues();
        cv.put(COl_PERSON_NAME,name);
        cv.put(COL_PERSON_CEL,cel);
        return mDB.insert(TB_PERSON,null,cv);
    }

    public long insertUser(String email, String pass, long personid) {
        ContentValues cv = new ContentValues();
        cv.put(COl_USER_EMAIL,email);
        cv.put(COL_USER_PASS,pass);
        cv.put(COl_USER_PERSON,personid);
        return mDB.insert(TB_USER,null,cv);
    }

    public Cursor getAllPersons() {
        return mDB.query(TB_PERSON,null,null,null,null,null,null);
    }

    public Cursor getAllUsers() {
        return mDB.query(TB_USER,null,null,null,null,null,null);
    }

    public Cursor getAllPersonsAndTheReferencedUser() {
        String table = TB_PERSON +
                " JOIN " + TB_USER +
                " ON " + COl_USER_PERSON + "=" +
                TB_PERSON + "." + COL_PERSON_ID;
        String[] columns = new String[]{
                TB_PERSON + "." + COL_PERSON_ID + " AS " + TB_PERSON + "_" + COL_PERSON_ID,
                COl_PERSON_NAME,
                COL_PERSON_CEL,
                TB_USER + "." + COl_USER_ID + " AS " + TB_USER + "_" + COl_USER_ID,
                COl_USER_EMAIL,
                COL_USER_PASS
        };
        Log.d("GETALLPandU","Table (FROM) clause = " + table);
        return mDB.query(table,columns,null,null,null,null,null);
    }

    public int changePersonsName(long personid, String newname) {
        ContentValues cv = new ContentValues();
        cv.put(COl_PERSON_NAME,newname);
        String whereclause = COL_PERSON_ID + "=?";
        String[] whereargs = new String[]{String.valueOf(personid)};
        return mDB.update(TB_PERSON,cv,whereclause,whereargs);
    }

    public int changePersonsCel(long personid, String newcel) {
        ContentValues cv = new ContentValues();
        cv.put(COL_PERSON_CEL,newcel);
        String whereclause = COL_PERSON_ID + "=?";
        String[] whereargs = new String[]{String.valueOf(personid)};
        return mDB.update(TB_PERSON,cv,whereclause,whereargs);
    }
}
  • Метод insertPerson используется для добавления строки в таблицу T_Person .
  • Метод insertUser используется для добавления строки в таблицу T_User , отмечая, что personid (третий параметр) должен ссылаться на Person.
  • Метод getAllPersons получает все строки из таблицы T_Person .
  • Метод getAllUsers получает все строки из таблицы T_User .
  • Метод getAllPersonsAndTheReferencedUser получает все строки в соответствии с внешними ключами / ссылками из таблиц Person и User.
  • Метод changePersonsName позволяет обновлять имя человека в соответствии с id человека.
  • Метод changePersonscel позволяет обновлять чел Лица в соответствии с id этого человека.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    DBHelper mDBHlpr;

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

        mDBHlpr = new DBHelper(this);

        // Delete all rows from both tables (if any)
        mDBHlpr.getWritableDatabase().delete(DBHelper.TB_USER,null,null);
        mDBHlpr.getWritableDatabase().delete(DBHelper.TB_PERSON,null,null);

        // Add some person rows
        mDBHlpr.insertPerson("Fred","0000-000-000"); // id will virtually certainly be 1
        mDBHlpr.insertPerson("Bert", "1111-111-111"); // id likely 2
        mDBHlpr.insertPerson("Mary","2222-222-222"); // id likely 3

        // Add some user rows
        mDBHlpr.insertUser("Fred@email.moc","Fred1234567890",1);
        mDBHlpr.insertUser("Bert@email.moc","Bert1234567890",2);
        mDBHlpr.insertUser("Mary@email.moc","Mary1234567890",3);

        //ooops add some unanticipated rows
        mDBHlpr.insertUser("whoever@email.moc","xxxx",3);
        mDBHlpr.insertUser("whoever@email.moc","xxxx",3);

        // Make some changes (updates)
        mDBHlpr.changePersonsCel(3,"6666-666-66");
        mDBHlpr.changePersonsName(3,"Marian");

        // get some data
        Cursor crs1 = mDBHlpr.getAllPersons();
        Cursor csr2 = mDBHlpr.getAllUsers();
        Cursor csr3 = mDBHlpr.getAllPersonsAndTheReferencedUser();

        // Output the retrieved data
        DatabaseUtils.dumpCursor(crs1);
        DatabaseUtils.dumpCursor(csr2);
        DatabaseUtils.dumpCursor(csr3);

        // Close the Cursors (should always be done when finished with the Cursor)
        crs1.close();
        crs1.close();
        csr3.close();
    }
}

Это вызывает методы в DBHelper.

  • Сначала создается экземпляр экземпляра DBHelper (mDBHlpr).
  • Затем все строки (если таковые имеются) удаляются из обеих таблиц (это делается для обеспечения согласованности результатов приложения).
  • Далее добавляются некоторые Персоны, а затем пользователи (в том числе некоторые непредвиденные / неожиданные пользователи (, в результате 3 человека ссылаются на 3 пользователей )).
  • Затем вносятся некоторые изменения (Мэри меняется на Мариан, а Мэри (или Мариана) изменяется с 2222-222-222 на 6666-666-66).
  • Все три метода выбора (getAll ....) запускаются и создаются 3 курсора.
  • Курсоры сбрасываются (записываются в журнал).
  • Курсоры закрыты.

3 выхода: -

Таблица Person (3 строки): -

>>>>> Dumping cursor android.database.sqlite.SQLiteCursor@a98de41
09-01 21:48:52.535 1919-1919/so52115977.so52115977 I/System.out: 0 {
       _id=1
09-01 21:48:52.536 1919-1919/so52115977.so52115977 I/System.out:    name_person=Fred
       cel_person=0000-000-000
    }
    1 {
       _id=2
       name_person=Bert
       cel_person=1111-111-111
    }
    2 {
       _id=3
       name_person=Marian
       cel_person=6666-666-66
    }
<<<<<

Таблица пользователей (5 строк)

    >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@e149fe6
    0 {
       _id=1
       email_user=Fred@email.moc
       pass_user=Fred1234567890
       id_person=1
    }
    1 {
       _id=2
       email_user=Bert@email.moc
       pass_user=Bert1234567890
       id_person=2
    }
    2 {
       _id=3
       email_user=Mary@email.moc
       pass_user=Mary1234567890
09-01 21:48:52.537 1919-1919/so52115977.so52115977 I/System.out:    id_person=3
    }
    3 {
       _id=4
       email_user=whoever@email.moc
       pass_user=xxxx
       id_person=3
    }
    4 {
       _id=5
       email_user=whoever@email.moc
       pass_user=xxxx
       id_person=3
    }
    <<<<<

Связанные / ссылочные / объединенные (с внешним ключом) таблицы Person / User (5 строк)

    >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@9645927
    0 {
       T_Person__id=1
       name_person=Fred
       cel_person=0000-000-000
       T_User__id=1
       email_user=Fred@email.moc
       pass_user=Fred1234567890
    }
    1 {
       T_Person__id=2
       name_person=Bert
       cel_person=1111-111-111
       T_User__id=2
       email_user=Bert@email.moc
       pass_user=Bert1234567890
    }
    2 {
       T_Person__id=3
       name_person=Marian
       cel_person=6666-666-66
       T_User__id=3
       email_user=Mary@email.moc
       pass_user=Mary1234567890
    }
    3 {
       T_Person__id=3
       name_person=Marian
       cel_person=6666-666-66
       T_User__id=4
       email_user=whoever@email.moc
       pass_user=xxxx
    }
    4 {
       T_Person__id=3
09-01 21:48:52.538 1919-1919/so52115977.so52115977 I/System.out:    name_person=Marian
       cel_person=6666-666-66
       T_User__id=5
       email_user=whoever@email.moc
       pass_user=xxxx
    }
    <<<<<

- ПРИМЕЧАНИЕ AUTOINCREMENT не использовалось.

  • На самом деле это не AUTOINCREMENT в SQLite, который приводит к генерации уникального обычно увеличивающегося числа.
  • Указание INTEGER PRIMARY KEY, как правило, является достаточным и не приводит к накладным расходам редко необходимого AUTOINCREMENT SQLite Autoincrement
  • На самом деле, если не указан БЕЗ ROWID, в таблице SQLite есть специальный, обычно скрытый столбец, называемый rowid , представляющий собой 64-битное целое число со знаком, которое первоначально будет равно 1, а затем, вероятно, 2 и т. Д. Кодирование INTEGER PRIMARY KEY делает столбец псевдонимом столбца rowid (AUTOINCREMENT может быть закодировано, только если закодирован INTEGER PRIMARY KEY).
...