繁体   English   中英

具有多个表的 SQLite 数据库

[英]SQLite DB with multiple tables

我不断看到有关如何对多个表使用 DBHelper 的示例,但它们都具有在 DBHelper 类而不是每个数据类中定义的主题数据和查询。 这似乎是错误的,就像它没有保留关注点分离一样。 我可能误解了 DBHelper 的使用方式。 DBHelper 只拥有数据库的基础部分(如 Create),然后将单独的数据库功能(如“Insert”)放在每个主题类中(如 Book.insert、Author.insert 等),然后那些不是更好吗?可以使用 DBHelper。 在 DBHelper 中结合书籍和作者的数据库功能似乎是错误的。 有没有人有一个如何编码的例子,或者解释为什么没有必要? 提前致谢!

有没有人有一个如何编码的例子,或者解释为什么没有必要?

正如您所看到的示例,那么当它们起作用时,显然没有必要。

  • 事实上,当它归结为它时,DBHelper 不是必需的,因为它可以方便地检查数据库是否存在,如果不创建数据库并调用 onCreate,然后打开与数据库的连接(如果它存在或不存在)。

将扩展 SQliteOpenHelper(DBHelper)的所有内容组合到一个类中有一个小小的优势,即可以使用this.getWritableDatabase()检索 SQLiteDatabase,在构造函数中设置一个变量,在类级别声明可以进一步简化问题; 然后你可以简单地引用变量。

可以进行组合的另一个原因是,由于 SQLite 是一个关系数据库,因此关系会使分离变得过于复杂/混乱。 你在哪里放置处理tableA和tableB之间关系的代码,然后你在哪里放置tableA和tableC以及tableB和tableC之间关系的代码以及tableA,tableB,tableC代码...... .然后如果您有通用代码或实用程序代码怎么办。

如果使用单独的类,则需要传递 DBHelper 实例或 SQLite 数据库实例。

当有多个开发人员每个人都可以处理整体的较小组件时,使用单独的类就会发挥作用。

因此,对于回答有关 SO 的问题,组合具有明显的优势。

拆分 - 示例

DBHelper.java

/**
 * DBHelper
 */
@SuppressWarnings("WeakerAccess")
class DBHelper extends SQLiteOpenHelper {

    /**
     * Consrtuctor
     *
     * @param context activity context
     * @param name    database name
     * @param factory cursorfactory
     * @param version database version
     */
    DBHelper(Context context, @SuppressWarnings("SameParameterValue") String name, @SuppressWarnings("SameParameterValue") SQLiteDatabase.CursorFactory factory, @SuppressWarnings("SameParameterValue") int version) {
        super(context, name, factory, version);
    }

    /**
     * Instantiates a new Db helper.
     *
     * @param context the context
     */
    DBHelper(Context context) {
        super(context, DBConstants.DATABASE_NAME, null, 1);
    }

    private static DBHelper instance;

    /**
     * Gets helper.
     *
     * @param context the context
     * @return the helper
     */
    static synchronized DBHelper getHelper(Context context) {
        if(instance == null) {
            instance = new DBHelper(context);
        }
        return instance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        expand(db, false);
    }
    

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldversion, int newversion) {

    }

    public static void reopen(Context context) {
        instance = new DBHelper(context);
    }
}

但是,DBHelper 本身是通过DBDAO.java检索/构造/实例化的:-

public class DBDAO {

    /**
     * The Db.
     */
    private SQLiteDatabase db;
    private DBHelper dbhelper;
    @SuppressWarnings("unused")
    private Context mContext;
    public static final String THISCLASS = DBDAO.class.getSimpleName();
    private static final String LOGTAG = "SW_DBDAO";

    /**
     * DBAO Constructor
     *
     * @param context Context of the invoking method
     */
    public DBDAO(Context context) {
        
        this.mContext = context;
        dbhelper = DBHelper.getHelper(context);
        db = dbhelper.getWritableDatabase();
    }

    public SQLiteDatabase getDb() {
        return db;
    }

    /**
     * Gets table row count.
     *
     * @param tablename table to inspect
     * @return number of rows
     */
    public int getTableRowCount(String tablename) {

        Cursor csr = db.query(tablename,null,null,null,null,null,null);
        int rv = csr.getCount();
        csr.close();     
        return rv;
    }

