Есть несколько разных методов, но вот как я это сделал для приложения шагомера, которое я сделал.
Сначала вы должны написать все 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();
}
}
Чтобы получить соединение с вашей базой данных, вам потребуется чтобы создать класс Factory, который реализует SQLiteOpenHelper.
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.
MainActivity:
private void fetchAllStepsCountByDate() {
new FetchAllStepsCountByDateAsyncTask(
this::onStepsCountByDateFound,
this::OnNoAccessError,
stepCountRepository
).execute();
}
FetchAllStepsCountByDateAsyncTask: * 102 8 *
@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);
}
}