The slides from Lukas Eder's jOOQ presentation at Topconf 2013.
The slides talk about the history of the Java and SQL integration, starting with JDBC, EJB 2.0, Hibernate, JPA, culminating in the claim that SQL is evolving in an entirely different direction than what is covered by Enterprise Java. This is where jOOQ comes in. jOOQ is currently the only platform in the Java market aiming at making SQL a first-class citizen in Java.
This website depicts what every CTO / software architect should consider at the beginning of every new Java project:
http://www.hibernate-alternative.com
This version of the presentation on Slideshare is licensed under the terms of the CC-BY-SA license 3.0:
http://creativecommons.org/licenses/by-sa/3.0
The jOOQ name, the jOOQ logo and the picture with the harbour worker are trademarks by Data Geekery GmbH. Please contact us if you want to use our trademarks in a derived presentation of yours.
contact@datageekery.com
1. Get Back in Control of your SQL
SQL and Java could work
together so much better if
we only let them.
Copyright (c) 2009-2013 by Data Geekery GmbH.
2. Intro
SQL and Java
jOOQ
Examples
About me
Java, SQL, PL/SQL
2001-2006 MSc Computer Science EPFL
2006-2009 Ergon Informatik AG, Zürich
2009-2013 Crealogix E-Banking AG, Zürich
2013 Adobe Systems Inc, Basel
2013
Data Geekery GmbH, Zürich
Copyright (c) 2009-2013 by Data Geekery GmbH.
3. Intro
SQL and Java
About my motivation
SQL dominates database systems
SQL seems «low level» and «dusty»
SQL can do so much more
SQL should be «sexy» again
Copyright (c) 2009-2013 by Data Geekery GmbH.
jOOQ
Examples
4. Intro
About today
History of SQL in Java
Persistence in Java today
jOOQ
jOOQ Examples
Copyright (c) 2009-2013 by Data Geekery GmbH.
SQL and Java
jOOQ
Examples
5. Intro
SQL and Java
jOOQ
SQL and Java - never ending story
JDBC
EJB 2.0 with EntityBeans
Hibernate / TopLink
EJB 3.0 with JPA 2.x
iBATIS / JDO / SpringData / 1’000 others
Copyright (c) 2009-2013 by Data Geekery GmbH.
Examples
6. Intro
SQL and Java
jOOQ
JDBC
PreparedStatement stmt = connection.prepareStatement(
"SELECT text FROM products WHERE cust_id = ? AND value < ?");
stmt.setInt(1, custID);
stmt.setBigDecimal(2, BigDecimal.ZERO);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("TEXT"));
}
Copyright (c) 2009-2013 by Data Geekery GmbH.
Examples
7. Intro
SQL and Java
JDBC – the naked truth
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
PreparedStatement stmt = connection.prepareStatement(
"SELECT p.text txt" +
(isAccount ? ", NVL(a.type, ?) " : "") +
"FROM products p " +
(isAccount ? " INNER JOIN accounts a USING (prod_id) " : "") +
" WHERE p.cust_id = ? AND p.value < ?" +
(isAccount ? " AND a.type LIKE '%" + type + "%'" : "");
stmt.setInt(1, defaultType);
stmt.setInt(2, custID);
stmt.setBigDecimal(3, BigDecimal.ZERO);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
Clob clob = rs.getClob("TEXT");
System.out.println(clob.getSubString(1, (int) clob.length());
}
rs.close();
stmt.close();
Copyright (c) 2009-2013 by Data Geekery GmbH.
jOOQ
Examples
8. Intro
SQL and Java
jOOQ
Examples
JDBC – the naked truth
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
PreparedStatement stmt = connection.prepareStatement(
//
"SELECT p.text txt" +
//
(isAccount ? ", NVL(a.type, ?) " : "") +
//
"FROM products p " +
// Syntax error when isAccount == false
(isAccount ? " INNER JOIN accounts a USING (prod_id) " : "") + //
" WHERE p.cust_id = ? AND p.value < ?" +
//
(isAccount ? " AND a.type LIKE '%" + type + "%'" : "");
// Syntax error and SQL injection possible
stmt.setInt(1, defaultType);
// Wrong bind index
stmt.setInt(2, custID);
//
stmt.setBigDecimal(3, BigDecimal.ZERO);
//
ResultSet rs = stmt.executeQuery();
//
while (rs.next()) {
Clob clob = rs.getClob("TEXT");
System.out.println(clob.getSubString(1, (int) clob.length());
}
//
// ojdbc6: clob.free() should be called
//
//
rs.close();
stmt.close();
// close() not really in finally block
//
Copyright (c) 2009-2013 by Data Geekery GmbH.
9. Intro
SQL and Java
jOOQ
Examples
JDBC – pros and cons
JDBC Pros
No restrictions (procedures, UDTs, vendor-specific features)
Simple
Fast
JDBC Cons
String-based
No syntax checking
Lots of code, flat / indexed variables
Repetitive
Vendor lock-in
Copyright (c) 2009-2013 by Data Geekery GmbH.
10. Intro
SQL and Java
EJB 2.0 EntityBeans
public interface CustomerRequest extends EJBObject {
BigInteger getId();
String getText();
void setText(String text);
@Override
void remove();
}
public interface CustomerRequestHome extends EJBHome {
CustomerRequest create(BigInteger id);
CustomerRequest find(BigInteger id);
}
Copyright (c) 2009-2013 by Data Geekery GmbH.
jOOQ
Examples
11. Intro
EJB 2.0 – the naked truth
<weblogic-enterprise-bean>
<ejb-name>com.example.CustomerRequestHome</ejb-name>
<entity-descriptor>
<pool>
<max-beans-in-free-pool>100</max-beans-in-free-pool>
</pool>
<entity-cache>
<max-beans-in-cache>500</max-beans-in-cache>
<idle-timeout-seconds>10</idle-timeout-seconds>
<concurrency-strategy>Database</concurrency-strategy>
</entity-cache>
<persistence>
<delay-updates-until-end-of-tx>True</delay-updates-until-end-of-tx>
</persistence>
<entity-clustering>
<home-is-clusterable>False</home-is-clusterable>
<home-load-algorithm>round-robin</home-load-algorithm>
</entity-clustering>
</entity-descriptor>
<transaction-descriptor/>
<enable-call-by-reference>True</enable-call-by-reference>
<jndi-name>com.example.CustomerRequestHome</jndi-name>
</weblogic-enterprise-bean>
Copyright (c) 2009-2013 by Data Geekery GmbH.
SQL and Java
jOOQ
Examples
12. Intro
SQL and Java
jOOQ
EJB 2.0 – pros and cons
EJB 2.0 Pros
Intuitive client code (create(), remove(), store())
Powerful (transactions, caching, etc.)
EJB 2.0 Cons
Not intuitive implementation (Home, conventions)
Lots of configuration
XDoclet
Checked Exceptions (FinderException, CreateException)
Repetitive (except with a code generator)
Domain Model depends on container
Copyright (c) 2009-2013 by Data Geekery GmbH.
Examples
13. Intro
SQL and Java
Hibernate – ORM
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(new Event("Conference", new Date());
session.save(new Event("After Party", new Date());
List result = session.createQuery("from Event").list();
for (Event event : (List<Event>) result) {
System.out.println("Event : " + event.getTitle());
}
session.getTransaction().commit();
session.close();
Copyright (c) 2009-2013 by Data Geekery GmbH.
jOOQ
Examples
14. Intro
SQL and Java
Hibernate – «navigation»
List result = session.createQuery("from Event").list();
for (Event event : (List<Event>) result) {
System.out.println("Participants of " + event);
for (Person person : event.getParticipants()) {
Company company = person.getCompany();
System.out.println(person + " (" + company + ")");
}
}
Copyright (c) 2009-2013 by Data Geekery GmbH.
jOOQ
Examples
15. Intro
SQL and Java
jOOQ
Hibernate – the naked truth
<hibernate-mapping package="org.hibernate.tutorial.hbm">
<class name="Event" table="EVENTS">
<id name="id" column="EVENT_ID">
<generator class="increment"/>
</id>
<property name="date" type="timestamp" column="EVENT_DATE"/>
<property name="title"/>
<set name="participants" inverse="true">
<key column="eventId"/>
<one-to-many entity-name="Person"/>
</set>
</class>
</hibernate-mapping>
Copyright (c) 2009-2013 by Data Geekery GmbH.
Examples
16. Intro
Hibernate – pros and cons
Hibernate Pros
Very intuitive client code (POJOs)
POJO code generator
Objects can be «navigated»
Hibernate implements JPA
Hibernate Cons
Hard to configure
Caching is complex
HQL is limited. SQL can do more.
ORM impedance mismatch
Copyright (c) 2009-2013 by Data Geekery GmbH.
SQL and Java
jOOQ
Examples
17. Intro
SQL and Java
jOOQ
JPA and EJB 3.0
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
em.persist(new Event("Conference", new Date());
em.persist(new Event("After Party", new Date());
List result = em.createQuery("from Event").getResultList();
for (Event event : (List<Event>) result) {
System.out.println("Event : " + event.getTitle());
}
em.getTransaction().commit();
em.close();
Copyright (c) 2009-2013 by Data Geekery GmbH.
Examples
18. Intro
SQL and Java
jOOQ
EJB 3.0 – the naked truth
@Entity @Table(name = "EVENTS")
public class Event {
private Long id;
private String title;
private Date date;
@Id @GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
public Long getId() { /* … */ }
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "EVENT_DATE")
public Date getDate() { /* … */ }
Copyright (c) 2009-2013 by Data Geekery GmbH.
Examples
19. Intro
SQL and Java
jOOQ
Examples
Criteria – the naked truth
EntityManager em= ...
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Person> criteria = builder.createQuery(Person.class);
Root<Person> person = criteria.from(Person.class);
Predicate condition = builder.gt(person.get(Person_.age), 20);
criteria.where(condition);
TypedQuery<Person> query = em.createQuery(query);
List<Person> result = query.getResultList();
Copyright (c) 2009-2013 by Data Geekery GmbH.
20. Intro
SQL and Java
jOOQ
JPA – pros and cons
JPA Facts
Hibernate HQL => JPQL
Hibernate XML mapping => annotations
Hibernate Sessions => EntityManager
JPA Pros
Next standard after EJB 2.0
Good implementations, such as Hibernate, EclipseLink
JPA Cons
CriteriaQuery
Copyright (c) 2009-2013 by Data Geekery GmbH.
Examples
21. Intro
SQL and Java
jOOQ
What else is there?
iBATIS / MyBatis
XML based. SQL is externalised
Active, but seems to be at the end of its hype cycle
JDO
Has JDOQL (similar to HQL, JPQL)
Supports also NoSQL stores
Is pretty dead
Spring JDBC, Apache DbUtils, etc
Ease *some* of the JDBC pain
Copyright (c) 2009-2013 by Data Geekery GmbH.
Examples
22. Intro
SQL and Java
jOOQ
Examples
SQL is so much more
|
TEXT | VOTES |
RANK | PERCENT |
|-------------|-------|------------|---------|
|
Hibernate |
138 |
1 |
32 % |
|
jOOQ |
102 |
2 |
23 % |
| EclipseLink |
88 |
3 |
20 % |
|
JDBC |
53 |
4 |
12 % |
| Spring JDBC |
45 |
5 |
10 % |
Copyright (c) 2009-2013 by Data Geekery GmbH.
23. Intro
SQL and Java
jOOQ
SQL is so much more
SELECT
p.text,
p.votes,
DENSE_RANK() OVER (ORDER BY p.votes DESC) AS "rank",
LPAD(
(p.votes * 100 / SUM(p.votes) OVER ()) || ' %',
4, ' '
) AS "percent"
FROM
poll_options p
WHERE
p.poll_id = 12
ORDER BY p.votes DESC
Copyright (c) 2009-2013 by Data Geekery GmbH.
Examples
24. Intro
SQL and Java
jOOQ
The same with jOOQ
select (p.TEXT,
p.VOTES,
denseRank().over().orderBy(p.VOTES.desc()).as("rank"),
lpad(
p.VOTES.mul(100).div(sum(p.VOTES).over()).concat(" %"),
4, " "
).as("percent"))
.from
(POLL_OPTIONS.as("p"))
.where (p.POLL_ID.eq(12))
.orderBy(p.VOTES.desc());
Copyright (c) 2009-2013 by Data Geekery GmbH.
Examples
25. Intro
SQL and Java
jOOQ
The same with jOOQ in Scala (!)
select (p.TEXT,
p.VOTES,
denseRank() over() orderBy(p.VOTES desc) as "rank",
lpad(
(p.VOTES * 100) / (sum(p.VOTES) over()) || " %",
4, " "
) as "percent")
from
(POLL_OPTIONS as "p")
where
(p.POLL_ID === 12)
orderBy (p.VOTES desc)
Copyright (c) 2009-2013 by Data Geekery GmbH.
Examples