每次我打开我的应用程序时,我的数据库都会一次又一次地创建

时间:2017-02-05 17:08:20

标签: android android-sqlite

我正在从Web服务响应填充我的SQLite数据库。第一个运行应用程序,应用程序正确显示ListView。我遇到的问题是,当我关闭应用程序并再次打开它时,数据库只是创建相同的表而不是覆盖数据。所以作为回报,我的数据库不断地一个接一个地生成相同的行。因此,8行的响应开始变为16,24等。

我尝试更改DATABASE_VERSION数字以强制onUpgrade但是没有任何结果。

数据库类

public class EmployeeDBHandler extends SQLiteOpenHelper {
    private static final int DATABASE_VERSION = 3;
    private static final String DATABASE_NAME = "OneTeam";
    private static final String TABLE_EMPLOYEE = "employees";
    //Employee table columns names
    private static final String KEY_ID = "Employee_number";
    private static final String KEY_FIRST_NAME = "First_name";
    private static final String KEY_LAST_NAME = "Last_name";
    private static final String KEY_PHONE_NUMBER_MOBILE = "Phone_mobile";
    private static final String KEY_PHONE_NUMBER_OFFICE = "Phone_office";
    private static final String KEY_PAYROLL_TITLE = "Payroll_title";
    private static final String KEY_HAS_DIRECT_REPORTS = "Has_direct_reports";
    private static final String KEY_EMAIL = "Email";
    private static final String KEY_COST_CENTER = "Cost_center_id";
    private static final String KEY_THUMBNAIL_IMAGE = "ThumbnailData";
    private final static String DB_CLIENTS_ID = "_id";

    public EmployeeDBHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String CREATE_EMPLOYEE_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE_EMPLOYEE + "("
                + DB_CLIENTS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                + KEY_ID + " TEXT,"
                + KEY_FIRST_NAME + " TEXT,"
                + KEY_LAST_NAME + " TEXT,"
                + KEY_PHONE_NUMBER_MOBILE + " TEXT,"
                + KEY_PHONE_NUMBER_OFFICE + " TEXT,"
                + KEY_PAYROLL_TITLE + " TEXT,"
                + KEY_HAS_DIRECT_REPORTS + " TEXT,"
                + KEY_EMAIL + " TEXT,"
                + KEY_THUMBNAIL_IMAGE + " TEXT,"
                + KEY_COST_CENTER + " TEXT"
                + ")";
        db.execSQL(CREATE_EMPLOYEE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //drop old table if existence
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_EMPLOYEE);
        //Create table again
        onCreate(db);
    }
    //Add new employee
    public boolean addEmployee(Employee employee) {
        SQLiteDatabase database = this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(KEY_ID, employee.getEmployee_number());
        values.put(KEY_FIRST_NAME, employee.getFirst_name());
        values.put(KEY_LAST_NAME, employee.getLast_name());
        values.put(KEY_PHONE_NUMBER_MOBILE, employee.getPhone_mobile());
        values.put(KEY_PHONE_NUMBER_OFFICE, employee.getPhone_office());
        values.put(KEY_HAS_DIRECT_REPORTS, employee.getHas_direct_reports());
        values.put(KEY_EMAIL, employee.getEmail());
        values.put(KEY_COST_CENTER, employee.getCost_center_id());
        values.put(KEY_PAYROLL_TITLE, employee.getPayroll_title());
        values.put(KEY_THUMBNAIL_IMAGE, employee.getThumbnailData());
        //Inserting Row
        database.replace(TABLE_EMPLOYEE, null, values);
        database.close();
        return true;
    }
    //Get single employee
    public Employee getEmployee(int employeeNumber) {
        SQLiteDatabase database = this.getReadableDatabase();
        Employee employee = null;    
        Cursor cursor = database.query(TABLE_EMPLOYEE, new String[]{
                        KEY_ID, KEY_FIRST_NAME, KEY_LAST_NAME, KEY_PHONE_NUMBER_OFFICE, KEY_PHONE_NUMBER_MOBILE,
                        KEY_HAS_DIRECT_REPORTS, KEY_EMAIL, KEY_COST_CENTER, KEY_PAYROLL_TITLE, KEY_THUMBNAIL_IMAGE}, KEY_ID + "=?",
                new String[]{String.valueOf(employeeNumber)}, null, null, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                employee = new Employee(cursor.getString(0),
                        cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(4),
                        cursor.getString(5), cursor.getString(6), cursor.getString(7), cursor.getString(8),
                        cursor.getString(9), cursor.getString(10), cursor.getString(11), cursor.getString(12),
                        cursor.getString(12), cursor.getString(14), cursor.getString(15), cursor.getString(16),
                        cursor.getString(17), cursor.getString(18), cursor.getString(19), cursor.getString(20),
                        cursor.getString(21), cursor.getString(22), cursor.getString(23), cursor.getString(24),
                        cursor.getString(24), cursor.getString(25), cursor.getString(26));
            }
        }
        cursor.close();
        database.close();
        return employee;    
    }
    //Get All Employees
    public ArrayList<Employee> getAllEmployees() {
        ArrayList<Employee> employeeList = new ArrayList<>();
        //Select all query
        String selectQuery = "SELECT * FROM " + TABLE_EMPLOYEE;
        SQLiteDatabase database = this.getWritableDatabase();
        Cursor cursor = database.rawQuery(selectQuery, null);
        //looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {
                Employee employee = new Employee();
                employee.setEmployee_number(cursor.getString(cursor.getColumnIndex(KEY_ID)));
                employee.setFirst_name(cursor.getString(cursor.getColumnIndex(KEY_FIRST_NAME)));
                employee.setLast_name(cursor.getString(cursor.getColumnIndex(KEY_LAST_NAME)));
                employee.setPhone_office(cursor.getString(cursor.getColumnIndex(KEY_PHONE_NUMBER_MOBILE)));
                employee.setPhone_mobile(cursor.getString(cursor.getColumnIndex(KEY_PHONE_NUMBER_OFFICE)));
                employee.setHas_direct_reports(cursor.getString(cursor.getColumnIndex(KEY_HAS_DIRECT_REPORTS)));
                employee.setEmail(cursor.getString(cursor.getColumnIndex(KEY_EMAIL)));
                employee.setCost_center_id(cursor.getString(cursor.getColumnIndex(KEY_COST_CENTER)));
                employee.setPayroll_title(cursor.getString(cursor.getColumnIndex(KEY_PAYROLL_TITLE)));
                employee.setThumbnailData(cursor.getString(cursor.getColumnIndex(KEY_THUMBNAIL_IMAGE)));
            } while (cursor.moveToNext());
        }
        //return employees list
        return employeeList;
    }

    //Get Employee Count
    public int getEmployeeCount() {
        String countQuery = "SELECT * FROM " + TABLE_EMPLOYEE;
        SQLiteDatabase database = this.getReadableDatabase();
        Cursor cursor = database.rawQuery(countQuery, null);
        cursor.close();
        return cursor.getCount();
    }

    // Updating single employee
    public int updateEmployee(Employee employee) {
        SQLiteDatabase database = this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(KEY_FIRST_NAME, employee.getFirst_name());
        values.put(KEY_LAST_NAME, employee.getLast_name());
        values.put(KEY_PHONE_NUMBER_MOBILE, employee.getPhone_mobile());
        values.put(KEY_PHONE_NUMBER_OFFICE, employee.getPhone_office());
        values.put(KEY_HAS_DIRECT_REPORTS, employee.getHas_direct_reports());
        values.put(KEY_EMAIL, employee.getEmail());
        values.put(KEY_COST_CENTER, employee.getCost_center_id());
        values.put(KEY_PAYROLL_TITLE, employee.getPayroll_title());
        values.put(KEY_THUMBNAIL_IMAGE, employee.getThumbnailData());
        return database.update(TABLE_EMPLOYEE, values, KEY_ID + " = ?",
                new String[]{String.valueOf(employee.getEmployee_number())});
    }

    //Delete single employee
    public void deleteEmployee(Employee employee) {
        SQLiteDatabase database = this.getWritableDatabase();
        database.delete(TABLE_EMPLOYEE, KEY_ID + " = ?",
                new String[]{String.valueOf(employee.getEmployee_number())});
        database.close();
    }

    //delete row
    public void delete(int id) {
        SQLiteDatabase db = this.getWritableDatabase();
        if (db == null) {
            return;
        }
        db.delete(TABLE_EMPLOYEE, "Employee+number = ?", new String[]{String.valueOf(id)});
        db.close();
    }
}

