From 311f3e26524c3f9b8e60524b2e3f885283f549e9 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Sat, 25 Aug 2012 14:30:22 +0200 Subject: [PATCH] [#1657] Reorganise the manual (144 / 176) --- .../src/main/resources/manual-2.5.xml | 289 ++++++++++++++++-- 1 file changed, 258 insertions(+), 31 deletions(-) diff --git a/jOOQ-website/src/main/resources/manual-2.5.xml b/jOOQ-website/src/main/resources/manual-2.5.xml index 415888c5af..d831ef0482 100644 --- a/jOOQ-website/src/main/resources/manual-2.5.xml +++ b/jOOQ-website/src/main/resources/manual-2.5.xml @@ -4457,30 +4457,101 @@ create.fetch("SELECT * FROM BOOK WHERE ID = 5 AND TITLE = 'Animal Farm'");]]>

- Both of these methods are contained in jOOQ's internal API's , which is internally implemented by every QueryPart. QueryPart internals are best illustrated with an example. + Both of these methods are contained in jOOQ's internal API's , which is internally implemented by every QueryPart.

-

Example: CompareCondition

-

- A simple example can be provided by checking out jOOQ's internal representation of a (simplified) . It is used for any comparing two fields as for example the T_AUTHOR.ID = T_BOOK.AUTHOR_ID condition here: -

+

+ The following sections explain some more details about and , as well as other implementation details about QueryParts in general. +

+ + + +
+ SQL rendering + +

QueryParts and how they render SQL statements

+

+ Every must implement the method to render its SQL string to a . This RenderContext has two purposes: +

+
    +
  • It provides some information about the "state" of SQL rendering.
  • +
  • It provides a common API for constructing SQL strings on the context's internal
  • +
+

+ An overview of the API is given here: +

+ + + +

+ The following additional methods are inherited from a common , which is shared among and : +

+ + + +

An example of rendering SQL

+

+ A simple example can be provided by checking out jOOQ's internal representation of a (simplified) . It is used for any comparing two fields as for example the T_AUTHOR.ID = T_BOOK.AUTHOR_ID condition here: +

+ -- [...] FROM T_AUTHOR JOIN T_BOOK ON T_AUTHOR.ID = T_BOOK.AUTHOR_ID -- [...] -

- This is how jOOQ implements such a condition: -

+

+ This is how jOOQ renders such a condition: +

+}]]> -

- The following sections explain some more details about and , as well as other implementation details about QueryParts in general. -

-
- - -
- SQL rendering - +

+ See the manual's sections about and to learn about how to write your own query parts in order to extend jOOQ. +

+
Variable binding - + +

QueryParts and how they bind values to SQL statements

+

+ Every must implement the method. This BindContext has two purposes: +

+
    +
  • It provides some information about the "state" of the variable binding in process.
  • +
  • It provides a common API for binding values to the context's internal
  • +
+

+ An overview of the API is given here: +

+ + parts) throws DataAccessException; +BindContext bind(QueryPart[] parts) throws DataAccessException; + +// These methods perform the actual variable binding +BindContext bindValue(Object value, Class type) throws DataAccessException; +BindContext bindValues(Object... values) throws DataAccessException;]]> + +

+ Some additional methods are inherited from a common , which is shared among and . Details are documented in the previous chapter about +

+ +

An example of binding values to SQL

+

+ A simple example can be provided by checking out jOOQ's internal representation of a (simplified) . It is used for any comparing two fields as for example the T_AUTHOR.ID = T_BOOK.AUTHOR_ID condition here: +

+ +-- [...] +WHERE T_AUTHOR.ID = ? +-- [...] + +

+ This is how jOOQ binds values on such a condition: +

+ + +

+ See the manual's sections about and to learn about how to write your own query parts in order to extend jOOQ. +

+
- Custom QueryParts - + Extend jOOQ with custom types + +

Write your own QueryPart implementations

+

+ If a SQL clause is too complex to express with jOOQ, you can extend either one of the following types for use directly in a jOOQ query: +

+ + extends AbstractField {} +public abstract class CustomCondition extends AbstractCondition {} +public abstract class CustomTable> extends TableImpl {} +public abstract class CustomRecord> extends TableRecordImpl {}]]> + +

+ These classes are declared public and covered by jOOQ's integration tests. When you extend these classes, you will have to provide your own implementations for the and methods, as discussed before: +

+ + + +

+ The above contract may be a bit tricky to understand at first. The best thing is to check out jOOQ source code and have a look at a couple of QueryParts, to see how it's done. Here's an example showing how to create a field multiplying another field by 2 +

+ + IDx2 = new CustomField(BOOK.ID.getName(), BOOK.ID.getDataType()) { + @Override + public void toSQL(RenderContext context) { + + // In inline mode, render the multiplication directly + if (context.inline()) { + context.sql(BOOK.ID).sql(" * 2"); + } + + // In non-inline mode, render a bind value + else { + context.sql(BOOK.ID).sql(" * ?"); + } + } + + @Override + public void bind(BindContext context) { + try { + + // Manually bind the value 2 + context.statement().setInt(context.nextIndex(), 2); + + // Alternatively, you could also write: + // context.bind(Factory.val(2)); + } + catch (SQLException e) { + throw translate(getSQL(), e); + } + } +}; + +// Use the above field in a SQL statement: +create.select(IDx2).from(BOOK);]]> +
Plain SQL QueryParts - + +

Plain SQL as a simpler alternative to custom QueryParts

+

+ If you don't need the integration of rather complex QueryParts into jOOQ, then you might be safer using simple functionality, where you can provide jOOQ with a simple String representation of your embedded SQL. Plain SQL methods in jOOQ's API come in two flavours. +

+
    +
  • method(String, Object...): This is a method that accepts a SQL string and a list of bind values that are to be bound to the variables contained in the SQL string
  • +
  • method(String, QueryPart...): This is a method that accepts a SQL string and a list of QueryParts that are "injected" at the position of their respective placeholders in the SQL string
  • +
+

+ The above distinction is best explained using an example: +

+ + id = val(5); +Field title = val("Animal Farm"); +create.selectFrom(BOOK).where("BOOK.ID = {0} AND TITLE = {1}", id, title);]]> + +

+ The above technique allows for creating rather complex SQL clauses that are currently not supported by jOOQ, without extending any of the as indicated in the previous chapter. +

+
Serializability - + +

Attaching QueryParts

+

+ The only transient, non-serializable element in any jOOQ object is the underlying . When you want to execute queries after de-serialisation, or when you want to store/refresh/delete , you will have to "re-attach" them to a Factory +

+ + select = (Select) in.readObject(); + +// This will throw a DetachedException: +select.execute(); + +// In order to execute the above select, attach it first +Factory create = new Factory(connection, SQLDialect.ORACLE); +create.attach(select);]]> + +

Automatically attaching QueryParts

+

+ Another way of attaching QueryParts automatically, or rather providing them with a new at will, is to hook into the . More details about this can be found in the manual's chapter about +

+