我正在开发一个包含带多列sqlite表的应用程序,因此我们可以将项目添加到表中并显示在listview中,然后每个项目都有其自己的详细信息,这些详细信息可以显示在detail活动中,以及如何导出和导入sqlite表中的数据?

显示产品1

详细活动2

最佳答案

有几种不同的方法,但是这是我为自己制作的计步器应用程序做的方法。

首先,应编写所需的所有SQL查询,并将它们作为常量放入类中,以便以后可以轻松使用它们。

public class StepCountTable {

    private StepCountTable() {}

    public static final String CREATE_TABLE_SQL =
            "CREATE TABLE STEP_COUNT_BY_DATE" +
            "(" +
            "    ID             INTEGER PRIMARY KEY AUTOINCREMENT," +
            "    STEP_COUNT     INTEGER," +
            "    DAY            INTEGER" +
            ")";

    public static final String DROP_TABLE_SQL = "DROP TABLE IF EXISTS STEP_COUNT_BY_DATE";

    public static final String SELECT_ALL =
            "SELECT\n" +
            "    ID,\n" +
            "    STEP_COUNT,\n" +
            "    DAY\n" +
            "FROM\n" +
            "    STEP_COUNT_BY_DATE";

    public static final String SELECT_BY_ID =
            "SELECT\n" +
            "    ID\n" +
            "    STEP_COUNT\n" +
            "    DAY\n" +
            "FROM" +
            "   STEP_COUNT_BY_DATE\n" +
            "WHERE\n" +
            "   ID = ?"; // ? represents parameters to be added later

    public static final String SELECT_BY_DATE =
            "SELECT\n" +
            "    SUM(STEP_COUNT) SUM_STEP_COUNT,\n" +
            "    DAY\n" +
            "FROM\n" +
            "    STEP_COUNT_BY_DATE\n" +
            "GROUP BY \n" +
            "    DAY";

    public static final String SELECT_FROM_DATE =
            "SELECT \n" +
            "    SUM(STEP_COUNT) SUM_STEP_COUNT,\n" +
            "    DAY\n" +
            "FROM " +
            "    STEP_COUNT_BY_DATE\n" +
            "WHERE " +
            "    DAY >= ? AND " +
            "    DAY <= ? " +
            "GROUP BY \n" +
            "    DAY";

    public static final String INSERT =
            "INSERT INTO STEP_COUNT_BY_DATE" +
            "(" +
            "   STEP_COUNT," +
            "   DAY" +
            ")" +
            "VALUES" +
            "(" +
            "   ?," +
            "   ?" +
            ")";

    public static final String UPDATE =
            "UPDATE\n" +
            "    STEP_COUNT_BY_DATE\n" +
            "SET\n" +
            "    STEP_COUNT = ?,\n" +
            "    DAY = ?\n" +
            "WHERE\n" +
            "    ID = ?;";

    public static final String DELETE_ALL_BEFORE_DATE =
            "DELETE FROM\n" +
            "    STEP_COUNT_BY_DATE\n" +
            "WHERE\n" +
            "    DAY < ?;";

    public static final String DELETE_ALL = "DELETE FROM STEP_COUNT_BY_DATE";

    public static final String SELECT_ID_SQL = "SELECT last_insert_rowid()";
}


您还应该具有一个代表每个表的类,以存储从数据库检索的数据或要添加到数据库的数据。

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class StepCount {

    private long id;
    private Date date;
    private int stepCount;

    public StepCount(long id, int stepCount, Date date) {
        this.id = id;
        this.date = date;
        this.stepCount = stepCount;
    }

    public long getId() {
        return id;
    }

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

    public Date getDate() {
        return date;
    }

    public String getStringFormatedDate() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy", Locale.ENGLISH);
        return dateFormat.format(this.date);
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public int getStepCount() {
        return stepCount;
    }
}


之后,您需要该表的存储库,该存储库将处理执行每个查询的所有必要操作。

import java.util.List;

public interface Repository<T> {
    void create(T item);
    T readById(Long id);
    List<T> readAll();
    void update(T item);
    void delete();
}


import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

public class StepCountRepository implements Repository<StepCount> {
    private SQLiteDatabase database;

    public StepCountRepository(SQLiteDatabase pedometerDatabase) {
        this.database = pedometerDatabase;
    }

