Android:如何编写自己的类而不是使用糖ORM

时间:2014-08-08 07:56:20

标签: android

我有五个类,每个类都有不同的字段名称。我通过扩展SugarRecord来存储和检索所有值。但我想扩展我的课而不是SugarRecord。我不知道如何为所有模态类编写公共类。我需要一些指导,从哪里开始编写代码。在这里,我发布了试图插入和检索的模态类。请帮我。提前谢谢。

作业类

public class assignments extends SugarRecord<assignments> {
public String valid;
public String pid;
public String event_added;
public String eid;
public String nature_of_contact;
public String assignment_date;
public String status;
public String aid;
public assignments(Context arg0) {
    super(arg0);
    // TODO Auto-generated constructor stub
}
}

要求等级

public class Requirement extends SugarRecord<Requirement> {
public String rid;
public String pid;
public String wid;
public String name;
public Requirement(Context arg0) {
    super(arg0);
    // TODO Auto-generated constructor stub
}
@Override
public String toString() {
    // TODO Auto-generated method stub
    return this.name;
}
}

如果我没有将SugarRecord用于我的模态类,那么我将为每个模态类编写单独的DBHelper类。就在这里,我在SugarRecord之前展示了我的代码。

public class DayExpensesDB extends SQLiteOpenHelper{
//Variable declaration
public static final String DATABASE_NAME = "DAYDB";
public static final String TABLE_NAME = "DAYTBL";
public static final int VERSION = 1;
public static final String ID = "id";
public static final String ENTERTAINMENT = "ENTERTAINMENT";
public static final String FOOD = "FOOD";
public static final String MEDICINE = "MEDICINE";
public static final String TRAVEL = "TRAVEL";
public static final String DATEVALUE ="DateValue";
public static final String TOTAL = "TOTAL";
public static Calendar cal = Calendar.getInstance();
public static final String CREATE_QUERY = "create table "+TABLE_NAME+" ("+ID+" INTEGER PRIMARY KEY AUTOINCREMENT, "+ENTERTAINMENT+" TEXT, "+FOOD+" TEXT, "+MEDICINE+" TEXT, "+TRAVEL+" TEXT, "+TOTAL+" TEXT, "+DATEVALUE+" DATETIME);";

public DayExpensesDB(Context context) {
    super(context, DATABASE_NAME, null, VERSION);
    // TODO Auto-generated constructor stub
}

@Override
public void onCreate(SQLiteDatabase db) {
    // TODO Auto-generated method stub
    db.execSQL(CREATE_QUERY);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub
    db.execSQL("DROP TABLE "+TABLE_NAME+" IF NOT EXISTS");
}
}

在DBHelper类中,我插入了DayExpensesDB类的所有值。 这是我的DBHelper类。

public class DBHelper {
SQLiteDatabase db;
DayExpensesDB dedb;
public DBHelper(Context context)
{
    dedb = new DayExpensesDB(context);
}
public SQLiteDatabase open()
{
    return dedb.getWritableDatabase();
}
public void close()
{
    dedb.close();
}
public void insertValues(double enter, double food, double medicine, double travel, double total, String date)
{
    db = this.open();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 
    date = dateFormat.format(new Date());
    ContentValues values = new ContentValues();
    values.put(DayExpensesDB.ENTERTAINMENT, enter);
    values.put(DayExpensesDB.FOOD, food);
    values.put(DayExpensesDB.MEDICINE, medicine);
    values.put(DayExpensesDB.TRAVEL, travel);
    values.put(DayExpensesDB.TOTAL, total);
    values.put(DayExpensesDB.DATEVALUE, date);
    db.insert(DayExpensesDB.TABLE_NAME, null, values);
    this.close();
}
public ArrayList<String> getValues()
{
    ArrayList<String> names = new ArrayList<String>();
    db = this.open();
    String query = "select * from "+DayExpensesDB.TABLE_NAME;
    Cursor cursor = db.rawQuery(query, null);
    if(cursor.moveToFirst())
    {
        do{
            names.add(cursor.getString(cursor.getColumnIndex(DayExpensesDB.ENTERTAINMENT)));
            names.add(cursor.getString(cursor.getColumnIndex(DayExpensesDB.FOOD)));
            names.add(cursor.getString(cursor.getColumnIndex(DayExpensesDB.MEDICINE)));
            names.add(cursor.getString(cursor.getColumnIndex(DayExpensesDB.TRAVEL)));
            names.add(cursor.getString(cursor.getColumnIndex(DayExpensesDB.DATEVALUE)));;
            names.add(cursor.getString(cursor.getColumnIndex(DayExpensesDB.TOTAL)));;
            names.add(cursor.getString(cursor.getColumnIndex(DayExpensesDB.TOTAL)));;
            //names.add(cursor.get)
        }while(cursor.moveToNext());
    }
    return names;

}

因此,如果我按照上面的编码,那么我需要为每个模态类(如Assignment和Requirement类)编写单独的DBHelper类。但我想写一个应该插入,保存和检索操作的公共类。

2 个答案:

答案 0 :(得分:2)

你可以在超类上扩展糖,并在子类中扩展该类:

class Person extends SugarRecord<Person>
....


class Customer extends Person
....

class Employee extends Person
....

这将创建表客户,员工和个人。客户和员工表也将包含所有人员字段。

答案 1 :(得分:1)

不确定如果我理解但这就是我要做的事 我会创造一个非常好的结构 首先,我最初会从你的班级DayExpensesDB中删除你放在那里的所有东西,成员。相反,我会从脚本创建我的数据库,一切都是OOP风格。 例。您为列创建了一个类,其中包含有关列的内容,它是主键,是或否?它是独特的还是不是?

修改
添加了从pastebin中删除的代码

//描述数据库列的类。

public class DatabaseColumnImpl implements DatabaseColumn {

