我正在开发一个包含带多列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);
}
}