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