- Java EE 8 High Performance
- Romain Manni Bucau
- 409字
- 2021-06-30 19:14:24
The service layer
The goal of the book being to discuss the performance and not how to write a Java EE application, we will not detail the whole service layer here. However, to ensure a common knowledge of what we are dealing with, we will illustrate the code with one service.
We are using JTA 1.2 with JPA 2.2 to establish a link between our database and the Java model. The QuoteService bean, responsible for managing the Quote persistence, can therefore look like the following:
@Transactional
@ApplicationScoped
public class QuoteService {
@PersistenceContext
private EntityManager entityManager;
public Optional<Quote> findByName(final String name) {
return entityManager.createQuery("select q from Quote q where
q.name = :name", Quote.class)
.setParameter("name", name)
.getResultStream()
.findFirst();
}
public Optional<Quote> findById(final long id) {
return Optional.ofNullable(entityManager.find(Quote.class, id));
}
public long countAll() {
return entityManager.createQuery("select count(q) from Quote
q", Number.class)
.getSingleResult()
.longValue();
}
public Quote create(final Quote newQuote) {
entityManager.persist(newQuote);
entityManager.flush();
return newQuote;
}
// ... other methods based on the same model
}
JPA may or may not be used in a transactional context, depending on the kind of operation you do. When you read data, you can often do it without any transaction until you need some lazy loading. However, when you write data (insert/update/delete entities), JPA requires a running transaction to be able to execute the action. This is to ensure consistency of data but also has some implications on the code. To respect that requirement, and have an active transaction, we use @Transactional on methods instead of relying on Enterprise Java Bean 3.2 (EJB 3.2), so we can reuse the power of CDI (@ApplicationScoped, for instance, which will avoid creating a new instance per injection).
Our finders are very simple and directly use the EntityManager API. The only new thing Java 8 brings us in this code is the ability to wrap the result with Optional which offers a programmatic way to deal with the presence or absense of the entity instead of relying on a null check. Concretely, the caller can use our finder this way:
final int quoteCount = getCustomer().getCountFor("myquote");
final double quotesPrice = quoteService.findByName("myquote")
.map(quote -> quote.getValue() * quoteCount)
.orElse(0);
This kind of code hides the conditional branches behind a fluent API, which makes it more expressive and readable, while the lambdas stay small enough.
Finally, we used inline queries in this code, not static ones like in the @NamedQuery API.
- Learning OpenDaylight
- Linux操作系統(tǒng)基礎(chǔ)
- Implementing Cisco UCS Solutions
- VMware Horizon View 6 Desktop Virtualization Cookbook
- SharePoint 2013 WCM Advanced Cookbook
- 高性能Linux服務(wù)器構(gòu)建實戰(zhàn):運維監(jiān)控、性能調(diào)優(yōu)與集群應(yīng)用
- 混沌工程:復(fù)雜系統(tǒng)韌性實現(xiàn)之道
- 新手學(xué)電腦從入門到精通(Windows 10+Office 2016版)
- Linux運維最佳實踐
- Mobile First Design with HTML5 and CSS3
- 嵌入式系統(tǒng)及其應(yīng)用(第三版)
- Android物聯(lián)網(wǎng)開發(fā)細致入門與最佳實踐
- 完美應(yīng)用RHEL 8
- 操作系統(tǒng)分析
- Linux操作系統(tǒng)