Speedment是一个开源的、基于Java的、流式ORM工具包和运行时工具,它把对现有数据库和表的各种操作封装成Java 8的Stream操作。Speedment的新版本还提供了支持数据库事务处理的便捷操作方式。
Speedment在GitHub的地址:https://github.com/speedment/speedment
搜索时长大于120分钟的电影。
使用SQL查询:
SELECT
`film_id`, `title`, `description`, `release_year`, `language_id`,
`original_language_id`, `rental_duration`, `rental_rate`, `length`,
`replacement_cost`, `rating`, `special_features`, `last_update`
FROM
`sakila`.`film`
WHERE
(`length` > 120)
使用Speedment:
Optional<Film> longFilm = films.stream()
.filter(Film.LENGTH.greaterThan(120))
.findAny();
可见,使用Speedment无需手动编写SQL语句,而且代码更简洁。
本文讲述怎样学习使用开源的Speedment ORM工具和Java 8/9实现数据库的事务处理。
有时我们要确保我们的数据库操作是原子执行的,并且与其他数据库操作是相互隔离的。这就是事务处理发挥作用的地方。事务处理是一组操作建议,可以被数据库管理系统视为原子操作。因此,事物处理中的所有操作要么都被接受,要么都不接受。事务处理的另一个优点是事务处理开始时,数据库的状态将在本地“冻结”,所以在事务处理中我们不会看到其他线程的更新。
想象一下,假设我们正在填写一个银行账户操作的申请表,我们想从一个账户(1)转移100美元到另一个账户(2)。在这种情况下,最重要的是我们的钱不能丢失(也即从账户1中扣除了100美元,但却没存入账户2中),或者甚至更糟(即账户2存入了100美元但不是从账户1中扣除的金额,银行会找用户的麻烦)。遇到这种情况,我们可以使用如Speedment这样的数据库事务处理来保证安全:
txHandler.createAndAccept(tx ->
Account sender = accounts.stream()
.filter(Account.ID.equal(1))
.findAny()
.get();
Account receiver = accounts.stream()
.filter(Account.ID.equal(2))
.findAny()
.get();
accounts.update(sender.setBalance(sender.getBalance() - 100));
accounts.update(receiver.setBalance(receiver.getBalance() + 100));
tx.commit();
}
当调用tx.commit()方法时,两个更新将以原子操作的方式提交给数据库,并对其他所有线程可见。如果我们不显式调用tx.commit()方法,那么事务将自动回滚(即更新不会有任何影响,相关操作都被丢弃)。
在使用事务处理之前,我们需要获取一个TransactionHandler对象,比如这样:
BankApplication app = ....
TransactionComponent transactionComponent = app.getOrThrow(TransactionComponent.class);
TransactionHandler txHandler = transactionComponent.createTransactionHandler();
然后AccountManager可以从应用程序中检索,比如:
AccountManager accounts = app.getOrThrow(AccountManager.class);