    /**
     * getTableRows - generic get rows from a table
     *
     * @param table      Table name
     * @param joinclause Joing clause, if blank skipped
     * @param filter     Filter clause less WHERE, if blank skipped
     * @param order      Order clause less ORDER BY keywords, skipped if blank
     * @return Cursor with extracted rows, if any.
     */
    public Cursor getTableRows(String table, @SuppressWarnings("SameParameterValue") String joinclause, String filter, String order) {
       
        String sql = " SELECT * FROM " + table;
        if (joinclause.length() > 0 ) {
            sql = sql + joinclause;
        }
        if (filter.length() > 0 ) {
            sql = sql + " WHERE " + filter;
        }
        if (order.length() > 0) {
            sql = sql + " ORDER BY " + order;
        }
        sql = sql + " ;";
        return db.query(table + joinclause,null,filter,null,null,null,order);
    }
}

其中一张表是方法所在的Aisle

class DBAisleMethods {

    private Context context;
    private DBDAO dbdao;
    private static SQLiteDatabase db;
    private static long lastaisleadded;
    private static boolean lastaisleaddok = false;
    private static boolean lastaisleupdateok = false;
    private DBShopMethods dbshopmethods;
    public static final String THISCLASS = DBAisleMethods.class.getSimpleName();

    private final String[] dummyrowcolumns = new String[] {
            DBAislesTableConstants.AISLES_ID_COL,
            DBAislesTableConstants.AISLES_SHOPREF_COL,
            DBAislesTableConstants.AISLES_ORDER_COL,
            DBAislesTableConstants.AISLES_NAME_COL
    };
    private final MatrixCursor dummyrow = new MatrixCursor(dummyrowcolumns);

    /**
     * Instantiates a new Db aisle methods.
     *
     * @param ctxt the ctxt
     */
    DBAisleMethods(Context ctxt) {
        context = ctxt;
        dbdao = new DBDAO(context);
        db = dbdao.getDb();
        dbshopmethods = new DBShopMethods(context);
    }

    /**************************************************************************
     * getAisleCount - get the number of aisles
     *
     * @return number of Aisles
     */
    int getAisleCount() {
        return DBCommonMethods.getTableRowCount(db,
                DBAislesTableConstants.AISLES_TABLE
        );
    }


    /**************************************************************************
     * getLastAisleAdded - return the is of the last Aisle added
     *
     * @return id of the Aisle that was last added
     */
    @SuppressWarnings("unused")
    long getLastAisleAdded() {
        return lastaisleadded;
    }

    /**************************************************************************
     * ifAisleAdded - returns status of the last Aisle insert
     *
     * @return true if the last Aisle insert added the Aisle, else false
     */
    boolean ifAisleAdded() {
        return lastaisleaddok;
    }

    /**************************************************************************
     * insertAisle - add a new Aisle
     *
     * @param aislename name of the aisle
     * @param aislorder order of the aisle (within shop)
     * @param shopref   reference to the parent shop
     */
    void insertAisle(String aislename, int aislorder, long shopref) {

        long addedid;
        if (dbshopmethods.doesShopExist(shopref)) {
            ContentValues cv = new ContentValues();
            cv.put(DBAislesTableConstants.AISLES_NAME_COL, aislename);
            cv.put(DBAislesTableConstants.AISLES_ORDER_COL, aislorder);
            cv.put(DBAislesTableConstants.AISLES_SHOPREF_COL, shopref);
            addedid = db.insert(DBAislesTableConstants.AISLES_TABLE,
                    null,
                    cv);
            if (addedid > -1) {
                lastaisleadded = addedid;
                lastaisleaddok = true;

            }
        } else {
            lastaisleaddok = false;
        }
    }