    @Override
    public void create(StepCount stepCount) {
        if (stepCount == null) {
            throw new IllegalArgumentException();
        }

        Calendar dateOfCreation = new GregorianCalendar();
        dateOfCreation.setTime(stepCount.getDate());
        dateOfCreation.set(Calendar.HOUR_OF_DAY, 0);
        dateOfCreation.set(Calendar.MINUTE, 0);
        dateOfCreation.set(Calendar.SECOND, 0);
        dateOfCreation.set(Calendar.MILLISECOND, 0);

        database.beginTransaction();

        Cursor cursor = null;
        try {
            cursor = database.rawQuery(StepCountTable.INSERT, new String[]{
                    Integer.toString(stepCount.getStepCount()),
                    Long.toString(dateOfCreation.getTimeInMillis())
            });

            cursor.moveToNext();
            cursor.close();

            cursor = database.rawQuery(StepCountTable.SELECT_ID_SQL, new String[]{});
            cursor.moveToNext();

            long id = cursor.getLong(0);
            stepCount.setId(id);

            database.setTransactionSuccessful();
        } catch (Exception e) {
            throw new SQLException("Unable to create stepCount.", e);
        } finally {
            if (cursor != null && !cursor.isClosed()) cursor.close();
        }

        database.endTransaction();
    }

    @Override
    public StepCount readById(Long id) {
        StepCount stepCount = null;

        try (Cursor cursor = database.rawQuery(
                StepCountTable.SELECT_BY_ID,
                new String[]{
                        String.valueOf(id)
                }
        )) {
            if (cursor.moveToNext()) {
                int count = cursor.getInt(cursor.getColumnIndex("STEP_COUNT"));
                Date date = new Date(cursor.getLong(cursor.getColumnIndex("DAY")));

                stepCount = new StepCount(id, count, date);
            }
        }
        return stepCount;
    }

    @Override
    public List<StepCount> readAll() {
        List<StepCount> stepCounts = new ArrayList<>();

        try (Cursor cursor = database.rawQuery(
                StepCountTable.SELECT_ALL,
                new String[]{}
        )) {
            while (cursor.moveToNext()) {
                long id = cursor.getLong(cursor.getColumnIndex("ID"));
                int count = cursor.getInt(cursor.getColumnIndex("STEP_COUNT"));
                Date date = new Date((cursor.getLong(cursor.getColumnIndex("DAY"))));

                stepCounts.add(new StepCount(id, count, date));
            }
        } catch (Exception e) {
            throw new SQLException("Unable to read stepCount", e);
        }

        return stepCounts;
    }

    public List<StepCount> readFromDate(Date dateFrom) {
        List<StepCount> stepCounts = new ArrayList<>();
        Date today = new Date();
        today.setSeconds(59);
        today.setMinutes(59);
        today.setHours(23);

        Calendar dateToReadFrom = new GregorianCalendar();
        dateToReadFrom.setTime(dateFrom);
        dateToReadFrom.set(Calendar.HOUR_OF_DAY, 0);
        dateToReadFrom.set(Calendar.MINUTE, 0);
        dateToReadFrom.set(Calendar.SECOND, 0);
        dateToReadFrom.set(Calendar.MILLISECOND, 0);

        try (Cursor cursor = database.rawQuery(
                StepCountTable.SELECT_FROM_DATE,
                new String[]{
                        Long.toString(dateToReadFrom.getTimeInMillis() + 1),
                        Long.toString(today.getTime())
                }
        )) {
            while (cursor.moveToNext()) {
                long id = -1L;
                int count = cursor.getInt(cursor.getColumnIndex("SUM_STEP_COUNT"));
                Date date = new Date((cursor.getLong(cursor.getColumnIndex("DAY"))));

                stepCounts.add(new StepCount(id, count, date));
            }
        } catch (Exception e) {
            throw new SQLException("Unable to read stepCount", e);
        }

        return stepCounts;
    }

