【问题标题】:A more efficient way to write database CRUD operations in Android在 Android 中编写数据库 CRUD 操作的更有效方法
【发布时间】:2018-01-09 13:31:36
【问题描述】:

我刚刚开始学习 Android 开发,我发现了一种在我的应用程序中编写模型、DAO 和模式的非常好的方法。例如,我有一个Category 模型,其中将包含代表其表在数据库中的列的所有字段:

public class Category {
    private int id;
    private String name;
    private String createdAt;

    // Getters and Setters
}

CategoryDao 类将响应访问数据库并执行所有操作:

package com.prettypenny.dao;

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

import com.prettypenny.model.Category;
import com.prettypenny.schema.CategorySchema;
import com.prettypenny.schema.DatabaseHandler;

import java.util.ArrayList;

/**
 * Category D.A.O
 */
public class CategoryDao {
    SQLiteOpenHelper helper;
    SQLiteDatabase database;

    private static final String[] columns = {
        CategorySchema.COL_ID,
        CategorySchema.COL_NAME,
        CategorySchema.COL_CREATED_AT,
    };

    public CategoryDao(Context context) {
        helper = new DatabaseHandler(context);
    }

    public void open() {
        database = helper.getWritableDatabase();
    }

    public void close() {
        helper.close();
    }

    /**
     * Retrieve all Category
     * @return ArrayList
     */
    public ArrayList<Category> all() {
        Cursor cursor = database.query(CategorySchema.TABLE_NAME, columns, null, null, null, null, null);

        ArrayList<Category> categories = new ArrayList<>();

        if (cursor.getCount() > 0) {
            while (cursor.moveToNext()) {
                Category category = new Category();
                category.setId(cursor.getInt(cursor.getColumnIndex(CategorySchema.COL_ID)));
                category.setName(cursor.getString(cursor.getColumnIndex(CategorySchema.COL_NAME)));

                categories.add(category);
            }
        }

        return categories;
    }

    /**
     * Inserts a new Category
     * @param category Category category to be inserted
     * @return Category
     */
    public Category insert(Category category) {
        ContentValues values = new ContentValues();
        values.put(CategorySchema.COL_NAME, category.getName());

        database.insert(CategorySchema.TABLE_NAME, null, values);

        return category;
    }

    /**
     * Updates an existing Category
     * @param category Category category to be updated
     * @return int
     */
    public int update(Category category) {
        ContentValues values = new ContentValues();
        values.put(CategorySchema.COL_NAME, category.getName());

        return database.update(
            CategorySchema.TABLE_NAME,
            values,
            CategorySchema.COL_ID + " = ?",
            new String[] { String.valueOf(category.getId()) }
        );
    }

    /**
     * Deletes an existing Category
     * @param id int id of the category to be deleted
     */
    public void delete(int id) {
        database.delete(
            CategorySchema.TABLE_NAME,
            CategorySchema.COL_ID + " = " + id,
            null
        );
    }
}

但是当我在我的应用程序中创建越来越多的实体时,我觉得必须输入所有这些相同的东西很麻烦,所以我想创建一个抽象类Dao,它将包含所有这些操作并且这些类只会扩展它。

abstract class Dao {
    SQLiteOpenHelper helper;
    SQLiteDatabase database;

    public ArrayList<?> all(String tableName, String[] columns) {
        Cursor cursor = database.query(tableName, columns, null, null, null, null, null);

        ArrayList<?> entities = new ArrayList<>();

        if (cursor.getCount() > 0) {
            while (cursor.moveToNext()) {
                // Oh shit.
            }
        }

        return entities;
    }
}

现在的问题,例如在all() 方法中是要实例化的模型类,如在CategoryDao.all() 中实例化Category。是否有可能在抽象类中实现,比如说,做类似ArrayList&lt;?&gt; 的事情,它传递可能是任何类型的东西?

【问题讨论】:

  • 是否可以选择使用一些 ORM,甚至是另一个便于实施的数据库?我有一些建议。
  • 我从没想过使用ORM,其实不知道有。但我实际上想知道我的问题,如果这可能的话,而且,让我更多地学习 Java。
  • ORM 是对象关系映射。它们是便于将实体作为对象进行管理的库。对于 Java EE,最流行的是 Hibernate。
  • 搜索android ROOM
  • 如果你不想使用 ORM,你可以通过反射来做到这一点,我认为这就是 ORM 的工作方式,所以你将重新发明轮子,但作为实验,它可能是一个很好的运动

标签: java android crud dao


【解决方案1】:

我建议您看看 Google 的房间方法。它仍然不稳定,您需要仍然不稳定的 android studio 3.0,但我没有注意到其中任何一个问题。

https://codelabs.developers.google.com/codelabs/android-persistence/#0

与典型替代方案相比,它具有非常有趣的优势,其中之一是在编译时检查您的 SQL 语句是否与您的数据库匹配。我不知道有其他人提供此特定功能。

【讨论】:

    【解决方案2】:

    使用任何语言的数据库时,最大的挑战之一是数据库表和实体对象之间的关系映射。

    考虑一下,创建了称为 ORM(对象关系映射)的库/框架。

    我的第一个建议是使用Realm Database,但由于您已经使用 SQLite,我的列表是:

    他们之间的比较可以找到herehere

    【讨论】:

    • 好吧,有很多选择。我想通过反射来实现我的想法,以更多地了解 Java 语言本身。谢谢。
    • 对 Android 的反射要小心。反射是缓慢且昂贵的。通常,在 Android 中,ORM 使用代码生成来避免使用反射。祝你学习顺利。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-28
    • 2019-09-06
    • 1970-01-01
    • 2019-10-16
    • 1970-01-01
    • 2012-07-05
    相关资源
    最近更新 更多