如何在Android中使用SQlite为特定用户存储和检索数据

时间:2019-06-19 19:41:02

标签: java android sqlite android-sqlite

我想保存用户凭证(名称),然后在该名称上保存该特定用户的一些数据。我正在为此使用SQlite,并且已经成功保存了数据,但截至目前为止,我无法为特定用户创建数据。我的特定用户名当前保存在“共享首选项”中。请为我显示适当的解决方案。

数据库助手:

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 CREATE_TABLE_USER =
            "CREATE TABLE " + TABLE_USER_NAME + "("
                    + USER_COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT"
                    + ")";

    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 " + TABLE_NAME);
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_USER_NAME);
        onCreate(db);
    }

    public long insertNote(String note) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(Notes.COLUMN_NOTE, note);

        long id = db.insert(TABLE_NAME, null, values);
        db.close();
        return id;
    }

    public Notes getNote(long id) {
        SQLiteDatabase db = this.getReadableDatabase();

        Cursor cursor = db.query(TABLE_NAME,
                new String[]{Notes.NOTE_COLUMN_ID, Notes.COLUMN_NOTE},
                Notes.NOTE_COLUMN_ID + "=?",
                new String[]{String.valueOf(id)}, null, null, null, null);

        if (cursor != null)
            cursor.moveToFirst();

        Notes notes = new Notes(
                cursor.getInt(cursor.getColumnIndex(Notes.NOTE_COLUMN_ID)),
                cursor.getString(cursor.getColumnIndex(Notes.COLUMN_NOTE)));

        cursor.close();

        return notes;
    }

    public List<Notes> getAllNotes() {
        List<Notes> notes = new ArrayList<>();

        String selectQuery = "SELECT  * FROM " + TABLE_NAME + " ORDER BY " +
                Notes.NOTE_COLUMN_ID + " DESC";

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        if (cursor.moveToFirst()) {
            do {
                Notes note = new Notes();
                note.setId(cursor.getInt(cursor.getColumnIndex(Notes.NOTE_COLUMN_ID)));
                note.setNote(cursor.getString(cursor.getColumnIndex(Notes.COLUMN_NOTE)));


                notes.add(note);
            } while (cursor.moveToNext());
        }

        db.close();

        return notes;
    }

    public int getNotesCount() {
        String countQuery = "SELECT  * FROM " + TABLE_NAME;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(countQuery, null);

        int count = cursor.getCount();
        cursor.close();
        return count;
    } 

}

注释:

public class Notes {

    public static final String NOTE_COLUMN_ID = "id";
    public static final String COLUMN_NOTE = "note";
    public static final String TABLE_NAME = "notes";
    private int id;
    private String note;

    public static final String CREATE_TABLE_NOTE =
            "CREATE TABLE " + TABLE_NAME + "("
                    + NOTE_COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                    + COLUMN_NOTE + " TEXT"
                    + ")";

    public Notes() {
    }

    public Notes(int id, String note) {
        this.id = id;
        this.note = note;
    }

    public int getId() {
        return id;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }


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


}