创建数据库的主要活动,并使用员工arraylist填充

public class MainActivity extends AppCompatActivity {

    private ProgressBar mProgressBar;
    EmployeeDBHandler dbHandler;
    private int mStartingEmployeeID = "startingNumber";
    private String table = "employees";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dbHandler = new EmployeeDBHandler(getApplicationContext());
        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
        mProgressBar.setVisibility(View.VISIBLE);
        getXMLData();
        //GUI for seeing android SQLite Database in Chrome Dev Tools
        Stetho.InitializerBuilder inBuilder = Stetho.newInitializerBuilder(this);
        inBuilder.enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this));
        Stetho.Initializer in = inBuilder.build();
        Stetho.initialize(in);
    }

    public void getXMLData() {
        OkHttpClient client = getUnsafeOkHttpClient();
        Request request = new Request.Builder()
                .url(getString(R.string.API_FULL_URL))
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                final String responseData = response.body().string();
                final InputStream stream = new ByteArrayInputStream(responseData.getBytes());
                final XMLPullParserHandler parserHandler = new XMLPullParserHandler();
                final ArrayList<Employee> employees = (ArrayList<Employee>) parserHandler.parse(stream);
                for (Employee e : employees) {
                     dbHandler.addEmployee(e);
                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mProgressBar.setVisibility(View.GONE);
                        displayTopList();
                        displayBottomList();
                    }
                });
            }
        });
    }
    public void displayTopList() {
        SQLiteDatabase db = dbHandler.getWritableDatabase();
        Cursor mTopListCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " + "Employee_number" + "=" + mStartingEmployeeID, null);
        ListView mTopListView = (ListView) findViewById(R.id.mTopList);
        TopListCursorAdapter topAdapter = new TopListCursorAdapter(this, mTopListCursor);
        mTopListView.setAdapter(topAdapter);
    }
    public void displayBottomList() {
        SQLiteDatabase db = dbHandler.getWritableDatabase();
        Cursor mBottomListCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " + "Employee_number" + "!=" + mStartingEmployeeID, null);
        ListView mBottomListView = (ListView) findViewById(R.id.mDirectReportList);
        BottomListViewAdapter bottomAdapter = new BottomListViewAdapter(this, mBottomListCursor);
        mBottomListView.setAdapter(bottomAdapter);
    }

    @Override
    public void onBackPressed() {
        moveTaskToBack(false);
    }
}

2 个答案:

答案 0 :(得分:1)

  

我遇到的问题是,当我关闭应用程序并再次打开它时,数据库只是创建相同的表而不是覆盖数据。

事实并非如此。首次启动应用程序时,仅创建一次数据库和表。但是,每次应用启动时都会调用getXmlData()。这似乎是从Web服务获取数据并将其插入数据库。因此,每次运行应用程序时都会看到数据重复。

我不确定你要做什么,所以这里有两个建议:

  1. 如果要在创建数据库时从Web提取数据,则应将getXmlData()方法移至EmployeeDBHandler并从该类onCreate()中调用它

  2. 如果要与Web服务共享数据,则需要添加更复杂的逻辑以跟踪已下载的数据。一种方法是在XML中添加一个项目,可以更新该项目以指示数据已经下载。

答案 1 :(得分:1)

从你的代码中可以看出,根据我的理解,它的表现正确。

  

您的问题是由于您的代码中的这一行:           &#39;

     

//插入行

    database.replace(TABLE_EMPLOYEE, null, values);

如果在表格中找不到匹配的记录,该行将创建新记录。你也试着找到如何完成记录的匹配,我认为它依赖于你没有提供的主键。

如果您需要使用服务器更新或同步本地数据,请执行以下操作:

  1. 在插入新数据之前删除以前的数据。(将是 根据我的说法,最适合你。)你可以使用触发器。
  2. 使用更新查询更新数据库中的记录。
  3. 如果使用替换API,请在内容值中插入primary_key值,以便获得正确的功能。
  4. 这适用于所有朋友,如果他们遇到类似的问题。从@Adam获取线索:

    1. 使用唯一键约束,正如他实现的那样。有关详细信息,请参阅注释。