Android SQLite更新行不起作用,并且未显示任何错误

时间:2018-09-12 00:11:22

标签: android android-studio android-fragments sqlite

我曾经试图通过一个片段在Android中通过一个SQLite更新行,但是它不更新表,我也没有得到任何错误。这是我的代码..也许我遗漏了一些东西。谢谢

MySQLiteHelper类

public class MySQLiteHelper extends SQLiteOpenHelper {

    public static final String MYDATABASE = "myDataBase";
    public static final String MYTABLE = "myTable";
    public static final String USERNAME = "myUser";
    public static final String PASSWORD = "myPass";
    public static final String EMAIL = "myEmail";
    public static final int VERSION = 1;
    public static final String KEY_ID = "_id";


    public MySQLiteHelper(Context context) {
        super(context, MYDATABASE, null, VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String CREATE_TABLE = "CREATE TABLE " + MYTABLE + "("
                + KEY_ID + " INTEGER PRIMARY KEY," + USERNAME + " TEXT," + PASSWORD + " TEXT,"
                + EMAIL + " TEXT" + ")";

        db.execSQL(CREATE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //any upgrade can update the version and if newV > oldV then upgrade will be exected
        db.execSQL("DROP TABLE IF EXISTS " + MYTABLE);
        onCreate(db);
    }


    public Integer deleteData(String id) {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.delete(MYTABLE, "_id = ?", new String[] {id});
    }

    public boolean updateData(String id, String user, String pass, String email) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put(USERNAME, user);
        cv.put(PASSWORD, pass);
        cv.put(EMAIL, email);
        db.update(MYTABLE, cv, "_id = ?", new String[] {id});
        return true;
    }


}

主要活动课程

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    EditText etUser, etPass, etEmail;
    Button btSave, btShow;
    MySQLiteHelper mySQLiteHelper;
    SQLiteDatabase sqLiteDatabase;
    ListView lvRecords;
    ArrayList<String> userDataList;
    ArrayAdapter<String> adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "onCreate: started");

        etUser = findViewById(R.id.etUser);
        etPass = findViewById(R.id.etPass);
        etEmail = findViewById(R.id.etEmail);
        btSave = findViewById(R.id.btSave);
        btShow = findViewById(R.id.btShow);
        lvRecords = findViewById(R.id.lvRecords);

        userDataList = new ArrayList<String>();

        mySQLiteHelper = new MySQLiteHelper(this);
        sqLiteDatabase = mySQLiteHelper.getWritableDatabase(); //write and read

        adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, userDataList);
        lvRecords.setAdapter(adapter);
        showList();

        lvRecords.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {

                String selectedData = userDataList.get(position);
                String rowId = selectedData.substring(0,1);
                Log.d(TAG, "onItemLongClick: *******id " + rowId);
                Integer deleteRow = mySQLiteHelper.deleteData(rowId);
                adapter.remove(adapter.getItem(position));
                adapter.notifyDataSetChanged();



                Toast.makeText(MainActivity.this, "Position: " + rowId, Toast.LENGTH_SHORT).show();

                return false;
            }
        });

        lvRecords.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                UpdateFragment updateFragment = new UpdateFragment();
                FragmentManager fragmentManager = getSupportFragmentManager();
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.add(R.id.fragment_container, updateFragment).addToBackStack(null).commit();

                String selectedData = userDataList.get(position);
                String[] userData = selectedData.split("\\s+");
                String userId = userData[0];
                String userName = userData[1];
                String userPass = userData[2];
                String userEmail = userData[3];

                Bundle b = new Bundle();
                b.putInt("position", position);
                b.putString("id", userId);
                b.putString("user", userName);
                b.putString("pass", userPass);
                b.putString("email", userEmail);
                updateFragment.setArguments(b);


                Toast.makeText(MainActivity.this, "id", Toast.LENGTH_SHORT).show();

            }
        });


        btShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showList();
            }

        });

        btSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //content values to put the data in the database
                //same order as table creation fields order
                ContentValues contentValues = new ContentValues();


                String user = etUser.getText().toString();
                String pass = etPass.getText().toString();
                String email = etEmail.getText().toString();

                contentValues.put(mySQLiteHelper.USERNAME, user);
                contentValues.put(mySQLiteHelper.PASSWORD, pass);
                contentValues.put(mySQLiteHelper.EMAIL, email);
                sqLiteDatabase.insert(mySQLiteHelper.MYTABLE, null, contentValues);

                hideKeyboard();

                showList();

                etUser.setText("");
                etPass.setText("");
                etEmail.setText("");
            }
        });


    }



    public void hideKeyboard() {
        InputMethodManager imm = (InputMethodManager) getSystemService(
                Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
    }

    private void showList() {
        Cursor cursor = sqLiteDatabase.rawQuery("SELECT * FROM " + mySQLiteHelper.MYTABLE, null);

            cursor.moveToFirst();
            userDataList.clear();


            //to read the first iteration use a do while
            do {
                if(cursor != null) {

                    int id = cursor.getInt(cursor.getColumnIndex(mySQLiteHelper.KEY_ID));
                    String user = cursor.getString(cursor.getColumnIndex(mySQLiteHelper.USERNAME));
                    String pass = cursor.getString(cursor.getColumnIndex(mySQLiteHelper.PASSWORD));
                    String email = cursor.getString(cursor.getColumnIndex(mySQLiteHelper.EMAIL));

                    userDataList.add(id + " " + user + " " + pass + " " + email);
                    adapter.notifyDataSetChanged();

                    Log.d(TAG, "onClick: ******rows: " + mySQLiteHelper.KEY_ID + ":" + id + " user: " + user + " pass: " + pass + " email: " + email);
                    Toast.makeText(MainActivity.this,
                            "id: " + id + " user: " + user + " pass: " + pass + " email: " + email, Toast.LENGTH_SHORT)
                            .show();
                }
            } while(cursor.moveToNext());


    }



}