    private boolean uniqueField = false;

    private boolean autoIncrement = false;

    private boolean isForeignKey = false;

    private boolean primaryKey = false;

    private String rowName;
    private RowType dataRowType;

     public GenericColumnImpl(boolean primaryKey, boolean autoIncrement, boolean uniqueField, boolean isForeignKey, String fieldName, @NonNull RowType type) {
        this.uniqueField = uniqueField;
        this.primaryKey = primaryKey;
        this.autoIncrement = autoIncrement;
        this.dataRowType = type;
        this.rowName = fieldName;
        this.isForeignKey = isForeignKey;
     }

     public DatabaseColumnImpl(boolean primaryKey, boolean autoIncrement, String fieldName, @NonNull RowType type) {
         this(primaryKey, autoIncrement, false, false, fieldName, type);
     }
    //... setters and getters
}

接下来,我将定义我的数据库合约和将要插入的行。例如,您的表格要求有4-5列,但尚未知道的行(请参见下图) http://gavo.mpa-garching.mpg.de/Millennium/images/databaseconcepts/table.png    
//每行数据库列。

  public enum DatabaseTable{

    DATA(new DatabaseColumnImpl(true, true, DataContract.X._ID, SqliteDataType.Integer),
        new DatabaseColumnImpl(DataContract.X.TIMEDURATION, SqliteDataType.Integer),
        new DatabaseColumnImpl(DataContract.X.DESCRIPTION, SqliteDataType.String),
        new DatabaseColumnImpl(DataContract.X.NAME, SqliteDataType.String));
  //much more data can be added here
   private DatabaseColumnImpl[] genericColumns;

   private DatabaseTable(DatabaseColumnImpl... columns) {
       this.genericColumns = columns;
   }

   public DatabaseColumnImpl[] getColumns() {
       return genericColumns;
   }

   public String getName() {
      return this.name();
   }
}

有了这些后,我会创建数据库合同的类。

public class DatabaseContract {
    public static final String CONTENT_STRING = "content://";

    public static final String CONTENT_AUTHORITY = "com.org.data";

    public static final String VND_AUTHORITY = "vnd.org.data";

    public static final Uri BASE_CONTENT_URI = Uri.parse(CONTENT_STRING + CONTENT_AUTHORITY);


    public static final class XData implements BaseColumns {

         public static final String TABLE_NAME = "xdata";

         //content://com.org.data/xdata
         public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(TABLE_NAME).build();

         //vnd.android.cursor.dir/vnd.org.data
         public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + File.separator + VND_AUTHORITY;

         //vnd.android.cursor.item/vnd.org.data
         public static final String CONTENT_ITEMTYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + File.separator + VND_AUTHORITY;

         public static final String NAME = "name";

         public static final String DESCRIPTION = "description";

