speedment / jpa-streamer

JPAstreamer is a lightweight library for expressing JPA queries as Java Streams
GNU Lesser General Public License v2.1
344 stars 35 forks source link
java java-streams jpa orm

= JPAstreamer Per Minborg, Julia Gustafsson :toc: macro

image::https://github.com/speedment/speedment-resources/blob/master/src/main/resources/logo/JPAstreamer.png[alt="JPAstreamer Logo",width=600px, align=center]

image:https://maven-badges.herokuapp.com/maven-central/com.speedment.jpastreamer/jpastreamer-core/badge.svg[link="https://maven-badges.herokuapp.com/maven-central/com.speedment.jpastreamer/jpastreamer-core"] image:https://github.com/speedment/jpa-streamer/workflows/Java%20CI%20with%20Maven/badge.svg[link="https://github.com/speedment/jpa-streamer/actions"] image:https://img.shields.io/badge/License-LGPL%20v2.1-blue.svg[link="https://www.gnu.org/licenses/lgpl-2.1"] image:https://badges.gitter.im/Join%20Chat.svg[link="https://badges.gitter.im/Join%20Chat.svg)]

JPAstreamer is a lightweight extension for any JPA provider that allows creation of Java Streams from database content.With a single dependency, your application can immediately operate on database elements using standard Stream operators e.g. filter(), sort() and map().

The following example assumes there is an existing JPA Entity that represents a table containing films as follows:

[source, Java]

@Entity @Table(name = "film", schema = "sakila") public class Film implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "film_id", nullable = false, updatable = false, columnDefinition = "smallint(5)")
private Integer filmId;

@Column(name = "title", nullable = false, columnDefinition = "varchar(255)")
private String title;

@Column(name = "length", columnDefinition = "smallint(5)")
private Integer length;

@Column(name = "rating", columnDefinition = "enum('G','PG','PG-13','R','NC-17')")
private String rating;

}

To operate on the elements of the table, JPAstreamer is first initialized with a simple builder (in this case using a persistence unit named "sakila"):

[source, java]

JPAStreamer jpaStreamer = JPAStreamer.of("sakila");

The obtained streamer is then used to create Streams that are rendered to database queries through JPA. For example:

[source, java]

jpaStreamer.stream(Film.class) // Film.class is the @Entity representing the film-table .filter(Film$.rating.equal("G")) .sorted(Film$.length.reversed().thenComparing(Film$.title.comparator())) .skip(10) .limit(5) .forEach(System.out::println);

This will print films rated G in reversed length order (where films of equal length will be in title order) but skipping the first ten and then printing only the following five films.(Film$ is automatically generated from the Film-table Entity at compile-time by JPAstreamer).

In order to minimize the burden on the JVM and the database, JPAstreamer eventually renders the Stream to SQL like so (example from Hibernate/MySQL):

[source, roomsql]

select film0_.film_id as film_id11, film0_.description as descript21, film0_.language_id as languag111, film0_.last_update as last_upd31, film0_.length as length41, film0_.rating as rating51, film0_.rental_duration as rental_d61, film0_.rental_rate as rental_r71, film0_.replacement_cost as replacem81, film0_.special_features as special_91, film0_.title as title101 from film film0 where film0.rating=? order by film0.length desc, film0.title asc limit ?, ?

[source, text]

["G", 10, 5]

More examples are available in the JPAstreamer link:https://speedment.github.io/jpa-streamer/jpa-streamer/0.1.0/fetching-data/stream-examples.html[documentation].

== Install Since JPAstreamer acts merely as an API extension for existing JPA providers it requires minimal installation and configuration efforts. You only need to specify that the JPAstreamer dependency is required to compile your source code.

NOTE: JPAStreamer requires the use of Java 11 or later.

=== Maven In Maven, the following JPAstreamer dependency is added to the project's pom.xml-file.

[source, xml]

com.speedment.jpastreamer jpastreamer-core ${jpa-streamer-version} org.codehaus.mojo build-helper-maven-plugin 3.2.0 generate-sources add-source ${project.build.directory}/generated-sources/annotations

=== Gradle In Gradle, the following JPAstreamer dependency is added to the project's build.gradle-file (replace "version" with the latest JPAstremer version):

[source, groovy]

repositories { mavenCentral() }

dependencies { compile "com.speedment.jpastreamer:jpastreamer-core:version" annotationProcessor "com.speedment.jpastreamer:fieldgenerator-standard:version" }

/ Needed by some IDEs / sourceSets { main { java { srcDir 'src/main/java' srcDir 'target/generated-sources/annotations' } } }

=== Resources

== Contributing We gladly welcome any form of contributions, whether it is comments and questions, filed issues or pull requests.

Before we can accept your patches we need to establish a common legal ground to protect your rights to your contributions and the users of JPAstreamer. This is done by signing a Contributor License Agreement (link:https://github.com/speedment/jpa-streamer/blob/master/CONTRIBUTOR_LICENSE_AGREEMENT[CLA]) with Speedment, Inc. The details of this process is laid out link:https://github.com/speedment/jpa-streamer/blob/master/CONTRIBUTING.md[here].

== License JPAstreamer is released under the link:https://github.com/speedment/jpa-streamer/blob/master/LICENSE[LGPL 2.1 License].

== Short Video Here is a short 1-minute video describing JPAstreamer:

image::https://github.com/speedment/jpa-streamer/blob/develop/images/video-tn.png[width=50%,link="https://youtu.be/nfskjG4bvAg"]

== Contents toc::[]