    public List<StepCount> readAllByDate() {
        List<StepCount> stepCounts = new ArrayList<>();

        try (Cursor cursor = database.rawQuery(
                StepCountTable.SELECT_BY_DATE,
                new String[]{}
        )) {
            while (cursor.moveToNext()) {
                int count = cursor.getInt(cursor.getColumnIndex("SUM_STEP_COUNT"));
                Date date = new Date((cursor.getLong(cursor.getColumnIndex("DAY"))));

                stepCounts.add(new StepCount(0, count, date));
            }
        } catch (Exception e) {
            throw new SQLException("Unable to read stepCount", e);
        }

        return stepCounts;
    }

    @Override
    public void update(StepCount stepCount) {
        database.beginTransaction();

        Cursor cursor = null;
        try {
            cursor = database.rawQuery(StepCountTable.UPDATE, new String[]{
                    Integer.toString(stepCount.getStepCount()),
                    Long.toString(stepCount.getDate().getTime()),
                    Long.toString(stepCount.getId())
            });

            cursor.moveToNext();
            cursor.close();

            database.setTransactionSuccessful();
        } catch (Exception e) {
            throw new SQLException("Unable to update StepCount.", e);
        } finally {
            if (cursor != null && !cursor.isClosed()) cursor.close();
        }

        database.endTransaction();
    }

    @Override
    public void delete() {
        database.beginTransaction();

        try (Cursor cursor = database.rawQuery(
                StepCountTable.DELETE_ALL,
                new String[]{}
        )) {
            cursor.moveToNext();
            cursor.close();

            database.setTransactionSuccessful();
        } catch (Exception e) {
            throw new SQLException("Unable de delete StepCounts.", e);
        }

        database.endTransaction();
    }

    public void delete(Date date) {
        database.beginTransaction();

        Calendar dateToDeleteFrom = new GregorianCalendar();
        dateToDeleteFrom.setTime(date);
        dateToDeleteFrom.set(Calendar.HOUR_OF_DAY, 0);
        dateToDeleteFrom.set(Calendar.MINUTE, 0);
        dateToDeleteFrom.set(Calendar.SECOND, 0);
        dateToDeleteFrom.set(Calendar.MILLISECOND, 0);


        try (Cursor cursor = database.rawQuery(
                StepCountTable.DELETE_ALL_BEFORE_DATE,
                new String[]{
                        Long.toString(dateToDeleteFrom.getTimeInMillis())
                }
        )) {
            cursor.moveToNext();
            cursor.close();

            database.setTransactionSuccessful();
        } catch (Exception e) {
            throw new SQLException("Unable to delete StepCounts.", e);
        }

        database.endTransaction();
    }
}


要获得与数据库的连接,您将需要创建一个实现SQLiteOpenHelper的Factory类。

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class PedometerDatabaseFactory extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "Pedometer.db";
    private static final int DATABASE_VERSION = 1;

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

    @Override
    public void onCreate(SQLiteDatabase database) {
        database.execSQL(StepCountTable.CREATE_TABLE_SQL);
    }

    @Override
    public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
        database.execSQL(StepCountTable.DROP_TABLE_SQL);
        onCreate(database);
    }
}


现在,要使用它,您将在活动中执行类似的操作。

public class MainActivity extends AppCompatActivity {

    private PedometerDatabaseFactory pedometerDatabaseFactory;
    private StepCountRepository stepCountRepository;

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

        pedometerDatabaseFactory = new PedometerDatabaseFactory(this);
    }

    @Override
    protected void onStart() {
        super.onStart();

        stepCountRepository = new StepCountRepository(
                pedometerDatabaseFactory.getWritableDatabase()
        );
    }

    @Override
    protected void onStop() {
        super.onStop();

        pedometerDatabaseFactory.close();
    }
}


但是,您将需要在AsyncTasks中执行查询,因此您必须将存储库传递给AsyncTask。

主要活动:

private void fetchAllStepsCountByDate() {
    new FetchAllStepsCountByDateAsyncTask(
            this::onStepsCountByDateFound,
            this::OnNoAccessError,
            stepCountRepository
    ).execute();
}


FetchAllStepsCountByDateAsyncTask:

@Override
protected Promise<List<StepCount>, DatabaseError> doInBackground(Void... voids) {
    List<StepCount> stepCountDataSet;

    try {
        stepCountDataSet = stepCountRepository.readAllByDate();
        return Promise.ok(stepCountDataSet);

    } catch (Exception e) {
        return Promise.err(DatabaseError.NO_ACCESS);
    }
}

08-06 12:45