         public static final String TIMEDURATION = "time_duration";
         //more data

    public static Uri buildXdataUri(long id) {
        return ContentUris.withAppendedId(CONTENT_URI, id);
    }
  }
}

一旦设置了上一个结构,查询就像这样:

 public class DatabaseOpenHelper extends SQLiteOpenHelper {

    private static final String DROP_START_QUERY = "DROP TABLE IF EXISTS ";
    /**
     * database name
     */
    public static final String DATABASE_NAME = "data.db";

    // default statements used for different queries
    public static final String PRIMARY_KEY_STATEMENT = " PRIMARY KEY ";
    public static final String PRIMARY_KEY_AUTOINCREMENT_STATEMENT = " PRIMARY KEY AUTOINCREMENT ";

    private static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS ";
    private static final String LEFT_PARENTHESES = "( \n";

    private static final String SPACE_CHARACTER = " ";
    private static final String CONFLICT_REPLACE_TEXT = ") ON CONFLICT IGNORE ";
    public static final String UNIQUE_KEY_STATEMENT = " UNIQUE (";
    // end of default queries

    private static final int DATABASE_VERSION = 19;
    public static final String COMMA_STRING = ",";
    public static final String EMPTY_STRING = "";
    public static final String TAB_STRING = "\n";

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

    @Override
    public void onCreate(SQLiteDatabase db) {
        createTables(db);
    }

    private void createTables(SQLiteDatabase db) {
        Collection<String> scripts = createScripts();
        for (String query : scripts) {
            db.execSQL(query);
        }
    }

    private Collection<String> createScripts() {
        Collection<String> scripts = new ArrayList<>();

        for (DatabaseTable table : DatabaseTable.values()) {
            String sqlQuery = CREATE_TABLE + table.getName() + LEFT_PARENTHESES;
            String primaryKeyQuery = getQueryScript(table);
            sqlQuery += primaryKeyQuery;
            sqlQuery += ")\n";
            scripts.add(sqlQuery);
        }
        return scripts;
    }

    private String getQueryScript(DatabaseTable table) {
        String query = "";
        for (int k = 0; k < table.getColumns().length; k++) {
            DatabaseColumn column = table.getColumns()[k];
            query += column.getFieldName() + SPACE_CHARACTER + column.getDataType().getRowType();
            if (column.isPrimaryKey() && column.isAutoIncremented()) {
                query += PRIMARY_KEY_AUTOINCREMENT_STATEMENT;
            } else if (column.isPrimaryKey()) {
                query += PRIMARY_KEY_STATEMENT;
            } else if (column.isUnique()) {
                query += UNIQUE_KEY_STATEMENT + column.getFieldName() + CONFLICT_REPLACE_TEXT;
            }
            query += (k == table.getColumns().length - 1 ? EMPTY_STRING : COMMA_STRING) + TAB_STRING;
        }
        return query;
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //drop tables
        List<String> dropScripts = createDropScripts();
        for (String query : dropScripts) {
            db.execSQL(query);
        }
    }

    /**
     * creates a list of all the drop table queries and update them
     * to a list so we can delete them in a simple way.
     *
     * @return array list containing the drop table queries.
     */
    private List<String> createDropScripts() {
        List<String> dropScripts = new ArrayList<>();
        DatabaseTable[] tables = DatabaseTable.values();
        for (DatabaseTable table : tables) {
            String query_script = DROP_START_QUERY + table.getName() + " ;";
            dropScripts.add(query_script);
        }
        return dropScripts;
     }
 }

接下来,我将创建一个界面,其中包含您要为每一行或ContentProvider使用的所有方法:
示例:插入,删除等

现在,基本上当我想进行插入,删除行时,使用内容提供程序将非常简单。

//数据应用程序的数据提供程序。

public class DataProvider extends ContentProvider {

    private static final String PATH_SEPARATOR_PROVIDER = "/#";

    private DatabaseOpenHelper databaseOpenHelper;

    private static UriMatcher buildUriMatcher() {

        final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
        //com.org.data
        final String authority = DatabaseContract.CONTENT_AUTHORITY;

        //com.org.data/xdata/0
        matcher.addURI(authority, DatabaseContract.XData.TABLE_NAME, UriType.DATA.ordinal());

        return matcher;
    }

    private static final UriMatcher sUriMatcher = buildUriMatcher();