片段

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_notes, container, false);
        recyclerView = view.findViewById(R.id.recycler_view);
        noNotesView = view.findViewById(R.id.empty_notes_view);
        logout = view.findViewById(R.id.button_logout);

        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();
        mGoogleSignInClient = GoogleSignIn.getClient(getActivity(), gso);
        GoogleSignInAccount acct = GoogleSignIn.getLastSignedInAccount(getActivity());
        mUser = acct.getDisplayName().trim();
        LoggedInSharedPreference.setGoogleUserId(getActivity(), mUser);


        db = new DBHelper(getActivity());
        user = db.insertUser(mUser);
        notesList.addAll(db.getNotesByUser(user));

        FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showNoteDialog(false, null, -1);
            }
        });

        mAdapter = new NotesAdapter(getActivity(), notesList);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(mAdapter);

        toggleEmptyNotes();

        recyclerView.addOnItemTouchListener(new NotesItemListener(getActivity(),
                recyclerView, new NotesItemListener.ClickListener() {
            @Override
            public void onClick(View view, final int position) {
            }

            @Override
            public void onLongClick(View view, int position) {
                showActionsDialog(position);
            }
        }));

        return view;
    }

    private void createNote(String note, long user) {
        long id = db.insertNote(note, user);

        Notes n = db.getNote(id);

        if (n != null) {
            notesList.add(0, n);
            mAdapter.notifyDataSetChanged();
            toggleEmptyNotes();
        }
    }

    private void updateNote(String note, int position) {
        Notes n = notesList.get(position);
        n.setNote(note);
        db.updateNote(n);
        notesList.set(position, n);
        mAdapter.notifyItemChanged(position);

        toggleEmptyNotes();
    }

    private void deleteNote(int position) {
        db.deleteNote(notesList.get(position));
        notesList.remove(position);
        mAdapter.notifyItemRemoved(position);

        toggleEmptyNotes();
    }

    private void showActionsDialog(final int position) {
        CharSequence charSequences[] = new CharSequence[]{"Edit", "Delete"};

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("Select");
        builder.setItems(charSequences, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (which == 0) {
                    showNoteDialog(true, notesList.get(position), position);
                } else {
                    deleteNote(position);
                }
            }
        });
        builder.show();
    }

    private void showNoteDialog(final boolean shouldUpdate, final Notes notes, final int position) {
        LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getContext());
        View view = layoutInflaterAndroid.inflate(R.layout.note_dialog, null);

        AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(getActivity());
        alertDialogBuilderUserInput.setView(view);

        final EditText inputNote = view.findViewById(R.id.notes);
        TextView dialogTitle = view.findViewById(R.id.dialog_title);
        dialogTitle.setText(!shouldUpdate ? getString(R.string.new_note) : getString(R.string.edit_note));

        if (shouldUpdate && notes != null) {
            inputNote.setText(notes.getNote());
        }
        alertDialogBuilderUserInput
                .setCancelable(false)
                .setPositiveButton(shouldUpdate ? "update" : "save", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialogBox, int id) {

                    }
                })
                .setNegativeButton("cancel",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialogBox, int id) {
                                dialogBox.cancel();
                            }
                        });

        final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
        alertDialog.show();

        alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (TextUtils.isEmpty(inputNote.getText().toString())) {
                    Toast.makeText(getActivity(), "Add Note", Toast.LENGTH_SHORT).show();
                    return;
                } else {
                    alertDialog.dismiss();
                }

                if (shouldUpdate && notes != null) {
                    updateNote(inputNote.getText().toString(), position);
                } else {
                    createNote(inputNote.getText().toString(), user);
                }
            }
        });
    }

}

1 个答案:

答案 0 :(得分:0)

您似乎需要一个注释(子项)与其用户(父项)之间的关系。假设一个便笺只有一个用户(拥有便笺)。然后,您可以在存储注释的表中添加一列。

由于User表具有使用INTEGER PRIMARY KEY定义的id列,因此该列是关系的理想候选者(已建立索引并且也是唯一的(隐式))。这将是一个整数值(在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类/对象进行免费更改以存储ID  类中拥有用户的用户(地图/关系)(最好是long),并为该用户的id添加一个getter和setter。您还应该具有一个包含用户ID的构造函数,以便从数据库中检索注释时使用。

然后,您需要更改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方法返回时,它永远不会为null。因此,以上方法使用moveToFirst方法的结果来确定行是否存在。
  • 如果找不到该注释,则上面的注释将返回null(而不是失败)。
  

但是截至目前,我无法为特定用户使用它   对于所有用户

上面的内容之后,您可以基于usermap列编写一个包含WHERE子句的查询。

例如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 因为它将在第一行中完成。

注意:以上为原理代码。它尚未经过测试也未运行,因此可能包含一些错误。它已作为指南提供。

工作示例

以下是基于您的代码和以上答案的基本工作示例。此外,已在用户的名称名称表中添加了另一列。

该应用程序添加了两个用户(Fred和Mary),然后为每个用户添加了2个注释。然后提取所有注释,然后提取Fred的所有注释,然后提取Mary的所有注释。然后将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

对于弗雷德(用户ID为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

对于Mary(用户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的支持(否则将忽略“ Foreign Key”定义)。
  • 请注意,AUTOINCREMENT已被删除,这是不必要的,并且有开销。
  • 请注意,为名称表添加了名称列,并且它具有不受限制的约束。

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()));
    }
}
  • 请注意,以上内容只能运行一次。如果随后运行Fred和Mary的id均为-1,因为由于名称重复而不会添加行,因此不会将注释提取到fredsnotes和marynotes中。