Skip to content

Tutorial: A First Stream from Speedment

Dan Lawesson edited this page Sep 30, 2017 · 45 revisions

Tutorial: A First Stream from Speedment

This tutorial covers some basic stream operations in a Speedment application using data from the Sakila film database.

Step 1: Setup the database

The Sakila database can be downloaded here. Installation instructions are here.

Step 2: Create a new Maven project

As in previous tutorials, create a new Java 8 Maven project and the Speedment dependencies to the pom.xml-file. In the following we assume a MySQL database since the Sakila database linked above is MySQL.

<build>
    <plugins>
        ...
        <plugin>
            <groupId>com.speedment</groupId>
            <artifactId>speedment-maven-plugin</artifactId>
            <version>3.0.14</version>
        </plugin>
        ...
    </plugins>
</build>
<dependencies>
    ...
    <dependency>
        <groupId>com.speedment</groupId>
        <artifactId>runtime</artifactId>
        <version>3.0.14</version>
        <type>pom</type>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.42</version>
    </dependency>
    ...
</dependencies>

If needed, please see the Hello Speedment tutorial for pom.xml-files for other databases and for how to use the Speedment maven goals to generate Speedment code for the database.

Step 3: Write the application

Previous tutorials describe in detail how to set up a Speedment applcation. Basically, a simple example boils down to code of the following outline. First the app is built, then the Managers needed for the application logic are fetched from the app and finally, the app is stopped when the application logic is completed.

    public static void main(String... params) {
        SakilaApplication app = new SakilaApplicationBuilder()
            .withPassword("MyPassword")
            .build();

        FilmManager films = app.getOrThrow(FilmManager.class);
        ActorManager actors = app.getOrThrow(ActorManager.class);
        FilmActorManager filmActors = app.getOrThrow(FilmActorManager.class);

        // your application logic here

        app.stop();
    }

Step 4: Basic film lookup via primary key

The first part of the application logic of this tutorial finds films using the ID of the film. Arguably the most basic kind of lookup, the code for accomplishing this task is very straight forward; the stream of films is filtered on ID and then the films of the stream are mapped to the kind of descriptions we are looking for.

        Scanner scn = new Scanner(System.in);
        System.out.println("Please enter Film ID ");
        final int id = Integer.decode(scn.nextLine().trim());
        System.out.println("Film ID " + id + films.stream()
            .filter(Film.FILM_ID.equal(id))                    // find the films we are looking for
            .findAny()                                         // we know that ID is unique
            .map(f ->  " has title " + f.getTitle())           // map film instance to the desired output
            .orElse(" not found."));                           // provide meaningful output for no film found

Proper input validation is left out for clarity.

Step 5: Film lookup via actor name

A slightly more advanced use case of Speedment streams is to look for films featuring actors of a given last name. To achieve this, the application logic will be split in two parts. First we compute selectedActorIds, the actors with matching names. Then we filter the relation between films and actors in the actor IDs in question and finally map the items of the stream into the desired output format.

    System.out.println("Please enter actor last name ");
    final String actorName = scn.nextLine().trim();
    Set<Integer> selectedActorIds = actors.stream()
        .filter(Actor.LAST_NAME.equalIgnoreCase(actorName))  
        .mapToInt(Actor.ACTOR_ID.getter())                      // turning the stream into a stream of actor IDs
        .boxed()                                                // turning IntStream into Stream<Integer>
        .collect(toSet()); 

    if (selectedActorIds.isEmpty()) {
        System.out.println("No actor with last name " + actorName + " found.");
    } else {
        System.out.println("Films with actor with last name " + actorName + ":");
        filmActors.stream()
            .filter(FilmActor.ACTOR_ID.in(selectedActorIds))   
            .map(films.finderBy(FilmActor.FILM_ID))  // the stream of films we are looking for
            .map(Film.TITLE.getter())                // the stream of film titles
            .sorted()
            .forEach(title -> System.out.println(" " + title));
    }

Example output

The following is an example output from the application, where we look for Film ID 14 and then films featuring an actor names Akroyd.

Please enter Film ID 
14

Film ID 14 has title ALICE FANTASIA
Please enter actor last name 
Akroyd

Films with actor with last name Akroyd:
 APOLLO TEEN
 BACKLASH UNDEFEATED
 BETRAYED REAR
 BOULEVARD MOB
 BRAVEHEART HUMAN
 BUCKET BROTHERHOOD
 BUGSY SONG
 CAPER MOTIONS
 CASABLANCA SUPER
 CATCH AMISTAD
 CHANCE RESURRECTION
 CHARADE DUFFEL
 CLUB GRAFFITI
 CONFUSED CANDLES
 CUPBOARD SINNERS
 DANGEROUS UPTOWN
 DEVIL DESIRE
 DIVIDE MONSTER
 DOOM DANCING
 DOORS PRESIDENT
 DRIVER ANNIE
 FAMILY SWEET
 FEATHERS METAL
 FIRE WOLVES
 FLINTSTONES HAPPINESS
 FRISCO FORREST
 GALAXY SWEETHEARTS
 GLORY TRACY
 GRINCH MASSAGE
 HALF OUTFIELD
 HEDWIG ALTER
 HILLS NEIGHBORS
 HOLIDAY GAMES
 HOME PITY
 HOURS RAGE
 HOUSE DYNAMITE
 HURRICANE AFFAIR
 IMAGE PRINCESS
 INNOCENT USUAL
 ISHTAR ROCKETEER
 JAWBREAKER BROOKLYN
 LABYRINTH LEAGUE
 LEAGUE HELLFIGHTERS
 LUKE MUMMY
 MADIGAN DORADO
 MADNESS ATTACKS
 MAGIC MALLRATS
 MAGNOLIA FORRESTER
 MAIDEN HOME
 MAKER GABLES
 MAKER GABLES
 MASSAGE IMAGE
 MEMENTO ZOOLANDER
 MILLION ACE
 MONEY HAROLD
 MOURNING PURPLE
 NECKLACE OUTBREAK
 NUTS TIES
 OKLAHOMA JUMANJI
 OPERATION OPERATION
 OPPOSITE NECKLACE
 PATHS CONTROL
 PEAK FOREVER
 PIANIST OUTFIELD
 PILOT HOOSIERS
 PLUTO OLEANDER
 PRESIDENT BANG
 PRINCESS GIANT
 PRIVATE DROP
 RAIDERS ANTITRUST
 RANDOM GO
 REDEMPTION COMFORTS
 RESERVOIR ADAPTATION
 REUNION WITCHES
 SABRINA MIDNIGHT
 SINNERS ATLANTIS
 SKY MIRACLE
 SONG HEDWIG
 SPEAKEASY DATE
 SPIKING ELEMENT
 STAGECOACH ARMAGEDDON
 STEPMOM DREAM
 STREETCAR INTENTIONS
 SUBMARINE BED
 SUNDANCE INVASION
 TIES HUNGER
 USUAL UNTOUCHABLES
 VICTORY ACADEMY
 WORLD LEATHERNECKS
 WORST BANGER