    @Override
    public boolean onCreate() {
        databaseOpenHelper = new DatabaseOpenHelper(getContext());
        return true;
    }

    private UriType getUriType(Uri url) {
        int id = sUriMatcher.match(url);
        return UriType.values()[id];
    }

    @Nullable
    @Override
    public String getType(Uri uri) {
        // Use the Uri Matcher to determine what kind of URI this is.
        final UriType match = getUriType(uri);

        switch (match) {
            case DATA:
                return DatabaseContract.XData.CONTENT_TYPE;
            default:
                throw new UnsupportedOperationException("Unknown uri: " + uri);
        }
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        Cursor queryCursor;

        UriType match = getUriType(uri);
        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
        String sort;
        switch (match) {
            case DATA: {
                queryBuilder.setTables(DatabaseContract.XData.TABLE_NAME);
                sort = sortOrder == null ? DatabaseConstants.DEFAULT_ORDER_COLUMN : sortOrder;
                break;
            }   
            default:
                throw new UnsupportedOperationException("Query for data failed!");
        }

        queryCursor = queryBuilder.query(getDb(), projection, selection, selectionArgs, null, null, sort);
        queryCursor.setNotificationUri(getContentResolver(), uri);
        return queryCursor;
    }

    private SQLiteDatabase getDb() {
        return databaseOpenHelper.getReadableDatabase();
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        final SQLiteDatabase db = databaseOpenHelper.getWritableDatabase();
        final UriType match = getUriType(uri);
        Uri returnUri;
        try {
            db.beginTransaction();
            switch (match) {
                case DATA: {             
                    long _id = db.insert(DabaseContract.XData.TABLE_NAME, DabaseContract.XData._ID, values);
                    if (_id >= 0) {
                        returnUri = DabaseContract.XData.buildXDataUri(_id);
                    } else
                        throw new android.database.SQLException("Failed to insert row into " + uri);
                    break;
                }

                default:
                    throw new UnsupportedOperationException("Unknown uri: " + uri);
            }
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }
        notifyChange(returnUri);
        return returnUri;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        final SQLiteDatabase db = databaseOpenHelper.getWritableDatabase();
        final UriType match = getUriType(uri);
        int rowsDeleted;
        switch (match) {
            case DATA: {
                rowsDeleted = db.delete(DatabaseContract.XData.TABLE_NAME, selection, selectionArgs);
                break;
            }

            default:
                throw new UnsupportedOperationException("Unknown uri when trying to delete");
        }
        if (selection == null || rowsDeleted != 0) {
            notifyChange(uri);
        }
        return rowsDeleted;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        final SQLiteDatabase db = databaseOpenHelper.getWritableDatabase();
        final UriType match = getUriType(uri);
        int rowsUpdated;
        switch (match) {
            case DATA: {
                rowsUpdated = db.update(DatabaseContract.XData.TABLE_NAME, values, selection, selectionArgs);
                break;
            }

            default:
                throw new UnsupportedOperationException("Unknown uri when trying to delete");
        }
        if (rowsUpdated != 0) {
            notifyChange(uri);
        }
        return rowsUpdated;
    }

    @Override
    public int bulkInsert(Uri uri, ContentValues[] values) {
        final SQLiteDatabase db = databaseOpenHelper.getWritableDatabase();
        final UriType match = getUriType(uri);
        switch (match) {
            case DATA: {
                db.beginTransaction();
                int count = 0;
                try {
                    for (ContentValues value : values) {
                        long _id = db.insert(DatabaseContract.XData.TABLE_NAME, null, value);
                        if (_id != -1) {
                            count++;
                        }
                    }
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                }
                notifyChange(uri);
                return count;
            }
            default:
                return super.bulkInsert(uri, values);
        }
    }

    //used for testing more below:
    // http://developer.android.com/reference/android/content/ContentProvider.html#shutdown()
    @Override
    @TargetApi(11)
    public void shutdown() {
        databaseOpenHelper.close();
        super.shutdown();
    }

    private void notifyChange(Uri returnUri) {
        getContentResolver().notifyChange(returnUri, null);
    }

    private ContentResolver getContentResolver() {
        if (getContext() != null) {
            return getContext().getContentResolver();
        } else {
            return MyApplication.getInstance().getContentResolver();
        }
    }

    enum UriType {
        DATA
    }
}