如何在Android数据库设置中使用事务

时间:2016-04-08 08:36:02

标签: android sqlite transactions

我有一个方法可以在SQLite数据库中执行大约400次插入,这需要几秒钟。我有红色,周围的插入与beginTransaction()和endTransaction()将优化它很多。但是我不明白怎么做,我现在尝试这样做的方式只会导致根本没有插入。请帮忙。

package com.example.oscar.strengthapp;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteStatement;

import java.util.ArrayList;

/**
 * Created by Oscar on 2016-01-09.
 */
public class WorkoutDB extends AbstractWorkoutDB{
    private static final WorkoutDB ourInstance = new WorkoutDB();
    private WorkoutDB() {}
    public static WorkoutDB getInstance() {
        return ourInstance;
    }

    public void beginTransaction(){
        database.beginTransaction();
    }
    public void endTransaction(){
        database.endTransaction();
    }
    public void insertExercise(int workoutID, String name, double weight, int sets, int reps){
        ContentValues values = new ContentValues();
        values.put(KEY_WORKOUT, workoutID);
        values.put(KEY_NAME, name);
        values.put(KEY_REPS, reps);
        values.put(KEY_SETS, sets);
        values.put(KEY_WEIGHT, weight);
        long rowId = database.insert(DB_TABLE_WORK, null, values);
    }

    public boolean updateExercise(Exercise exercise){
        ContentValues values = new ContentValues();
        values.put(KEY_WORKOUT, exercise.getWorkoutID());
        values.put(KEY_NAME, exercise.getName());
        values.put(KEY_REPS, exercise.getReps());
        values.put(KEY_SETS, exercise.getSets());
        values.put(KEY_WEIGHT, exercise.getWeight());
        return database.update(DB_TABLE_WORK, values, KEY_EXERCISE_ID +
                "=" + exercise.getExerciseID(), null) > 0;
    }

    public boolean deleteExercise(Exercise exercise){
        return database.delete(DB_TABLE_WORK, KEY_EXERCISE_ID +
                "=" + exercise.getExerciseID(), null) >0;
    }

    public void clearTable(){
        database.delete(DB_TABLE_WORK, null, null);
    }
    public ArrayList<Exercise> getAllExercises(){
        Cursor cr = getAllExercisesCursor();
        return makeExerciseListFromCursor(cr);
    }

    public ArrayList<Exercise> getWorkout(int id){
        Cursor cr = getWorkoutCursor(id);
        return makeExerciseListFromCursor(cr);
    }

    private ArrayList<Exercise> makeExerciseListFromCursor(Cursor cr){
        ArrayList<Exercise> exercises = new ArrayList<Exercise>();
        if(cr != null && cr.moveToFirst())
            do{
                exercises.add(new Exercise(cr.getLong(0), cr.getInt(1), cr.getString(2),
                        cr.getDouble(3), cr.getInt(4), cr.getInt(5)));
            }while (cr.moveToNext());
        return exercises;
    }

    protected void createTestData() {

        System.out.println("Inserting Test Data");
        WorkoutDB.getInstance().insertExercise(1, "Bench", 0.75, 5, 5);
        WorkoutDB.getInstance().insertExercise(1, "Squat", 0.75, 5, 5);
        WorkoutDB.getInstance().insertExercise(2, "Deadlift", 0.8, 3, 2);
        WorkoutDB.getInstance().insertExercise(2, "Squat", 0.75, 5, 5);
        WorkoutDB.getInstance().insertExercise(3, "Bench", 0.85, 3, 3);
        WorkoutDB.getInstance().insertExercise(3, "Squat", 0.85, 3, 3);
    }
}

package com.example.oscar.strengthapp;

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

/**
 * Created by Oscar on 2016-01-09.
 */
public abstract class AbstractWorkoutDB {
    public static final String DB_TABLE_WORK = "Work";
    public static final String KEY_EXERCISE_ID = "exerciseId";
    public static final String KEY_WORKOUT = "workoutId";
    public static final String KEY_NAME = "name";
    public static final String KEY_WEIGHT = "weight";
    public static final String KEY_REPS = "reps";
    public static final String KEY_SETS = "sets";
    public static final String TAG = "WorkoutDB";
    public static final String DB_NAME = "Workouts";
    protected SQLiteDatabase database;
    private static final String [] columns = {
            KEY_EXERCISE_ID,
            KEY_WORKOUT,
            KEY_NAME,
            KEY_WEIGHT,
            KEY_REPS,
            KEY_SETS};
    private static final int DB_VERSION = 1;
    private MyDbHelper mDbHelper;
    private Context context;