UpdateFragment.class

public class UpdateFragment extends Fragment {

    private static final String TAG = "UpdateFragment";

    Button btUpdate, btClose;
    EditText etUser, etPass, etEmail;
    Fragment me = this;
    MySQLiteHelper mySQLiteHelper;
    SQLiteDatabase sqLiteDatabase;

    String userId, username, password, email;
    int position, e;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_update, container, false);

        etUser = v.findViewById(R.id.etUserFrag);
        etPass = v.findViewById(R.id.etPassFrag);
        etEmail = v.findViewById(R.id.etEmailFrag);
        btUpdate = v.findViewById(R.id.btUpdateFrag);
        btClose = v.findViewById(R.id.btCloseFrag);

        Bundle b = getArguments();
        position = b.getInt("position");
        position = position -1;
        userId =  b.getString("id");
        e = Integer.parseInt(userId);
        //e = e - 1;
        //userId = userId -1 ;
        Log.d(TAG, "onCreateView: **********userID: " + userId);
        username = b.getString("user");
        password = b.getString("pass");
        email = b.getString("email");

        etUser.setText(username);
        etPass.setText(password);
        etEmail.setText(email);

        mySQLiteHelper = new MySQLiteHelper(getContext());
        sqLiteDatabase = mySQLiteHelper.getWritableDatabase(); //write and read

        btClose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                closeFragment();
            }
        });

        btUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {//
                boolean isUpdate = mySQLiteHelper.updateData(userId, username, password, email);
                if(isUpdate==true)
                    Toast.makeText(getContext(),"Data Update",Toast.LENGTH_LONG).show();
                else
                    Toast.makeText(getContext(),"Data not Updated",Toast.LENGTH_LONG).show();



            }
        });








        return v;
    }

    private void closeFragment() {
        getActivity().getSupportFragmentManager().beginTransaction().remove(me).commit();
    }
}

1 个答案:

答案 0 :(得分:0)

第1个空游标

从不认为空光标为空。

返回Cursor的

SQLiteDatabase方法将返回有效的Cursor,而不是null。光标为空时,其计数为0(即cursor.getCount() == 0)。

因此,如果您只是这样做(按照您的 showlist 方法)

    cursor.moveToFirst();
    if (cursor == null) {
        do you stuff here
    }

如果游标为空,则会出现索引错误。相反,您应该检查cursor.moveToFirst()的结果,如果现在提取了行,则结果为false。但是,使用 while 循环更容易(请参见下面的代码)。

问题1-2关闭光标

完成操作后,您还应该关闭游标。

更正/更好的 showList 方法:-

private void showList() {
    Cursor cursor = sqLiteDatabase.rawQuery("SELECT * FROM " + mySQLiteHelper.MYTABLE, null);

    userDataList.clear();
    //<<<<<<<<<< simpler while loop >>>>>>>>>>
    while (cursor.moveToNext()) {
        int id = cursor.getInt(cursor.getColumnIndex(mySQLiteHelper.KEY_ID));
        String user = cursor.getString(cursor.getColumnIndex(mySQLiteHelper.USERNAME));
        String pass = cursor.getString(cursor.getColumnIndex(mySQLiteHelper.PASSWORD));
        String email = cursor.getString(cursor.getColumnIndex(mySQLiteHelper.EMAIL));

        userDataList.add(id + " " + user + " " + pass + " " + email);
        adapter.notifyDataSetChanged();

        Log.d(TAG, "onClick: ******rows: " + mySQLiteHelper.KEY_ID + ":" + id + " user: " + user + " pass: " + pass + " email: " + email);
        Toast.makeText(MainActivity.this,
                "id: " + id + " user: " + user + " pass: " + pass + " email: " + email, Toast.LENGTH_SHORT)
                .show();
    }
    cursor.close();
}

问题2-未输入任何数据时保存。

如果单击“保存”按钮,但尚未在字段中输入任何数据,则将添加新行。如果在ListView中单击该项目,则会导致由于数组中的索引错误而导致崩溃,因为 split 不会提取4个项目(只有 id 保证)。

