使用包装类对sql语句声明
优质
小牛编辑
120浏览
2023-12-01
在第一部分,我描述如何使用包装类彻底简化代码编写。
例如,我们要在找到所有类型为“工人”,并为女性的蚂蚁。编写SQL语句是很容易的:
我们想用Android的代码来写这一点,SQL数据转换成有用信息:
String[] args = new String[2];
args[0] = "worker";
args[1] = "0";
Cursor cursor = db.rawQuery("SELECT * FROM Ant where type = ? AND isMale = ?", args);
final List<Ant> ants = new ArrayList<Ant>();
Ant ant;
if (cursor.moveToFirst()) {
do {
// get each column and then set it on each
ant = new Ant();
ant.setId(cursor.getLong(cursor.getColumnIndex("id")));
ant.setType(cursor.getString(cursor.getColumnIndex("type")));
ant.setIsMale(cursor.getInt(cursor.getColumnIndex("isMale") == 1);
ant.setQueenId(cursor.getLong(cursor.getColumnIndex("queen_id")));
ants.add(ant);
}
while (cursor.moveToNext());
}
这幺简短而亲切的简单的查询,但我们为什幺要继续写这些语句?
如果这样写会发生什幺呢:
- 我们添加或删除列的时候呢?
- 在其他表写这样的查询是否每次都要重复写这些代码?或者类似的查询页要重复写这些代码?
// main thread retrieval
List<Ant> devices = SQLite.select().from(Ant.class)
.where(Ant_Table.type.eq("worker"))
.and(Ant_Table.isMale.eq(false)).queryList();
// Async Transaction Queue Retrieval (Recommended for large queries)
SQLite.select()
.from(DeviceObject.class)
.where(Ant_Table.type.eq("worker"))
.and(Ant_Table.isMale.eq(false))
.async().queryList(transactionListener);
有许多操作在DBFlow得到支持:
- SELECT
- UPDATE
- INSERT
- JOIN
一个SELECT
语句从数据库中检索数据。我们通过检索数据
- 普通的在主线程中
Select
- 用
TransactionManager
运行一个Transaction
(建议用于大型查询).
// 查询一个List
SQLite.select().from(SomeTable.class).queryList();
SQLite.select().from(SomeTable.class).where(conditions).queryList();
//查询单个 Model
SQLite.select().from(SomeTable.class).querySingle();
SQLite.select().from(SomeTable.class).where(conditions).querySingle();
// 从一个表中查询一个list或游标(cursor)
SQLite.select().from(SomeTable.class).where(conditions).queryTableList();
SQLite.select().from(SomeTable.class).where(conditions).queryCursorList();
// 在ModelContainer查询!
SQLite.select().from(SomeTable.class).where(conditions).queryModelContainer(new MapModelContainer<>(SomeTable.class));
// 查询 methods
SQLite.select().distinct().from(table).queryList();
SQLite.select().from(table).queryList();
SQLite.select(Method.avg(SomeTable_Table.salary))
.from(SomeTable.class).queryList();
SQLite.select(Method.max(SomeTable_Table.salary))
.from(SomeTable.class).queryList();
// Transact a query on the DBTransactionQueue
TransactionManager.getInstance().addTransaction(
new SelectListTransaction<>(new Select().from(SomeTable.class).where(conditions),
new TransactionListenerAdapter<List<SomeTable>>() {
@Override
public void onResultReceived(List<SomeTable> someObjectList) {
// retrieved here
});
// Selects Count of Rows for the SELECT statment
long count = SQLite.selectCountOf()
.where(conditions).count();
// true for 'ASC', false for 'DESC'
SQLite.select()
.from(table)
.where()
.orderBy(Customer_Table.customer_id, true)
.queryList();
SQLite.select()
.from(table)
.where()
.orderBy(Customer_Table.customer_id, true)
.orderBy(Customer_Table.name, false)
.queryList();
SQLite.select()
.from(table)
.groupBy(Customer_Table.customer_id, Customer_Table.customer_name))
.queryList();
SQLite.select()
.from(table)
.limit(3)
.offset(2)
.queryList();
这里有2中更耐心数据库的方法:
- 调用
SQLite.update()
或者使用Update
类 - 运行
事务
使用事务管理器
(推荐线程安全的,但是看到的变化是异步)。
在本节中,我们将从数据库描述批量更新数据
在我们对前面蚂蚁的例子中,我们要改变我们目前所有的男性“worker”蚂蚁为“other”蚂蚁,因为他们偷懒不工作了。
From our earlier example on ants, we want to change all of our current male “worker” ants into “other” ants because they became lazy and do not work anymore.
UPDATE Ant SET type = 'other' WHERE male = 1 AND type = 'worker';
使用DBFlow:
// Native SQL wrapper
Where<Ant> update = SQLite.update(Ant.class)
.set(Ant_Table.type.eq("other"))
.where(Ant_Table.type.is("worker"))
.and(Ant_Table.isMale.is(true));
update.queryClose();
// TransactionManager (more methods similar to this one)
TransactionManager.getInstance().addTransaction(new QueryTransaction(DBTransactionInfo.create(BaseTransaction.PRIORITY_UI), update);
作为参考, (JOIN examples).
JOIN
语句能很好地结合很多一对多的关系。
如果查询返回非表字段,不能映射到现有的对象,
If your query returns non-table fields and cannot map to an existing object,
请参阅有关
例如,我们有一个表名为客户
,另一个名为预订
。
SELECT FROM `Customer` AS `C` INNER JOIN `Reservations` AS `R` ON `C`.`customerId`=`R`.`customerId`
// use the different QueryModel (instead of Table) if the result cannot be applied to existing Model classes.
List<CustomTable> customers = new Select()
.from(Customer.class).as("C")
.join(Reservations.class, JoinType.INNER).as("R")
.on(Customer_Table.customerId
.withTable(new NameAlias("C"))
.eq(Reservations_Table.customerId.withTable("R"))
.queryCustomList(CustomTable.class);
该 IProperty.withTable()
方法会在前面加上 NameAlias
或 Table
别名到 IProperty
查询, 方便连接查询:
SELECT EMP_ID, NAME, DEPT FROM COMPANY LEFT OUTER JOIN DEPARTMENT
ON COMPANY.ID = DEPARTMENT.EMP_ID
SQLite.select(Company_Table.EMP_ID, Company_Table.DEPT)
.from(Company.class)
.leftOuterJoin(Department.class)
.on(Company_Table.ID.withTable().eq(Department_Table.EMP_ID.withTable()))