    private static final String DB_CREATE_WORK = "create table " +
            DB_TABLE_WORK + " (" +
            KEY_EXERCISE_ID + " INTEGER PRIMARY KEY, " +
            KEY_WORKOUT + " INTEGER, " +
            KEY_NAME + " TEXT, " +
            KEY_WEIGHT + " DOUBLE, " +
            KEY_SETS + " INTEGER, " +
            KEY_REPS + " INTEGER);";

    protected abstract void createTestData(); // must be implemented

    public void open(boolean writable, Context ctx) throws SQLException
    {
        this.context = ctx;
        mDbHelper = new MyDbHelper(context);
        if (writable)
        {
            database = mDbHelper.getWritableDatabase();
            if(mDbHelper.isFirstTime())
                System.out.println("is first time");
                //createTestData();
        }
        else
            database = mDbHelper.getReadableDatabase();
    }
    public void close()
    {
        mDbHelper.close();
    }


    protected Cursor getAllExercisesCursor()
    { // select * from song
        return database.query(DB_TABLE_WORK, columns, null, null, null, null, null);
    }
    protected Cursor getWorkoutCursor(int id){
        return database.query(
                DB_TABLE_WORK,
                columns,
                KEY_WORKOUT + "=?",
                new String[]{String.valueOf(id)},
                null, null, null, null);
    }

    protected static class MyDbHelper extends SQLiteOpenHelper // Local help class
    {
        private boolean firstTime = false;
        MyDbHelper(Context context)
        {
            super(context, DB_NAME, null, DB_VERSION);
        }
        public void onCreate(SQLiteDatabase sqldb) // called if needed
        {
            sqldb.execSQL(DB_CREATE_WORK);
            firstTime = true;
        }
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
        {
            db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE_WORK);
            onCreate(db);
        }
        public boolean isFirstTime()
        {
            return firstTime;
        }

    }
}

这就是我的方法看起来像巫婆做了一堆插入

public void initiate(String program, int length){
    SharedPreferences.Editor editor = prefs.edit();
    editor.putInt("CURRENT_WORKOUT", 1);
    editor.putString("CURRENT_PROGRAM", program);
    editor.putInt("CURRENT_LENGTH", length);
    editor.apply();
    WorkoutDB.getInstance().clearTable();
}
public void juggernaut(){
    initiate("Juggernaut Method", 112);
    WorkoutDB.getInstance().beginTransaction();
    WorkoutDB.getInstance().insertExercise(1, "Squat", 0.6, 5, 10);
    WorkoutDB.getInstance().insertExercise(1, "RDL", 0, 3, 12);
    WorkoutDB.getInstance().insertExercise(1, "Lunges", 0, 3, 20);
    WorkoutDB.getInstance().insertExercise(1, "Plank", 0, 3, 30);

    WorkoutDB.getInstance().insertExercise(2, "REST", 0, 0, 0);
    //and 400more of the same
    WorkoutDB.getInstance().endTransaction();
    }

3 个答案:

答案 0 :(得分:0)

您需要在setTransactionSuccessful()之前致电endTransaction(),以便提交更改。

答案 1 :(得分:0)

database.getWritableDatabase();(打开数据库命令)之后的开头,您调用

database.beginTransaction(); 

并在调用database.close();(关闭数据库命令)之前结束调用

database.setTransactionSuccessful();
database.endTransaction();

所以架构是这样的:

    database.getWritableDatabase();
    database.beginTransaction(); 

    //Insert, Update, Delete commands   

    database.setTransactionSuccessful();
    database.endTransaction();
    database.close();

答案 2 :(得分:0)

交易的标准惯用语记录在documentation

db.beginTransaction();
try {
  ...
  db.setTransactionSuccessful();
} finally {
  db.endTransaction();
}

单独调用setTransactionSuccessful()是必要的,以便异常绕过它并导致回滚。