    /**************************************************************************
     * @param aisleid    ID of the Aisle to modify
     * @param aisleorder new Aisle Order value (0 skips)
     * @param aislename  new Aisle Name value (blank skips)
     */
    void modifyAisle(long aisleid, int aisleorder, String aislename) {

        int updatecount = 0;
        ContentValues cv = new ContentValues();
        if (aisleorder > 0) {
            cv.put(DBAislesTableConstants.AISLES_ORDER_COL, aisleorder);
            updatecount++;
        }
        if (aislename.length() > 0) {
            cv.put(DBAislesTableConstants.AISLES_NAME_COL, aislename);
            updatecount++;
        }
        if (updatecount < 1) {
            return;
        }
        String[] whereargs = {Long.toString(aisleid)};
        String whereclause = DBAislesTableConstants.AISLES_ID_COL + " = ?";
        lastaisleupdateok = db.update(DBAislesTableConstants.AISLES_TABLE, cv, whereclause, whereargs) > 0;
    }

    /**************************************************************************
     * deleteAisle - Delete an Aisle and any children the aisle has
     * children could be :- productusage rows
     * shoplist rows
     * rule rows
     *
     * @param aisleid       id of the aisle to be deleted
     * @param intransaction true if already in a transaction
     */
    void deleteAisle(long aisleid, boolean intransaction) {

        @SuppressWarnings("unused") String sql;
        @SuppressWarnings("UnusedAssignment") int pudeletes = 0;
        @SuppressWarnings({"UnusedAssignment", "unused"}) int sldeletes = 0;
        @SuppressWarnings({"UnusedAssignment", "unused"}) int rdeletes = 0;
        @SuppressWarnings({"UnusedAssignment", "unused"}) int adelete = 0;

        if (doesAisleExist(aisleid)) {
            if (!intransaction) {
                db.beginTransaction();
            }

            //  Set whereargs string array to the aisleid as a string
            String[] whereargs = {Long.toString(aisleid)};
            // Delete ProductUsage rows that have Aisle as a parent
            pudeletes = db.delete(
                    DBProductusageTableConstants.PRODUCTUSAGE_TABLE,
                    DBProductusageTableConstants.PRODUCTUSAGE_AISLEREF_COL +
                            " = ?",
                    whereargs
            );
           
            // Delete Shopping List rows with Aisle as a parent
            //noinspection UnusedAssignment
            sldeletes = db.delete(
                    DBShopListTableConstants.SHOPLIST_TABLE,
                    DBShopListTableConstants.SHOPLIST_AISLEREF_COL +
                            " = ?",
                    whereargs
            );

            // Delete Rule rows with Aisle as a parent
            //noinspection UnusedAssignment
            rdeletes = db.delete(
                    DBRulesTableConstants.RULES_TABLE,
                    DBRulesTableConstants.RULES_AISLEREF_COL +
                            " = ?"
                    ,
                    whereargs);

            // Finally Delete the Aisle itself
            //noinspection UnusedAssignment
            adelete = db.delete(
                    DBAislesTableConstants.AISLES_TABLE,
                    DBAislesTableConstants.AISLES_ID_COL + " = ?",
                    whereargs);

            if (!intransaction) {
                db.setTransactionSuccessful();
                db.endTransaction();
            }
        }
    }

}

正如您从上述关系中看到的那样; Aisle 作为子项与 Shop 相关,Aisle 可能是 Product 的父项,ProductUsage 可能是 ShoppingList 的父项。

  • 这也是一个简化版本,为了简洁起见删除了其他方法。

在活动中使用上述内容的示例可能是(在其他代码中):-

    dbshopmethods = new DBShopMethods(this);
    dbaislemethods = new DBAisleMethods(this);

    slcsr = dbshopmethods.getShops("", shopsorderby);
    selectshoplistadapter = new AdapterShopList(this,
            slcsr,
            CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER,
            getIntent(),
            true, false, false);

    selectshoplist.setAdapter(selectshoplistadapter);
    setSelectShopListener();

    alcsr = dbaislemethods.getAisles(shopfilter,orderby,false);
    aislelistadapter = new AdapterAisleList(
            this,
            alcsr,
            CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER,
            getIntent(),
            false, false, false
    );
    aiselist.setAdapter(aislelistadapter);
    aislesadapterset = true;

    aiselist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView,
                                View view,
                                int position,
                                long id) {
            listItemClick(view, position, id);
        }
    });
    aiselist.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> adapterView, View view,
                                       int position,
                                       long id) {
            listItemLongClick(view, position,id);
            return true;
        }
    });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM