Start learning free

LESSON 121 OF 173 · BACKEND: SPEED

Measure First in Java

Practice

Before you make the shop faster, measure it: otherwise you can't tell whether a change really helped. In this module you measure the work a request does by counting its database queries. A count gives the same answer on every computer, while a time in milliseconds changes with the machine and with whatever else it is doing.

Every route in the shop asks the database through one of two helpers, runQuery for reading and runUpdate for changes, so those are the places to count: a wrapper that does its job and keeps score on the way. The score lives in a map field. The field is final, so it always holds the same map, but the values inside the map can still change. Here is the same idea on another value, a counter of visits:

private final Map<String, Integer> visits = new HashMap<>(Map.of("count", 0));

@GetMapping("/hello")
Map<String, Object> hello() {
    visits.put("count", visits.get("count") + 1);
    return Map.of("message", "Hi!", "visits", visits.get("count"));
}

To read the count, add a debug route: a tool for you, the developer, not a page for customers. The count only goes up, so read it before and after a request: the difference is what that request cost. Your code must give these answers, in this order:

GET /debug/queries  →  200  {"queries": 0}
GET /products/1  →  200  {"category": "kitchen", "id": 1, "name": "Mug", "price": 12, "stock": 10}
GET /debug/queries  →  200  {"queries": 1}
GET /customers/1/orders  →  200  [{"id": 1, "items": […], …}, {"id": 3, "items": […], …}]
GET /debug/queries  →  200  {"queries": 4}
GET /customers/5/orders  →  200  []
GET /debug/queries  →  200  {"queries": 5}

Customer 1's orders cost 3 queries: one for the orders, then one for the items of each of the 2 orders. Customer 5 has no orders, so only the first query runs. Reading the count is not a query, so it never counts itself.

Your task: add a field stats, a HashMap whose key "queries" starts at 0, make runQuery and runUpdate add 1 to it every time they run, and add a method showQueries for GET /debug/queries that returns stats, which Spring sends as JSON.


Assignment
Follow the Coding Tutorial to count every query in runQuery and runUpdate and show the count at GET /debug/queries.


Hint
The counting line goes first in both helpers. Map.of can't change, so copy it into a new HashMap<>(…); then put the key back with stats.get("queries") + 1 as its value.


STEP 1 OF 6
    Ctrl + Enter to check

    Speed Count Queries in Java

    Keep going with Java1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free