以下内容将纠正此问题(请看commenets):-

    btSave.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //<<<<<<<<<< Start of Extra Code >>>>>>>>>>
            if (
                    etUser.getText().toString().length() < 1 ||
                            etEmail.getText().toString().length() < 1 ||
                            etPass.getText().toString().length() < 1
                    ) {
                Toast.makeText(MainActivity.this,"WHOA ENTER DATA IN ALL FIELDS!!!!!!!!!!",Toast.LENGTH_SHORT).show();
                return;
            }
            //<<<<<<<<<< End of Extra Code >>>>>>>>>>
            //content values to put the data in the database
            //same order as table creation fields order
            ContentValues contentValues = new ContentValues();
            String user = etUser.getText().toString();
            String pass = etPass.getText().toString();
            String email = etEmail.getText().toString();
            contentValues.put(mySQLiteHelper.USERNAME, user);
            contentValues.put(mySQLiteHelper.PASSWORD, pass);
            contentValues.put(mySQLiteHelper.EMAIL, email);
            sqLiteDatabase.insert(mySQLiteHelper.MYTABLE, null, contentValues);
            hideKeyboard();
            showList();
            etUser.setText("");
            etPass.setText("");
            etEmail.setText("");
        }
    });

问题3-updateData方法始终返回true

SQliteDatabase update 方法返回受影响的行数,因此,如果没有行被更新(将行更改为与更新相同的值),则将返回0。您的 updateData 方法不检查结果,因此始终返回true。

也许将其更改为:-

public boolean updateData(String id, String user, String pass, String email) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues cv = new ContentValues();
    cv.put(USERNAME, user);
    cv.put(PASSWORD, pass);
    cv.put(EMAIL, email);
    if (db.update(MYTABLE, cv, "_id = ?", new String[] {id}) > 0) {
        return true;
    }
    return false;
}

为了提供更准确的反馈(并突出显示您的主要问题),可以添加以下方法来根据ID获取数据:-

public Cursor getDataById(String id) {
    SQLiteDatabase db = this.getWritableDatabase();
    String whereclause = KEY_ID + "=?";
    String[] whereargs = new String[]{String.valueOf(id)};
    return db.query(MYTABLE,null,whereclause,whereargs,null,null,null);
}
  • 请注意,下面的主要问题中包含了对此的使用。

主要问题

导致没有更新的主要问题是因为您将旧值传递给了更新,而不是按照EditTexts传递值。

以下代码更改了更新按钮 onClickListener 以解决此问题,并且还通过发布的Toast提供了更好的反馈:-

    btUpdate.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {//
            //boolean isUpdate = mySQLiteHelper.updateData(userId, username, password, email);
            boolean isUpdate = mySQLiteHelper.updateData(
                    userId,
                    etUser.getText().toString(),
                    etPass.getText().toString(),
                    etEmail.getText().toString()
            );
            Cursor csr = mySQLiteHelper.getDataById(userId);
            String newUser = "not found";
            String newEmail = "not found";
            String newPass = "not found";
            if (csr.moveToFirst()) {
                newUser = csr.getString(csr.getColumnIndex(MySQLiteHelper.USERNAME));
                newEmail = csr.getString(csr.getColumnIndex(MySQLiteHelper.EMAIL));
                newPass = csr.getString(csr.getColumnIndex(MySQLiteHelper.PASSWORD));
            }
            csr.close();
            if(isUpdate==true)
                Toast.makeText(getContext(),
                        "Data Updated - User now " + newUser +
                                " Email now " + newEmail +
                                " Password now " + newPass,
                        Toast.LENGTH_LONG
                ).show();
            else
                Toast.makeText(getContext(),"Data not Updated - User is " + newUser +
                                " Email is " + newEmail +
                                " Password is " + newPass,
                        Toast.LENGTH_LONG
                ).show();
        }
    });

    btUpdate.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //boolean isUpdate = mySQLiteHelper.updateData(userId, username, password, email); //<<<<<<<<<< Commented out (old)
            //<<<<<<<<<< NEW (gets values from the edit texts)
            boolean isUpdate = mySQLiteHelper.updateData(
                    userId,
                    etUser.getText().toString(),
                    etPass.getText().toString(),
                    etEmail.getText().toString()
            );
            //<<<<<<<<<< ADDED to get current stored data for Toast
            Cursor csr = mySQLiteHelper.getDataById(userId);
            String newUser = "not found";
            String newEmail = "not found";
            String newPass = "not found";
            if (csr.moveToFirst()) {
                newUser = csr.getString(csr.getColumnIndex(MySQLiteHelper.USERNAME));
                newEmail = csr.getString(csr.getColumnIndex(MySQLiteHelper.EMAIL));
                newPass = csr.getString(csr.getColumnIndex(MySQLiteHelper.PASSWORD));
            }
            csr.close();
            //<<<<<<<<< CHANGES so more info is provided by Toasts
            if(isUpdate==true)
                Toast.makeText(getContext(),
                        "Data Updated - User now " + newUser +
                                " Email now " + newEmail +
                                " Password now " + newPass,
                        Toast.LENGTH_LONG
                ).show();
            else
                Toast.makeText(getContext(),"Data not Updated - User is " + newUser +
                                " Email is " + newEmail +
                                " Password is " + newPass,
                        Toast.LENGTH_LONG
                ).show();
        }
    });