Похоже, вам нужна связь между Заметкой (дочерней) и ее пользователем (родительской). Предполагая, что заметка будет иметь только одного пользователя (которому принадлежит заметка). Затем вы можете добавить столбец в таблицу, где вы храните заметки.
Поскольку в таблице User столбец id определен с использованием INTEGER PRIMARY KEY
, этот столбец является идеальным кандидатом для отношения (он проиндексирован и также уникален (неявно)). Это будет целочисленное значение (потенциально длинное в Java).
Чтобы быть последовательным, вы должны определить константу для имени столбца, поэтому добавьте: -
public static final String NOTE_COLUMN_USERMAP = "usermap";
Затем вы можете определить изменение константы CREATE_TABLE_NOTE для включения
+ NOTE_COLUMN_USERMAP + " INTEGER "; //<<<<<<<<<comma if needed after INTEGER
Или, если вы хотите ввести ограничения FOREIGN KEY и использовать
+ NOTE_COLUMN_USERMAP + "INTEGER REFERENCES " + DBHelper.TABLE_USER_NAME + "(" + USER_COLUMN_ID + ") ON DELETE CASCADE ON UPDATE CASCADE "; //<<<<<<<<<comma if needed after 2nd CASCADE
Вы должны сделать бесплатное изменение класса / объекта Notes, чтобы сохранить идентификатор
пользователь (карта / отношение) (предпочтительно как длинный) пользователя-владельца в классе и добавить геттер и сеттер для идентификатора пользователя. У вас также должен быть конструктор, который включает идентификатор пользователя для использования при извлечении заметки из базы данных.
Затем вам нужно будет внести изменения в методы DBHelper для обслуживания дополнительного столбца. например
Метод insertNote может стать: -
public long insertNote(String note, long userMap) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Notes.COLUMN_NOTE, note);
values.put(Notes.NOTE_COLUMN_USERMAP,userMap);
long id = db.insert(TABLE_NAME, null, values);
db.close();
return id;
}
Метод getNotes может стать: -
public Notes getNote(long id) {
Notes notes;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME,
new String[]{Notes.NOTE_COLUMN_ID, Notes.COLUMN_NOTE,Notes.NOTE_COLUMN_USERMAP},
Notes.NOTE_COLUMN_ID + "=?",
new String[]{String.valueOf(id)}, null, null, null, null);
if (cursor.moveToFirst()) {
notes = new Notes(
cursor.getInt(cursor.getColumnIndex(Notes.NOTE_COLUMN_ID)),
cursor.getString(cursor.getColumnIndex(Notes.COLUMN_NOTE)),
cursor.getLong(cursor.getColumnIndex(Notes.NOTE_COLUMN_USERMAP))
);
}
cursor.close();
return notes;
}
- Обратите внимание, что в приведенном выше примере предполагается, что конструктор имеет значение для отображения пользователя в качестве последнего.
- Заметьте, что проверка Cursor на null бесполезна, она никогда не будет нулевой, когда возвращается из метода SQliteDatabase Следовательно, вышеизложенное использует результат метода moveToFirst для определения, существует строка или нет.
- Обратите внимание, что вышеупомянутое вернет ноль (а не провал), если примечание не будет найдено.
но я не могу сделать это для конкретного пользователя. Сейчас он показывает
для всех пользователей
После вышесказанного вы можете написать запрос, содержащий предложение WHERE, основанное на столбце usermap.
например. getNotesByUser может быть: -
public List<Notes> getNotesByUser(long usermap) {
List<Notes> notes = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME,
new String[]{Notes.NOTE_COLUMN_ID, Notes.COLUMN_NOTE,Notes.NOTE_COLUMN_USERMAP},
Notes.NOTE_COLUMN_USERMAP + "=?",
new String[]{String.valueOf(usermap)}, null, null, null, null);
while(cursor.moveToNext()) {
notes.add(new Notes(cursor.getInt(cursor.getColumnIndex(Notes.NOTE_COLUMN_ID)),
cursor.getString(cursor.getColumnIndex(Notes.COLUMN_NOTE)),
cursor.getLong(cursor.getColumnIndex(Notes.NOTE_COLUMN_USERMAP)))
);
}
cursor.close();
return notes;
}
- Обратите внимание на более простой цикл while, т. Е. Метод moveToNext возвращает значение false, если перемещение не может быть выполнено (т. Е. После последней строки), тогда нет необходимости moveToFirst , поскольку он сделаю это для первого ряда.
Примечание Выше приведен принципиальный код. Он не тестировался и не запускался, поэтому может содержать некоторые ошибки. Это было предоставлено в качестве руководства.
Рабочий пример
Ниже приведен основной рабочий пример, основанный на вашем коде и приведенном выше ответе. Кроме того, в таблицу имя добавлен дополнительный столбец для имя пользователя.
Приложение добавляет двух пользователей (Фред и Мэри), а затем добавляет 2 заметки для каждого пользователя. Затем он извлекает все заметки, а затем все заметки для Фреда, а затем для Мэри. Затем 3 набора извлеченных выходных данных выводятся в журнал.
В результате: -
Для всех Заметки для всех пользователей: -
06-20 12:29:22.901 2401-2401/s.e.so56674777notes D/LOGNOTEALL: Note isMy Second Note
ID is 4
Owned by User who's ID is 2
06-20 12:29:22.901 2401-2401/s.e.so56674777notes D/LOGNOTEALL: Note isMy Second Note
ID is 3
Owned by User who's ID is 1
06-20 12:29:22.901 2401-2401/s.e.so56674777notes D/LOGNOTEALL: Note isMy First Note
ID is 2
Owned by User who's ID is 2
06-20 12:29:22.901 2401-2401/s.e.so56674777notes D/LOGNOTEALL: Note isMy First Note
ID is 1
Owned by User who's ID is 1
Для Фреда (идентификатор пользователя 1): -
06-20 12:29:22.901 2401-2401/s.e.so56674777notes D/LOGNOTEFRED: Note isMy First Note
ID is 1
Owned by User who's ID is 1
06-20 12:29:22.901 2401-2401/s.e.so56674777notes D/LOGNOTEFRED: Note isMy Second Note
ID is 3
Owned by User who's ID is 1
Для Мэри (ID пользователя 2): -
06-20 12:29:22.901 2401-2401/s.e.so56674777notes D/LOGNOTEMARY: Note isMy First Note
ID is 2
Owned by User who's ID is 2
06-20 12:29:22.901 2401-2401/s.e.so56674777notes D/LOGNOTEMARY: Note isMy Second Note
ID is 4
Owned by User who's ID is 2
код
Notes.java
public class Notes {
public static final String TABLE_NAME = "notes";
public static final String NOTE_COLUMN_ID = BaseColumns._ID;
public static final String COLUMN_NOTE = "note";
public static final String NOTE_COLUMN_USERMAP = "usermap";
public static final String CREATE_TABLE_NOTE = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" +
NOTE_COLUMN_ID + " INTEGER PRIMARY KEY, " +
COLUMN_NOTE + " TEXT, " +
NOTE_COLUMN_USERMAP + " INTEGER " +
"REFERENCES " + DBHelper.TABLE_USER_NAME + "(" + DBHelper.USER_COLUMN_ID + ") " +
"ON DELETE CASCADE ON UPDATE CASCADE" +
")";
public Notes(int id, String note, long usermap) {
this.id = id;
this.note = note;
this.usermap = usermap;
}
public Notes() {}
private int id;
private String note;
private long usermap;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public long getUsermap() {
return usermap;
}
public void setUsermap(long usermap) {
this.usermap = usermap;
}
}
DBHelper.java
public class DBHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "NOTES";
public static final String USER_COLUMN_ID = "idu";
public static final String TABLE_USER_NAME = "name";
public static final String USER_COLUMN_NAME = TABLE_USER_NAME;
public static final String CREATE_TABLE_USER =
"CREATE TABLE " + TABLE_USER_NAME + "("
+ USER_COLUMN_ID + " INTEGER PRIMARY KEY,"
+ USER_COLUMN_NAME + " TEXT UNIQUE "
+ ")";
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(Notes.CREATE_TABLE_NOTE);
db.execSQL(CREATE_TABLE_USER);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + Notes.TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_USER_NAME);
onCreate(db);
}
@Override
public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db);
db.setForeignKeyConstraintsEnabled(true);
}
public long insertUser(String username) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(USER_COLUMN_NAME,username);
return db.insert(TABLE_USER_NAME,null,cv);
}
public long insertNote(String note, long usermap) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Notes.COLUMN_NOTE, note);
values.put(Notes.NOTE_COLUMN_USERMAP,usermap);
long id = db.insert(Notes.TABLE_NAME, null, values);
db.close();
return id;
}
public Notes getNote(long id) {
Notes notes = null;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(Notes.TABLE_NAME,
new String[]{Notes.NOTE_COLUMN_ID, Notes.COLUMN_NOTE, Notes.NOTE_COLUMN_USERMAP},
Notes.NOTE_COLUMN_ID + "=?",
new String[]{String.valueOf(id)},
null, null, null, null
);
if (cursor.moveToFirst()) {
notes = new Notes(
cursor.getInt(cursor.getColumnIndex(Notes.NOTE_COLUMN_ID)),
cursor.getString(cursor.getColumnIndex(Notes.COLUMN_NOTE)),
cursor.getLong(cursor.getColumnIndex(Notes.NOTE_COLUMN_USERMAP))
);
}
cursor.close();
return notes;
}
public List<Notes> getAllNotes() {
List<Notes> notes = new ArrayList<>();
String selectQuery = "SELECT * FROM " + Notes.TABLE_NAME + " ORDER BY " +
Notes.NOTE_COLUMN_ID + " DESC";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
while (cursor.moveToNext()) {
Notes note = new Notes();
note.setId(cursor.getInt(cursor.getColumnIndex(Notes.NOTE_COLUMN_ID)));
note.setNote(cursor.getString(cursor.getColumnIndex(Notes.COLUMN_NOTE)));
note.setUsermap(cursor.getLong(cursor.getColumnIndex(Notes.NOTE_COLUMN_USERMAP)));
notes.add(note);
}
db.close();
return notes;
}
public List<Notes> getNotesByUser(long usermap) {
List<Notes> notes = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(Notes.TABLE_NAME,
new String[]{Notes.NOTE_COLUMN_ID, Notes.COLUMN_NOTE,Notes.NOTE_COLUMN_USERMAP},
Notes.NOTE_COLUMN_USERMAP + "=?",
new String[]{String.valueOf(usermap)}, null, null, null, null);
while(cursor.moveToNext()) {
notes.add(new Notes(cursor.getInt(cursor.getColumnIndex(Notes.NOTE_COLUMN_ID)),
cursor.getString(cursor.getColumnIndex(Notes.COLUMN_NOTE)),
cursor.getLong(cursor.getColumnIndex(Notes.NOTE_COLUMN_USERMAP)))
);
}
cursor.close();
return notes;
}
public int getNotesCount() {
String countQuery = "SELECT * FROM " + Notes.TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int count = cursor.getCount();
cursor.close();
return count;
}
}
- Обратите внимание на добавление, которое переопределяет метод onConfigure , это включает поддержку ForeignKey (в противном случае определения внешнего ключа игнорируются).
- Примечание AUTOINCREMENT была удалена, она не нужна и имеет накладные расходы.
- Обратите внимание на добавление столбца имени для таблицы имен и на то, что она имеет ограничение unqiue.
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);
long user1 = mDBHlpr.insertUser("Fred");
long user2 = mDBHlpr.insertUser("Mary");
Notes n1 = new Notes(-1,"My First Note",-1);
Notes n2 = new Notes(-1,"My Second Note",-1);
if (mDBHlpr.getNotesCount() < 1) {
mDBHlpr.insertNote(n1.getNote(), user1);
mDBHlpr.insertNote(n1.getNote(), user2);
mDBHlpr.insertNote(n2.getNote(), user1);
mDBHlpr.insertNote(n2.getNote(), user2);
}
List<Notes> allusers = mDBHlpr.getAllNotes();
List<Notes> fredsnotes = mDBHlpr.getNotesByUser(user1);
List<Notes> marysnotes = mDBHlpr.getNotesByUser(user2);
for (Notes n: allusers) {
logNote("ALL",n);
}
for (Notes n: fredsnotes) {
logNote("FRED",n);
}
for (Notes n: marysnotes) {
logNote("MARY",n);
}
}
private void logNote(String type, Notes n) {
Log.d("LOGNOTE" + type,"Note is" + n.getNote() + "\n\t ID is " + String.valueOf(n.getId()) + "\n\t" + "Owned by User who's ID is " + String.valueOf(n.getUsermap()));
}
}
- Обратите внимание, что вышеуказанное предназначено для запуска только один раз. При последующем запуске оба идентификатора для Фреда и Мэри будут равны -1, поскольку строки не будут добавлены из-за повторяющегося имени, и, следовательно, не будет никаких примечаний, извлеченных в fredsnotes и marynotes.