updating code examples with generics/varargs; polishing
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@1136 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
01e336dd5b
commit
79aae9dde9
|
|
@ -8,11 +8,11 @@
|
||||||
<title>Introduction</title>
|
<title>Introduction</title>
|
||||||
|
|
||||||
<para>The Data Access Object (DAO) support in Spring is aimed at making it
|
<para>The Data Access Object (DAO) support in Spring is aimed at making it
|
||||||
easy to work with data access technologies like JDBC, Hibernate or JDO in
|
easy to work with data access technologies like JDBC, Hibernate, JPA or
|
||||||
a consistent way. This allows one to switch between the aforementioned
|
JDO in a consistent way. This allows one to switch between the
|
||||||
persistence technologies fairly easily and it also allows one to code
|
aforementioned persistence technologies fairly easily and it also allows
|
||||||
without worrying about catching exceptions that are specific to each
|
one to code without worrying about catching exceptions that are specific
|
||||||
technology.</para>
|
to each technology.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="dao-exceptions">
|
<section id="dao-exceptions">
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||||
|
|
||||||
<chapter id="jdbc">
|
<chapter id="jdbc">
|
||||||
<title>Data access using JDBC</title>
|
<title>Data access using JDBC</title>
|
||||||
|
|
||||||
|
|
@ -73,8 +72,8 @@
|
||||||
<para><emphasis role="bold">JdbcTemplate</emphasis> - this is the
|
<para><emphasis role="bold">JdbcTemplate</emphasis> - this is the
|
||||||
classic Spring JDBC approach and the most widely used. This is the
|
classic Spring JDBC approach and the most widely used. This is the
|
||||||
"lowest level" approach and all other approaches use a JdbcTemplate
|
"lowest level" approach and all other approaches use a JdbcTemplate
|
||||||
under the covers. Works well in a JDK 1.4 and higher
|
under the covers. In Spring 3.0 it has been updated with Java 5
|
||||||
environment.</para>
|
support like generics and vararg support. </para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
@ -82,16 +81,17 @@
|
||||||
wraps a JdbcTemplate to provide more convenient usage with named
|
wraps a JdbcTemplate to provide more convenient usage with named
|
||||||
parameters instead of the traditional JDBC "?" place holders. This
|
parameters instead of the traditional JDBC "?" place holders. This
|
||||||
provides better documentation and ease of use when you have multiple
|
provides better documentation and ease of use when you have multiple
|
||||||
parameters for an SQL statement. Works with JDK 1.4 and up.</para>
|
parameters for an SQL statement. It has also been updated with Java
|
||||||
|
5 support like generics and vararg support for Spring 3.0.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para><emphasis role="bold">SimpleJdbcTemplate</emphasis> - this
|
<para><emphasis role="bold">SimpleJdbcTemplate</emphasis> - this
|
||||||
class combines the most frequently used features of both
|
class combines the most frequently used features of both
|
||||||
JdbcTemplate and NamedParameterJdbcTemplate plus it adds additional
|
JdbcTemplate and NamedParameterJdbcTemplate plus it adds additional
|
||||||
convenience by taking advantage of some Java 5 features like
|
convenience by taking better advantage of Java 5 varargs for
|
||||||
varargs, autoboxing and generics to provide an easier to use API.
|
ceratain methods where this wasn't possible in the JdbcTemplate due
|
||||||
Requires JDK 5 or higher.</para>
|
to backwars compatibility reasons.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
@ -101,8 +101,8 @@
|
||||||
simplify the coding to a point where you only need to provide the
|
simplify the coding to a point where you only need to provide the
|
||||||
name of the table or procedure and provide a Map of parameters
|
name of the table or procedure and provide a Map of parameters
|
||||||
matching the column names. Designed to work together with the
|
matching the column names. Designed to work together with the
|
||||||
SimpleJdbcTemplate. Requires JDK 5 or higher and a database that
|
SimpleJdbcTemplate. Requires a database that provides adequate
|
||||||
provides adequate metadata.</para>
|
metadata.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
@ -112,8 +112,9 @@
|
||||||
your data access layer. This approach is modeled after JDO Query
|
your data access layer. This approach is modeled after JDO Query
|
||||||
where you define your query string, declare parameters and compile
|
where you define your query string, declare parameters and compile
|
||||||
the query. Once that is done any execute methods can be called
|
the query. Once that is done any execute methods can be called
|
||||||
multiple times with various parameter values passed in. Works with
|
multiple times with various parameter values passed in. It has also
|
||||||
JDK 1.4 and higher.</para>
|
been updated with Java 5 support like generics and vararg support
|
||||||
|
for Spring 3.0.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -231,48 +232,48 @@
|
||||||
<para>A simple query for getting the number of rows in a
|
<para>A simple query for getting the number of rows in a
|
||||||
relation.</para>
|
relation.</para>
|
||||||
|
|
||||||
<programlisting language="java">int rowCount = this.jdbcTemplate.queryForInt("select count(0) from t_accrual");</programlisting>
|
<programlisting language="java"><![CDATA[int rowCount = this.jdbcTemplate.queryForInt("select count(*) from t_actor");]]></programlisting>
|
||||||
|
|
||||||
<para>A simple query using a bind variable.</para>
|
<para>A simple query using a bind variable.</para>
|
||||||
|
|
||||||
<programlisting language="java">int countOfActorsNamedJoe = this.jdbcTemplate.queryForInt(
|
<programlisting language="java"><![CDATA[int countOfActorsNamedJoe = this.jdbcTemplate.queryForInt(
|
||||||
"select count(0) from t_actors where first_name = ?", new Object[]{"Joe"});</programlisting>
|
"select count(*) from t_actor where first_name = ?", "Joe");]]></programlisting>
|
||||||
|
|
||||||
<para>Querying for a <classname>String</classname>.</para>
|
<para>Querying for a <classname>String</classname>.</para>
|
||||||
|
|
||||||
<programlisting language="java">String surname = (String) this.jdbcTemplate.queryForObject(
|
<programlisting language="java"><![CDATA[String surname = this.jdbcTemplate.queryForObject(
|
||||||
"select surname from t_actor where id = ?",
|
"select surname from t_actor where id = ?",
|
||||||
new Object[]{new Long(1212)}, String.class);</programlisting>
|
new Object[]{1212L}, String.class);]]></programlisting>
|
||||||
|
|
||||||
<para>Querying and populating a <emphasis>single</emphasis> domain
|
<para>Querying and populating a <emphasis>single</emphasis> domain
|
||||||
object.</para>
|
object.</para>
|
||||||
|
|
||||||
<programlisting language="java">Actor actor = (Actor) this.jdbcTemplate.queryForObject(
|
<programlisting language="java"><![CDATA[Actor actor = this.jdbcTemplate.queryForObject(
|
||||||
"select first_name, surname from t_actor where id = ?",
|
"select first_name, surname from t_actor where id = ?",
|
||||||
new Object[]{new Long(1212)},
|
new Object[]{1212L},
|
||||||
new RowMapper() {
|
new RowMapper<Actor>() {
|
||||||
|
public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
|
Actor actor = new Actor();
|
||||||
Actor actor = new Actor();
|
actor.setFirstName(rs.getString("first_name"));
|
||||||
actor.setFirstName(rs.getString("first_name"));
|
actor.setSurname(rs.getString("surname"));
|
||||||
actor.setSurname(rs.getString("surname"));
|
return actor;
|
||||||
return actor;
|
}
|
||||||
}
|
});
|
||||||
});</programlisting>
|
]]></programlisting>
|
||||||
|
|
||||||
<para>Querying and populating a number of domain objects.</para>
|
<para>Querying and populating a number of domain objects.</para>
|
||||||
|
|
||||||
<programlisting language="java">Collection actors = this.jdbcTemplate.query(
|
<programlisting language="java"><![CDATA[List<Actor> actors = this.jdbcTemplate.query(
|
||||||
"select first_name, surname from t_actor",
|
"select first_name, surname from t_actor",
|
||||||
new RowMapper() {
|
new RowMapper<Actor>() {
|
||||||
|
public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
|
Actor actor = new Actor();
|
||||||
Actor actor = new Actor();
|
actor.setFirstName(rs.getString("first_name"));
|
||||||
actor.setFirstName(rs.getString("first_name"));
|
actor.setSurname(rs.getString("surname"));
|
||||||
actor.setSurname(rs.getString("surname"));
|
return actor;
|
||||||
return actor;
|
}
|
||||||
}
|
});
|
||||||
});</programlisting>
|
]]></programlisting>
|
||||||
|
|
||||||
<para>If the last two snippets of code actually existed in the same
|
<para>If the last two snippets of code actually existed in the same
|
||||||
application, it would make sense to remove the duplication present
|
application, it would make sense to remove the duplication present
|
||||||
|
|
@ -282,35 +283,35 @@
|
||||||
by DAO methods as needed. For example, the last code snippet might
|
by DAO methods as needed. For example, the last code snippet might
|
||||||
be better off written like so:</para>
|
be better off written like so:</para>
|
||||||
|
|
||||||
<programlisting language="java">public Collection findAllActors() {
|
<programlisting language="java"><![CDATA[public List<Actor> findAllActors() {
|
||||||
return this.jdbcTemplate.query( "select first_name, surname from t_actor", new ActorMapper());
|
return this.jdbcTemplate.query( "select first_name, surname from t_actor", new ActorMapper());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class ActorMapper implements RowMapper {
|
private static final class ActorMapper implements RowMapper<Actor> {
|
||||||
|
|
||||||
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
|
public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
Actor actor = new Actor();
|
Actor actor = new Actor();
|
||||||
actor.setFirstName(rs.getString("first_name"));
|
actor.setFirstName(rs.getString("first_name"));
|
||||||
actor.setSurname(rs.getString("surname"));
|
actor.setSurname(rs.getString("surname"));
|
||||||
return actor;
|
return actor;
|
||||||
}
|
}
|
||||||
}</programlisting>
|
}]]></programlisting>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="jdbc-JdbcTemplate-examples-update">
|
<section id="jdbc-JdbcTemplate-examples-update">
|
||||||
<title>Updating (INSERT/UPDATE/DELETE)</title>
|
<title>Updating (INSERT/UPDATE/DELETE)</title>
|
||||||
|
|
||||||
<programlisting language="java">this.jdbcTemplate.update(
|
<programlisting language="java"><![CDATA[this.jdbcTemplate.update(
|
||||||
"insert into t_actor (first_name, surname) values (?, ?)",
|
"insert into t_actor (first_name, surname) values (?, ?)",
|
||||||
new Object[] {"Leonor", "Watling"});</programlisting>
|
new Object[] {"Leonor", "Watling"});]]></programlisting>
|
||||||
|
|
||||||
<programlisting language="java">this.jdbcTemplate.update(
|
<programlisting language="java"><![CDATA[this.jdbcTemplate.update(
|
||||||
"update t_actor set weapon = ? where id = ?",
|
"update t_actor set weapon = ? where id = ?",
|
||||||
new Object[] {"Banjo", new Long(5276)});</programlisting>
|
new Object[] {"Banjo", new Long(5276)});]]></programlisting>
|
||||||
|
|
||||||
<programlisting language="java">this.jdbcTemplate.update(
|
<programlisting language="java"><![CDATA[this.jdbcTemplate.update(
|
||||||
"delete from actor where id = ?",
|
"delete from actor where id = ?",
|
||||||
new Object[] {new Long.valueOf(actorId)});</programlisting>
|
new Object[] {new Long.valueOf(actorId)});]]></programlisting>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="jdbc-JdbcTemplate-examples-other">
|
<section id="jdbc-JdbcTemplate-examples-other">
|
||||||
|
|
@ -321,15 +322,15 @@ private static final class ActorMapper implements RowMapper {
|
||||||
statements. It is heavily overloaded with variants taking callback
|
statements. It is heavily overloaded with variants taking callback
|
||||||
interfaces, binding variable arrays, and suchlike.</para>
|
interfaces, binding variable arrays, and suchlike.</para>
|
||||||
|
|
||||||
<programlisting language="java">this.jdbcTemplate.execute("create table mytable (id integer, name varchar(100))");</programlisting>
|
<programlisting language="java"><![CDATA[this.jdbcTemplate.execute("create table mytable (id integer, name varchar(100))");]]></programlisting>
|
||||||
|
|
||||||
<para>Invoking a simple stored procedure (more sophisticated stored
|
<para>Invoking a simple stored procedure (more sophisticated stored
|
||||||
procedure support is <link linkend="jdbc-StoredProcedure">covered
|
procedure support is <link linkend="jdbc-StoredProcedure">covered
|
||||||
later</link>).</para>
|
later</link>).</para>
|
||||||
|
|
||||||
<programlisting language="java">this.jdbcTemplate.update(
|
<programlisting language="java"><![CDATA[this.jdbcTemplate.update(
|
||||||
"call SUPPORT.REFRESH_ACTORS_SUMMARY(?)",
|
"call SUPPORT.REFRESH_ACTORS_SUMMARY(?)",
|
||||||
new Object[]{Long.valueOf(unionId)});</programlisting>
|
new Object[]{Long.valueOf(unionId)});]]></programlisting>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
@ -693,11 +694,11 @@ public Actor findActor(long id) {
|
||||||
used to connect to the database. Here is an example of how to configure
|
used to connect to the database. Here is an example of how to configure
|
||||||
a <classname>DriverManagerDataSource</classname>:</para>
|
a <classname>DriverManagerDataSource</classname>:</para>
|
||||||
|
|
||||||
<programlisting language="java">DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
<programlisting language="java"><![CDATA[DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
||||||
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
|
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
|
||||||
dataSource.setUrl("jdbc:hsqldb:hsql://localhost:");
|
dataSource.setUrl("jdbc:hsqldb:hsql://localhost:");
|
||||||
dataSource.setUsername("sa");
|
dataSource.setUsername("sa");
|
||||||
dataSource.setPassword("");</programlisting>
|
dataSource.setPassword("");]]></programlisting>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="jdbc-SQLExceptionTranslator">
|
<section id="jdbc-SQLExceptionTranslator">
|
||||||
|
|
@ -752,7 +753,7 @@ dataSource.setPassword("");</programlisting>
|
||||||
<para><classname>SQLErrorCodeSQLExceptionTranslator</classname> can be
|
<para><classname>SQLErrorCodeSQLExceptionTranslator</classname> can be
|
||||||
extended the following way:</para>
|
extended the following way:</para>
|
||||||
|
|
||||||
<programlisting language="java">public class MySQLErrorCodesTranslator extends SQLErrorCodeSQLExceptionTranslator {
|
<programlisting language="java"><![CDATA[public class MySQLErrorCodesTranslator extends SQLErrorCodeSQLExceptionTranslator {
|
||||||
|
|
||||||
protected DataAccessException customTranslate(String task, String sql, SQLException sqlex) {
|
protected DataAccessException customTranslate(String task, String sql, SQLException sqlex) {
|
||||||
if (sqlex.getErrorCode() == -12345) {
|
if (sqlex.getErrorCode() == -12345) {
|
||||||
|
|
@ -760,7 +761,7 @@ dataSource.setPassword("");</programlisting>
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}</programlisting>
|
}]]></programlisting>
|
||||||
|
|
||||||
<para>In this example the specific error code
|
<para>In this example the specific error code
|
||||||
<literal>'-12345'</literal> is translated and any other errors are
|
<literal>'-12345'</literal> is translated and any other errors are
|
||||||
|
|
@ -802,7 +803,7 @@ su.update();</programlisting>
|
||||||
what you need to include for a minimal but fully functional class that
|
what you need to include for a minimal but fully functional class that
|
||||||
creates a new table.</para>
|
creates a new table.</para>
|
||||||
|
|
||||||
<programlisting language="java">import javax.sql.DataSource;
|
<programlisting language="java"><![CDATA[import javax.sql.DataSource;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
|
||||||
public class ExecuteAStatement {
|
public class ExecuteAStatement {
|
||||||
|
|
@ -816,7 +817,7 @@ public class ExecuteAStatement {
|
||||||
public void doExecute() {
|
public void doExecute() {
|
||||||
this.jdbcTemplate.execute("create table mytable (id integer, name varchar(100))");
|
this.jdbcTemplate.execute("create table mytable (id integer, name varchar(100))");
|
||||||
}
|
}
|
||||||
}</programlisting>
|
}]]></programlisting>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="jdbc-statements-querying">
|
<section id="jdbc-statements-querying">
|
||||||
|
|
@ -836,7 +837,7 @@ public class ExecuteAStatement {
|
||||||
an <classname>int</classname> and one that queries for a
|
an <classname>int</classname> and one that queries for a
|
||||||
<classname>String</classname>.</para>
|
<classname>String</classname>.</para>
|
||||||
|
|
||||||
<programlisting language="java">import javax.sql.DataSource;
|
<programlisting language="java"><![CDATA[import javax.sql.DataSource;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
|
||||||
public class RunAQuery {
|
public class RunAQuery {
|
||||||
|
|
@ -858,7 +859,7 @@ public class RunAQuery {
|
||||||
public void setDataSource(DataSource dataSource) {
|
public void setDataSource(DataSource dataSource) {
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
}
|
}
|
||||||
}</programlisting>
|
}]]></programlisting>
|
||||||
|
|
||||||
<para>In addition to the single results query methods there are several
|
<para>In addition to the single results query methods there are several
|
||||||
methods that return a List with an entry for each row that the query
|
methods that return a List with an entry for each row that the query
|
||||||
|
|
@ -870,7 +871,7 @@ public class RunAQuery {
|
||||||
above example to retrieve a list of all the rows, it would look like
|
above example to retrieve a list of all the rows, it would look like
|
||||||
this:</para>
|
this:</para>
|
||||||
|
|
||||||
<programlisting language="java">
|
<programlisting language="java"><![CDATA[
|
||||||
private JdbcTemplate jdbcTemplate;
|
private JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
public void setDataSource(DataSource dataSource) {
|
public void setDataSource(DataSource dataSource) {
|
||||||
|
|
@ -879,11 +880,11 @@ public void setDataSource(DataSource dataSource) {
|
||||||
|
|
||||||
public List getList() {
|
public List getList() {
|
||||||
return this.jdbcTemplate.queryForList("select * from mytable");
|
return this.jdbcTemplate.queryForList("select * from mytable");
|
||||||
}</programlisting>
|
}]]></programlisting>
|
||||||
|
|
||||||
<para>The list returned would look something like this:</para>
|
<para>The list returned would look something like this:</para>
|
||||||
|
|
||||||
<programlisting>[{name=Bob, id=1}, {name=Mary, id=2}]</programlisting>
|
<programlisting><![CDATA[[{name=Bob, id=1}, {name=Mary, id=2}]]]></programlisting>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="jdbc-updates">
|
<section id="jdbc-updates">
|
||||||
|
|
@ -896,7 +897,7 @@ public List getList() {
|
||||||
objects (and thus primitives have to be wrapped in the primitive wrapper
|
objects (and thus primitives have to be wrapped in the primitive wrapper
|
||||||
classes).</para>
|
classes).</para>
|
||||||
|
|
||||||
<programlisting language="java">import javax.sql.DataSource;
|
<programlisting language="java"><![CDATA[import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
|
||||||
|
|
@ -913,7 +914,7 @@ public class ExecuteAnUpdate {
|
||||||
"update mytable set name = ? where id = ?",
|
"update mytable set name = ? where id = ?",
|
||||||
new Object[] {name, new Integer(id)});
|
new Object[] {name, new Integer(id)});
|
||||||
}
|
}
|
||||||
}</programlisting>
|
}]]></programlisting>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="jdbc-auto-genereted-keys">
|
<section id="jdbc-auto-genereted-keys">
|
||||||
|
|
@ -1016,8 +1017,9 @@ jdbcTemplate.update(
|
||||||
|
|
||||||
<para>The <classname>DriverManagerDataSource</classname> class is an
|
<para>The <classname>DriverManagerDataSource</classname> class is an
|
||||||
implementation of the standard <interfacename>DataSource</interfacename>
|
implementation of the standard <interfacename>DataSource</interfacename>
|
||||||
interface that configures a plain old JDBC Driver via bean properties, and
|
interface that configures a plain old JDBC Driver via bean properties,
|
||||||
returns a new <interfacename>Connection</interfacename> every time.</para>
|
and returns a new <interfacename>Connection</interfacename> every
|
||||||
|
time.</para>
|
||||||
|
|
||||||
<para>This is potentially useful for test or standalone environments
|
<para>This is potentially useful for test or standalone environments
|
||||||
outside of a J2EE container, either as a
|
outside of a J2EE container, either as a
|
||||||
|
|
@ -1172,7 +1174,7 @@ jdbcTemplate.update(
|
||||||
where we update the actor table based on entries in a list. The entire
|
where we update the actor table based on entries in a list. The entire
|
||||||
list is used as the batch in his example.</para>
|
list is used as the batch in his example.</para>
|
||||||
|
|
||||||
<para><programlisting language="java">public class JdbcActorDao implements ActorDao {
|
<para><programlisting language="java"><![CDATA[public class JdbcActorDao implements ActorDao {
|
||||||
private JdbcTemplate jdbcTemplate;
|
private JdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
public void setDataSource(DataSource dataSource) {
|
public void setDataSource(DataSource dataSource) {
|
||||||
|
|
@ -1197,7 +1199,7 @@ jdbcTemplate.update(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... additional methods
|
// ... additional methods
|
||||||
}</programlisting>If you are processing stream of updates or reading from a
|
}]]></programlisting>If you are processing stream of updates or reading from a
|
||||||
file then you might have a preferred batch size, but the last batch
|
file then you might have a preferred batch size, but the last batch
|
||||||
might not have that number of entries. In this case you can use the
|
might not have that number of entries. In this case you can use the
|
||||||
<classname>InterruptibleBatchPreparedStatementSetter</classname>
|
<classname>InterruptibleBatchPreparedStatementSetter</classname>
|
||||||
|
|
@ -1223,14 +1225,14 @@ jdbcTemplate.update(
|
||||||
|
|
||||||
<para>This example shows a batch update using named parameters:</para>
|
<para>This example shows a batch update using named parameters:</para>
|
||||||
|
|
||||||
<para><programlisting language="java">public class JdbcActorDao implements ActorDao {
|
<para><programlisting language="java"><![CDATA[public class JdbcActorDao implements ActorDao {
|
||||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||||
|
|
||||||
public void setDataSource(DataSource dataSource) {
|
public void setDataSource(DataSource dataSource) {
|
||||||
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] batchUpdate(final List<Actor> actors) {
|
public int[] batchUpdate(final List<Actor> actors) {
|
||||||
SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(actors.toArray());
|
SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(actors.toArray());
|
||||||
int[] updateCounts = simpleJdbcTemplate.batchUpdate(
|
int[] updateCounts = simpleJdbcTemplate.batchUpdate(
|
||||||
"update t_actor set first_name = :firstName, last_name = :lastName where id = :id",
|
"update t_actor set first_name = :firstName, last_name = :lastName where id = :id",
|
||||||
|
|
@ -1239,23 +1241,23 @@ jdbcTemplate.update(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... additional methods
|
// ... additional methods
|
||||||
}</programlisting>For an SQL statement using the classic "?" place holders you
|
}]]></programlisting>For an SQL statement using the classic "?" place holders
|
||||||
pass in a List containing an object array with the update values. This
|
you pass in a List containing an object array with the update values.
|
||||||
object array must have one entry for each placeholder in the SQL
|
This object array must have one entry for each placeholder in the SQL
|
||||||
statement and they must be in the same order as they are defined in the
|
statement and they must be in the same order as they are defined in the
|
||||||
SQL statement.</para>
|
SQL statement.</para>
|
||||||
|
|
||||||
<para>The same example using classic JDBC "?" place holders:</para>
|
<para>The same example using classic JDBC "?" place holders:</para>
|
||||||
|
|
||||||
<para><programlisting language="java">public class JdbcActorDao implements ActorDao {
|
<para><programlisting language="java"><![CDATA[public class JdbcActorDao implements ActorDao {
|
||||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||||
|
|
||||||
public void setDataSource(DataSource dataSource) {
|
public void setDataSource(DataSource dataSource) {
|
||||||
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] batchUpdate(final List<Actor> actors) {
|
public int[] batchUpdate(final List<Actor> actors) {
|
||||||
List<Object[]> batch = new ArrayList<Object[]>();
|
List<Object[]> batch = new ArrayList<Object[]>();
|
||||||
for (Actor actor : actors) {
|
for (Actor actor : actors) {
|
||||||
Object[] values = new Object[] {
|
Object[] values = new Object[] {
|
||||||
actor.getFirstName(),
|
actor.getFirstName(),
|
||||||
|
|
@ -1270,9 +1272,9 @@ jdbcTemplate.update(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... additional methods
|
// ... additional methods
|
||||||
}</programlisting>All batch update methods return an int array containing the
|
}]]></programlisting>All batch update methods return an int array containing
|
||||||
number of affected rows for each batch entry. This count is reported by
|
the number of affected rows for each batch entry. This count is reported
|
||||||
the JDBC driver and it's not always available in which case the JDBC
|
by the JDBC driver and it's not always available in which case the JDBC
|
||||||
driver simply returns a -2 value.</para>
|
driver simply returns a -2 value.</para>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -1304,7 +1306,7 @@ jdbcTemplate.update(
|
||||||
configuration methods. In this case there is only one configuration
|
configuration methods. In this case there is only one configuration
|
||||||
method used but we will see examples of multiple ones soon.</para>
|
method used but we will see examples of multiple ones soon.</para>
|
||||||
|
|
||||||
<programlisting language="java">public class JdbcActorDao implements ActorDao {
|
<programlisting language="java"><![CDATA[public class JdbcActorDao implements ActorDao {
|
||||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||||
private SimpleJdbcInsert insertActor;
|
private SimpleJdbcInsert insertActor;
|
||||||
|
|
||||||
|
|
@ -1315,7 +1317,7 @@ jdbcTemplate.update(
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(Actor actor) {
|
public void add(Actor actor) {
|
||||||
Map<String, Object> parameters = new HashMap<String, Object>(3);
|
Map<String, Object> parameters = new HashMap<String, Object>(3);
|
||||||
parameters.put("id", actor.getId());
|
parameters.put("id", actor.getId());
|
||||||
parameters.put("first_name", actor.getFirstName());
|
parameters.put("first_name", actor.getFirstName());
|
||||||
parameters.put("last_name", actor.getLastName());
|
parameters.put("last_name", actor.getLastName());
|
||||||
|
|
@ -1323,7 +1325,7 @@ jdbcTemplate.update(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... additional methods
|
// ... additional methods
|
||||||
}</programlisting>
|
}]]></programlisting>
|
||||||
|
|
||||||
<para>The execute method used here takes a plain
|
<para>The execute method used here takes a plain
|
||||||
<classname>java.utils.Map</classname> as its only parameter. The
|
<classname>java.utils.Map</classname> as its only parameter. The
|
||||||
|
|
@ -1343,7 +1345,7 @@ jdbcTemplate.update(
|
||||||
generated key column using the
|
generated key column using the
|
||||||
<classname>usingGeneratedKeyColumns</classname> method.</para>
|
<classname>usingGeneratedKeyColumns</classname> method.</para>
|
||||||
|
|
||||||
<para><programlisting language="java">public class JdbcActorDao implements ActorDao {
|
<para><programlisting language="java"><![CDATA[public class JdbcActorDao implements ActorDao {
|
||||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||||
private SimpleJdbcInsert insertActor;
|
private SimpleJdbcInsert insertActor;
|
||||||
|
|
||||||
|
|
@ -1356,7 +1358,7 @@ jdbcTemplate.update(
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(Actor actor) {
|
public void add(Actor actor) {
|
||||||
Map<String, Object> parameters = new HashMap<String, Object>(2);
|
Map<String, Object> parameters = new HashMap<String, Object>(2);
|
||||||
parameters.put("first_name", actor.getFirstName());
|
parameters.put("first_name", actor.getFirstName());
|
||||||
parameters.put("last_name", actor.getLastName());
|
parameters.put("last_name", actor.getLastName());
|
||||||
Number newId = insertActor.executeAndReturnKey(parameters);
|
Number newId = insertActor.executeAndReturnKey(parameters);
|
||||||
|
|
@ -1364,7 +1366,7 @@ jdbcTemplate.update(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... additional methods
|
// ... additional methods
|
||||||
}</programlisting>Here we can see the main difference when executing the
|
}]]></programlisting>Here we can see the main difference when executing the
|
||||||
insert is that we don't add the id to the Map and we call the
|
insert is that we don't add the id to the Map and we call the
|
||||||
<literal>executeReturningKey</literal> method. This returns a
|
<literal>executeReturningKey</literal> method. This returns a
|
||||||
<literal>java.lang.Number</literal> object that we can use to create an
|
<literal>java.lang.Number</literal> object that we can use to create an
|
||||||
|
|
@ -1384,7 +1386,7 @@ jdbcTemplate.update(
|
||||||
specifying a list of column names to be used. This is accomplished using
|
specifying a list of column names to be used. This is accomplished using
|
||||||
the <classname>usingColumns</classname> method.</para>
|
the <classname>usingColumns</classname> method.</para>
|
||||||
|
|
||||||
<para><programlisting language="java">public class JdbcActorDao implements ActorDao {
|
<para><programlisting language="java"><![CDATA[public class JdbcActorDao implements ActorDao {
|
||||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||||
private SimpleJdbcInsert insertActor;
|
private SimpleJdbcInsert insertActor;
|
||||||
|
|
||||||
|
|
@ -1398,7 +1400,7 @@ jdbcTemplate.update(
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(Actor actor) {
|
public void add(Actor actor) {
|
||||||
Map<String, Object> parameters = new HashMap<String, Object>(2);
|
Map<String, Object> parameters = new HashMap<String, Object>(2);
|
||||||
parameters.put("first_name", actor.getFirstName());
|
parameters.put("first_name", actor.getFirstName());
|
||||||
parameters.put("last_name", actor.getLastName());
|
parameters.put("last_name", actor.getLastName());
|
||||||
Number newId = insertActor.executeAndReturnKey(parameters);
|
Number newId = insertActor.executeAndReturnKey(parameters);
|
||||||
|
|
@ -1406,8 +1408,8 @@ jdbcTemplate.update(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... additional methods
|
// ... additional methods
|
||||||
}</programlisting>The execution of the insert is the same as if we had relied
|
}]]></programlisting>The execution of the insert is the same as if we had
|
||||||
on the metadata for determining what columns to use.</para>
|
relied on the metadata for determining what columns to use.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="jdbc-simple-jdbc-parameters">
|
<section id="jdbc-simple-jdbc-parameters">
|
||||||
|
|
@ -1422,7 +1424,7 @@ jdbcTemplate.update(
|
||||||
contains your values. It will use the corresponding getter method to
|
contains your values. It will use the corresponding getter method to
|
||||||
extract the parameter values. Here is an example:</para>
|
extract the parameter values. Here is an example:</para>
|
||||||
|
|
||||||
<para><programlisting language="java">public class JdbcActorDao implements ActorDao {
|
<para><programlisting language="java"><![CDATA[public class JdbcActorDao implements ActorDao {
|
||||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||||
private SimpleJdbcInsert insertActor;
|
private SimpleJdbcInsert insertActor;
|
||||||
|
|
||||||
|
|
@ -1441,12 +1443,12 @@ jdbcTemplate.update(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... additional methods
|
// ... additional methods
|
||||||
}</programlisting>Another option is the
|
}]]></programlisting>Another option is the
|
||||||
<classname>MapSqlParameterSource</classname> that resembles a Map but
|
<classname>MapSqlParameterSource</classname> that resembles a Map but
|
||||||
provides a more convenient <classname>addValue</classname> method that
|
provides a more convenient <classname>addValue</classname> method that
|
||||||
can be chained.</para>
|
can be chained.</para>
|
||||||
|
|
||||||
<para><programlisting language="java">public class JdbcActorDao implements ActorDao {
|
<para><programlisting language="java"><![CDATA[public class JdbcActorDao implements ActorDao {
|
||||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||||
private SimpleJdbcInsert insertActor;
|
private SimpleJdbcInsert insertActor;
|
||||||
|
|
||||||
|
|
@ -1467,8 +1469,8 @@ jdbcTemplate.update(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... additional methods
|
// ... additional methods
|
||||||
}</programlisting>As you can see, the configuration is the same, it;s just the
|
}]]></programlisting>As you can see, the configuration is the same, it;s just
|
||||||
executing code that has to change to use these alternative input
|
the executing code that has to change to use these alternative input
|
||||||
classes.</para>
|
classes.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
@ -1491,7 +1493,7 @@ jdbcTemplate.update(
|
||||||
the source for the procedure as it would look when using MySQL as the
|
the source for the procedure as it would look when using MySQL as the
|
||||||
database:</para>
|
database:</para>
|
||||||
|
|
||||||
<para><programlisting>CREATE PROCEDURE read_actor (
|
<para><programlisting><![CDATA[CREATE PROCEDURE read_actor (
|
||||||
IN in_id INTEGER,
|
IN in_id INTEGER,
|
||||||
OUT out_first_name VARCHAR(100),
|
OUT out_first_name VARCHAR(100),
|
||||||
OUT out_last_name VARCHAR(100),
|
OUT out_last_name VARCHAR(100),
|
||||||
|
|
@ -1500,7 +1502,7 @@ BEGIN
|
||||||
SELECT first_name, last_name, birth_date
|
SELECT first_name, last_name, birth_date
|
||||||
INTO out_first_name, out_last_name, out_birth_date
|
INTO out_first_name, out_last_name, out_birth_date
|
||||||
FROM t_actor where id = in_id;
|
FROM t_actor where id = in_id;
|
||||||
END;</programlisting>As you can see there are four parameters. One is an in
|
END;]]></programlisting>As you can see there are four parameters. One is an in
|
||||||
parameter "in_id" containing the id of the Actor we are looking up. The
|
parameter "in_id" containing the id of the Actor we are looking up. The
|
||||||
remaining parameters are out parameters and they will be used to return
|
remaining parameters are out parameters and they will be used to return
|
||||||
the data read from the table.</para>
|
the data read from the table.</para>
|
||||||
|
|
@ -1510,7 +1512,7 @@ END;</programlisting>As you can see there are four parameters. One is an in
|
||||||
subclass and we declare it in the initialization method. For this
|
subclass and we declare it in the initialization method. For this
|
||||||
example, all we need to specify is the name of the procedure.</para>
|
example, all we need to specify is the name of the procedure.</para>
|
||||||
|
|
||||||
<para><programlisting language="java">public class JdbcActorDao implements ActorDao {
|
<para><programlisting language="java"><![CDATA[public class JdbcActorDao implements ActorDao {
|
||||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||||
private SimpleJdbcCall procReadActor;
|
private SimpleJdbcCall procReadActor;
|
||||||
|
|
||||||
|
|
@ -1534,7 +1536,7 @@ END;</programlisting>As you can see there are four parameters. One is an in
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... additional methods
|
// ... additional methods
|
||||||
}</programlisting>The execution of the call involves creating an
|
}]]></programlisting>The execution of the call involves creating an
|
||||||
<classname>SqlParameterSource</classname> containing the in parameter.
|
<classname>SqlParameterSource</classname> containing the in parameter.
|
||||||
It's important to match the name of the parameter declared in the stored
|
It's important to match the name of the parameter declared in the stored
|
||||||
procedure. The case doesn't have to match since we use metadata to
|
procedure. The case doesn't have to match since we use metadata to
|
||||||
|
|
@ -1565,7 +1567,7 @@ END;</programlisting>As you can see there are four parameters. One is an in
|
||||||
<classname>commons-collections.jar</classname> on your classpath for
|
<classname>commons-collections.jar</classname> on your classpath for
|
||||||
this to work. Here is an example of this configuration:</para>
|
this to work. Here is an example of this configuration:</para>
|
||||||
|
|
||||||
<para><programlisting language="java">public class JdbcActorDao implements ActorDao {
|
<para><programlisting language="java"><![CDATA[public class JdbcActorDao implements ActorDao {
|
||||||
private SimpleJdbcCall procReadActor;
|
private SimpleJdbcCall procReadActor;
|
||||||
|
|
||||||
public void setDataSource(DataSource dataSource) {
|
public void setDataSource(DataSource dataSource) {
|
||||||
|
|
@ -1578,8 +1580,8 @@ END;</programlisting>As you can see there are four parameters. One is an in
|
||||||
|
|
||||||
|
|
||||||
// ... additional methods
|
// ... additional methods
|
||||||
}</programlisting>By doing this, you don't have to worry about the case used
|
}]]></programlisting>By doing this, you don't have to worry about the case
|
||||||
for the names of your returned out parameters.</para>
|
used for the names of your returned out parameters.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="jdbc-simple-jdbc-call-2">
|
<section id="jdbc-simple-jdbc-call-2">
|
||||||
|
|
@ -1606,7 +1608,7 @@ END;</programlisting>As you can see there are four parameters. One is an in
|
||||||
<para>This is what a fully declared procedure call declaration of our
|
<para>This is what a fully declared procedure call declaration of our
|
||||||
earlier example would look like:</para>
|
earlier example would look like:</para>
|
||||||
|
|
||||||
<para><programlisting language="java">public class JdbcActorDao implements ActorDao {
|
<para><programlisting language="java"><![CDATA[public class JdbcActorDao implements ActorDao {
|
||||||
private SimpleJdbcCall procReadActor;
|
private SimpleJdbcCall procReadActor;
|
||||||
|
|
||||||
public void setDataSource(DataSource dataSource) {
|
public void setDataSource(DataSource dataSource) {
|
||||||
|
|
@ -1627,7 +1629,7 @@ END;</programlisting>As you can see there are four parameters. One is an in
|
||||||
|
|
||||||
|
|
||||||
// ... additional methods
|
// ... additional methods
|
||||||
}</programlisting>The execution and end results are the same, we are just
|
}]]></programlisting>The execution and end results are the same, we are just
|
||||||
specifying all the details explicitly rather than relying on metadata.
|
specifying all the details explicitly rather than relying on metadata.
|
||||||
This will be necessary if the database we use is not part of the
|
This will be necessary if the database we use is not part of the
|
||||||
supported databases. Currently we support metadata lookup of stored
|
supported databases. Currently we support metadata lookup of stored
|
||||||
|
|
@ -1647,8 +1649,8 @@ END;</programlisting>As you can see there are four parameters. One is an in
|
||||||
<classname>java.sql.Types</classname> constants. We have already seen
|
<classname>java.sql.Types</classname> constants. We have already seen
|
||||||
declarations like:</para>
|
declarations like:</para>
|
||||||
|
|
||||||
<para><programlisting language="java"> new SqlParameter("in_id", Types.NUMERIC),
|
<para><programlisting language="java"><![CDATA[ new SqlParameter("in_id", Types.NUMERIC),
|
||||||
new SqlOutParameter("out_first_name", Types.VARCHAR),</programlisting></para>
|
new SqlOutParameter("out_first_name", Types.VARCHAR),]]></programlisting></para>
|
||||||
|
|
||||||
<para>The first line with the <classname>SqlParameter</classname>
|
<para>The first line with the <classname>SqlParameter</classname>
|
||||||
declares an in parameter. In parameters can be used for both stored
|
declares an in parameter. In parameters can be used for both stored
|
||||||
|
|
@ -1668,7 +1670,7 @@ END;</programlisting>As you can see there are four parameters. One is an in
|
||||||
input values. This is different from the
|
input values. This is different from the
|
||||||
<classname>StoredProcedure</classname> class which for backwards
|
<classname>StoredProcedure</classname> class which for backwards
|
||||||
compatibility reasons allows input values to be provided for
|
compatibility reasons allows input values to be provided for
|
||||||
parameters declared as <classname>SqlOutParameter</classname>. </para>
|
parameters declared as <classname>SqlOutParameter</classname>.</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
<para>In addition to the name and the SQL type you can specify
|
<para>In addition to the name and the SQL type you can specify
|
||||||
|
|
@ -1699,7 +1701,7 @@ END;</programlisting>As you can see there are four parameters. One is an in
|
||||||
that returns an actor's full name. Here is the MySQL source for this
|
that returns an actor's full name. Here is the MySQL source for this
|
||||||
function:</para>
|
function:</para>
|
||||||
|
|
||||||
<para><programlisting>CREATE FUNCTION get_actor_name (in_id INTEGER)
|
<para><programlisting><![CDATA[CREATE FUNCTION get_actor_name (in_id INTEGER)
|
||||||
RETURNS VARCHAR(200) READS SQL DATA
|
RETURNS VARCHAR(200) READS SQL DATA
|
||||||
BEGIN
|
BEGIN
|
||||||
DECLARE out_name VARCHAR(200);
|
DECLARE out_name VARCHAR(200);
|
||||||
|
|
@ -1707,13 +1709,13 @@ BEGIN
|
||||||
INTO out_name
|
INTO out_name
|
||||||
FROM t_actor where id = in_id;
|
FROM t_actor where id = in_id;
|
||||||
RETURN out_name;
|
RETURN out_name;
|
||||||
END;</programlisting></para>
|
END;]]></programlisting></para>
|
||||||
|
|
||||||
<para>To call this function we again create a
|
<para>To call this function we again create a
|
||||||
<classname>SimpleJdbcCall</classname> in the initialization
|
<classname>SimpleJdbcCall</classname> in the initialization
|
||||||
method.</para>
|
method.</para>
|
||||||
|
|
||||||
<para><programlisting language="java">public class JdbcActorDao implements ActorDao {
|
<para><programlisting language="java"><![CDATA[public class JdbcActorDao implements ActorDao {
|
||||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||||
private SimpleJdbcCall funcGetActorName;
|
private SimpleJdbcCall funcGetActorName;
|
||||||
|
|
||||||
|
|
@ -1734,7 +1736,7 @@ END;</programlisting></para>
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... additional methods
|
// ... additional methods
|
||||||
}</programlisting>The execute method used returns a
|
}]]></programlisting>The execute method used returns a
|
||||||
<classname>String</classname> containing the return value from the
|
<classname>String</classname> containing the return value from the
|
||||||
function call.</para>
|
function call.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -1761,17 +1763,17 @@ END;</programlisting></para>
|
||||||
parameters and returns all rows from the t_actor table. Here is the
|
parameters and returns all rows from the t_actor table. Here is the
|
||||||
MySQL source for this procedure:</para>
|
MySQL source for this procedure:</para>
|
||||||
|
|
||||||
<para><programlisting>CREATE PROCEDURE read_all_actors()
|
<para><programlisting><![CDATA[CREATE PROCEDURE read_all_actors()
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT a.id, a.first_name, a.last_name, a.birth_date FROM t_actor a;
|
SELECT a.id, a.first_name, a.last_name, a.birth_date FROM t_actor a;
|
||||||
END;</programlisting>In order to call this procedure we need to declare the
|
END;]]></programlisting>In order to call this procedure we need to declare the
|
||||||
<classname>RowMapper</classname> to be used. Since the class we want to
|
<classname>RowMapper</classname> to be used. Since the class we want to
|
||||||
map to follows the JavaBean rules, we can use a
|
map to follows the JavaBean rules, we can use a
|
||||||
<classname>ParameterizedBeanPropertyRowMapper</classname> that is
|
<classname>ParameterizedBeanPropertyRowMapper</classname> that is
|
||||||
created by passing in the required class to map to in the
|
created by passing in the required class to map to in the
|
||||||
<classname>newInstance</classname> method.</para>
|
<classname>newInstance</classname> method.</para>
|
||||||
|
|
||||||
<para><programlisting language="java">public class JdbcActorDao implements ActorDao {
|
<para><programlisting language="java"><![CDATA[public class JdbcActorDao implements ActorDao {
|
||||||
private SimpleJdbcTemplate simpleJdbcTemplate;
|
private SimpleJdbcTemplate simpleJdbcTemplate;
|
||||||
private SimpleJdbcCall procReadAllActors;
|
private SimpleJdbcCall procReadAllActors;
|
||||||
|
|
||||||
|
|
@ -1787,12 +1789,12 @@ END;</programlisting>In order to call this procedure we need to declare the
|
||||||
}
|
}
|
||||||
|
|
||||||
public List getActorsList() {
|
public List getActorsList() {
|
||||||
Map m = procReadAllActors.execute(new HashMap<String, Object>(0));
|
Map m = procReadAllActors.execute(new HashMap<String, Object>(0));
|
||||||
return (List) m.get("actors");
|
return (List) m.get("actors");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... additional methods
|
// ... additional methods
|
||||||
}</programlisting>The execute call passes in an empty Map since this call
|
}]]></programlisting>The execute call passes in an empty Map since this call
|
||||||
doesn't take any parameters. The list of Actors is then retrieved from
|
doesn't take any parameters. The list of Actors is then retrieved from
|
||||||
the results map and returned to the caller.</para>
|
the results map and returned to the caller.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -1855,7 +1857,7 @@ END;</programlisting>In order to call this procedure we need to declare the
|
||||||
customer relation to an instance of the <classname>Customer</classname>
|
customer relation to an instance of the <classname>Customer</classname>
|
||||||
class.</para>
|
class.</para>
|
||||||
|
|
||||||
<programlisting language="java">private class CustomerMappingQuery extends MappingSqlQuery {
|
<programlisting language="java"><![CDATA[private class CustomerMappingQuery extends MappingSqlQuery {
|
||||||
|
|
||||||
public CustomerMappingQuery(DataSource ds) {
|
public CustomerMappingQuery(DataSource ds) {
|
||||||
super(ds, "SELECT id, name FROM customer WHERE id = ?");
|
super(ds, "SELECT id, name FROM customer WHERE id = ?");
|
||||||
|
|
@ -1869,7 +1871,7 @@ END;</programlisting>In order to call this procedure we need to declare the
|
||||||
cust.setName(rs.getString("name"));
|
cust.setName(rs.getString("name"));
|
||||||
return cust;
|
return cust;
|
||||||
}
|
}
|
||||||
}</programlisting>
|
}]]></programlisting>
|
||||||
|
|
||||||
<para>We provide a constructor for this customer query that takes the
|
<para>We provide a constructor for this customer query that takes the
|
||||||
<interfacename>DataSource</interfacename> as the only parameter. In this
|
<interfacename>DataSource</interfacename> as the only parameter. In this
|
||||||
|
|
@ -1886,18 +1888,18 @@ END;</programlisting>In order to call this procedure we need to declare the
|
||||||
have been defined we call the <literal>compile()</literal> method so the
|
have been defined we call the <literal>compile()</literal> method so the
|
||||||
statement can be prepared and later be executed.</para>
|
statement can be prepared and later be executed.</para>
|
||||||
|
|
||||||
<programlisting language="java">public Customer getCustomer(Integer id) {
|
<programlisting language="java"><![CDATA[public Customer getCustomer(Integer id) {
|
||||||
CustomerMappingQuery custQry = new CustomerMappingQuery(dataSource);
|
CustomerMappingQuery custQry = new CustomerMappingQuery(dataSource);
|
||||||
Object[] parms = new Object[1];
|
Object[] parms = new Object[1];
|
||||||
parms[0] = id;
|
parms[0] = id;
|
||||||
List customers = custQry.execute(parms);
|
List customers = custQry.execute(parms);
|
||||||
if (customers.size() > 0) {
|
if (customers.size() > 0) {
|
||||||
return (Customer) customers.get(0);
|
return (Customer) customers.get(0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}</programlisting>
|
}]]></programlisting>
|
||||||
|
|
||||||
<para>The method in this example retrieves the customer with the id that
|
<para>The method in this example retrieves the customer with the id that
|
||||||
is passed in as the only parameter. After creating an instance of the
|
is passed in as the only parameter. After creating an instance of the
|
||||||
|
|
@ -1975,8 +1977,8 @@ public class UpdateCreditRating extends SqlUpdate {
|
||||||
SQL type is specified using the <classname>java.sql.Types</classname>
|
SQL type is specified using the <classname>java.sql.Types</classname>
|
||||||
constants. We have already seen declarations like:</para>
|
constants. We have already seen declarations like:</para>
|
||||||
|
|
||||||
<para><programlisting language="java"> new SqlParameter("in_id", Types.NUMERIC),
|
<para><programlisting language="java"><![CDATA[ new SqlParameter("in_id", Types.NUMERIC),
|
||||||
new SqlOutParameter("out_first_name", Types.VARCHAR),</programlisting></para>
|
new SqlOutParameter("out_first_name", Types.VARCHAR),]]></programlisting></para>
|
||||||
|
|
||||||
<para>The first line with the <classname>SqlParameter</classname>
|
<para>The first line with the <classname>SqlParameter</classname>
|
||||||
declares an in parameter. In parameters can be used for both stored
|
declares an in parameter. In parameters can be used for both stored
|
||||||
|
|
@ -1991,11 +1993,11 @@ public class UpdateCreditRating extends SqlUpdate {
|
||||||
that also return a value</para>
|
that also return a value</para>
|
||||||
|
|
||||||
<para><note>
|
<para><note>
|
||||||
<para> Parameters declared as <classname>SqlParameter</classname>
|
<para>Parameters declared as <classname>SqlParameter</classname> and
|
||||||
and <classname>SqlInOutParameter</classname> will always be used to
|
<classname>SqlInOutParameter</classname> will always be used to
|
||||||
provide input values. In addition to this any parameter declared as
|
provide input values. In addition to this any parameter declared as
|
||||||
<classname>SqlOutParameter</classname> where an non-null input value
|
<classname>SqlOutParameter</classname> where an non-null input value
|
||||||
is provided will also be used as an input paraneter. </para>
|
is provided will also be used as an input paraneter.</para>
|
||||||
</note></para>
|
</note></para>
|
||||||
|
|
||||||
<para>In addition to the name and the SQL type you can specify
|
<para>In addition to the name and the SQL type you can specify
|
||||||
|
|
@ -2113,7 +2115,7 @@ public class TitlesAndGenresStoredProcedure extends StoredProcedure {
|
||||||
<classname>Title</classname> domain object for each row in the supplied
|
<classname>Title</classname> domain object for each row in the supplied
|
||||||
<interfacename>ResultSet</interfacename>.</para>
|
<interfacename>ResultSet</interfacename>.</para>
|
||||||
|
|
||||||
<programlisting language="java">import com.foo.sprocs.domain.Title;
|
<programlisting language="java"><![CDATA[import com.foo.sprocs.domain.Title;
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
|
@ -2127,14 +2129,14 @@ public final class TitleMapper implements RowMapper {
|
||||||
title.setName(rs.getString("name"));
|
title.setName(rs.getString("name"));
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
}</programlisting>
|
}]]></programlisting>
|
||||||
|
|
||||||
<para>Secondly, the <classname>GenreMapper</classname> class, which
|
<para>Secondly, the <classname>GenreMapper</classname> class, which
|
||||||
again simply maps a <interfacename>ResultSet</interfacename> to a
|
again simply maps a <interfacename>ResultSet</interfacename> to a
|
||||||
<classname>Genre</classname> domain object for each row in the supplied
|
<classname>Genre</classname> domain object for each row in the supplied
|
||||||
<interfacename>ResultSet</interfacename>.</para>
|
<interfacename>ResultSet</interfacename>.</para>
|
||||||
|
|
||||||
<programlisting language="java">import org.springframework.jdbc.core.RowMapper;
|
<programlisting language="java"><![CDATA[import org.springframework.jdbc.core.RowMapper;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
@ -2146,7 +2148,7 @@ public final class GenreMapper implements RowMapper {
|
||||||
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
|
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
return new Genre(rs.getString("name"));
|
return new Genre(rs.getString("name"));
|
||||||
}
|
}
|
||||||
}</programlisting>
|
}]]></programlisting>
|
||||||
|
|
||||||
<para>If one needs to pass parameters to a stored procedure (that is the
|
<para>If one needs to pass parameters to a stored procedure (that is the
|
||||||
stored procedure has been declared as having one or more input
|
stored procedure has been declared as having one or more input
|
||||||
|
|
@ -2155,7 +2157,7 @@ public final class GenreMapper implements RowMapper {
|
||||||
superclass' (untyped) <literal>execute(Map parameters)</literal> (which
|
superclass' (untyped) <literal>execute(Map parameters)</literal> (which
|
||||||
has <literal>protected</literal> access); for example:</para>
|
has <literal>protected</literal> access); for example:</para>
|
||||||
|
|
||||||
<programlisting language="java">import oracle.jdbc.driver.OracleTypes;
|
<programlisting language="java"><![CDATA[import oracle.jdbc.driver.OracleTypes;
|
||||||
import org.springframework.jdbc.core.SqlOutParameter;
|
import org.springframework.jdbc.core.SqlOutParameter;
|
||||||
import org.springframework.jdbc.object.StoredProcedure;
|
import org.springframework.jdbc.object.StoredProcedure;
|
||||||
|
|
||||||
|
|
@ -2180,7 +2182,7 @@ public class TitlesAfterDateStoredProcedure extends StoredProcedure {
|
||||||
inputs.put(CUTOFF_DATE_PARAM, cutoffDate);
|
inputs.put(CUTOFF_DATE_PARAM, cutoffDate);
|
||||||
return super.execute(inputs);
|
return super.execute(inputs);
|
||||||
}
|
}
|
||||||
}</programlisting>
|
}]]></programlisting>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="jdbc-SqlFunction">
|
<section id="jdbc-SqlFunction">
|
||||||
|
|
@ -2211,11 +2213,11 @@ public class TitlesAfterDateStoredProcedure extends StoredProcedure {
|
||||||
the appropriate run method repeatedly to execute the function. Here is
|
the appropriate run method repeatedly to execute the function. Here is
|
||||||
an example of retrieving the count of rows from a table:</para>
|
an example of retrieving the count of rows from a table:</para>
|
||||||
|
|
||||||
<programlisting language="java">public int countRows() {
|
<programlisting language="java"><![CDATA[public int countRows() {
|
||||||
SqlFunction sf = new SqlFunction(dataSource, "select count(*) from mytable");
|
SqlFunction sf = new SqlFunction(dataSource, "select count(*) from mytable");
|
||||||
sf.compile();
|
sf.compile();
|
||||||
return sf.run();
|
return sf.run();
|
||||||
}</programlisting>
|
}]]></programlisting>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
@ -2346,7 +2348,7 @@ public class TitlesAfterDateStoredProcedure extends StoredProcedure {
|
||||||
<area coords="13" id="jdbc.lobhandler.setBlob" />
|
<area coords="13" id="jdbc.lobhandler.setBlob" />
|
||||||
</areaspec>
|
</areaspec>
|
||||||
|
|
||||||
<programlisting language="java">final File blobIn = new File("spring2004.jpg");
|
<programlisting language="java"><![CDATA[final File blobIn = new File("spring2004.jpg");
|
||||||
final InputStream blobIs = new FileInputStream(blobIn);
|
final InputStream blobIs = new FileInputStream(blobIn);
|
||||||
final File clobIn = new File("large.txt");
|
final File clobIn = new File("large.txt");
|
||||||
final InputStream clobIs = new FileInputStream(clobIn);
|
final InputStream clobIs = new FileInputStream(clobIn);
|
||||||
|
|
@ -2363,7 +2365,7 @@ jdbcTemplate.execute(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
blobIs.close();
|
blobIs.close();
|
||||||
clobReader.close();</programlisting>
|
clobReader.close();]]></programlisting>
|
||||||
|
|
||||||
<calloutlist>
|
<calloutlist>
|
||||||
<callout arearefs="jdbc.lobhandler.variableref">
|
<callout arearefs="jdbc.lobhandler.variableref">
|
||||||
|
|
@ -2395,7 +2397,7 @@ clobReader.close();</programlisting>
|
||||||
<area coords="7" id="jdbc.lobhandler.getBlob" />
|
<area coords="7" id="jdbc.lobhandler.getBlob" />
|
||||||
</areaspec>
|
</areaspec>
|
||||||
|
|
||||||
<programlisting language="java">List l = jdbcTemplate.query("select id, a_clob, a_blob from lob_table",
|
<programlisting language="java"><![CDATA[List l = jdbcTemplate.query("select id, a_clob, a_blob from lob_table",
|
||||||
new RowMapper() {
|
new RowMapper() {
|
||||||
public Object mapRow(ResultSet rs, int i) throws SQLException {
|
public Object mapRow(ResultSet rs, int i) throws SQLException {
|
||||||
Map results = new HashMap();
|
Map results = new HashMap();
|
||||||
|
|
@ -2406,7 +2408,7 @@ clobReader.close();</programlisting>
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</programlisting>
|
]]></programlisting>
|
||||||
|
|
||||||
<calloutlist>
|
<calloutlist>
|
||||||
<callout arearefs="jdbc.lobhandler.setClob">
|
<callout arearefs="jdbc.lobhandler.setClob">
|
||||||
|
|
@ -2474,7 +2476,7 @@ clobReader.close();</programlisting>
|
||||||
interface is used as part of the declaration of an
|
interface is used as part of the declaration of an
|
||||||
<classname>SqlOutParameter</classname>.</para>
|
<classname>SqlOutParameter</classname>.</para>
|
||||||
|
|
||||||
<para><programlisting language="java">declareParameter(new SqlOutParameter("item", OracleTypes.STRUCT, "ITEM_TYPE",
|
<para><programlisting language="java"><![CDATA[declareParameter(new SqlOutParameter("item", OracleTypes.STRUCT, "ITEM_TYPE",
|
||||||
new SqlReturnType() {
|
new SqlReturnType() {
|
||||||
public Object getTypeValue(CallableStatement cs, int colIndx, int sqlType, String typeName)
|
public Object getTypeValue(CallableStatement cs, int colIndx, int sqlType, String typeName)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
|
|
@ -2486,7 +2488,7 @@ clobReader.close();</programlisting>
|
||||||
item.setExpirationDate((java.util.Date)attr[2]);
|
item.setExpirationDate((java.util.Date)attr[2]);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
}));</programlisting>Going from Java to the database and passing in the
|
}));]]></programlisting>Going from Java to the database and passing in the
|
||||||
value of a <classname>TestItem</classname> into a stored procedure is
|
value of a <classname>TestItem</classname> into a stored procedure is
|
||||||
done using the <classname>SqlTypeValue</classname>. The
|
done using the <classname>SqlTypeValue</classname>. The
|
||||||
<classname>SqlTypeValue</classname> interface has a single method named
|
<classname>SqlTypeValue</classname> interface has a single method named
|
||||||
|
|
@ -2495,7 +2497,7 @@ clobReader.close();</programlisting>
|
||||||
specific objects like <classname>StructDescriptor</classname>s or
|
specific objects like <classname>StructDescriptor</classname>s or
|
||||||
<classname>ArrayDescriptor</classname>s</para>
|
<classname>ArrayDescriptor</classname>s</para>
|
||||||
|
|
||||||
<para><programlisting language="java">SqlTypeValue value = new AbstractSqlTypeValue() {
|
<para><programlisting language="java"><![CDATA[SqlTypeValue value = new AbstractSqlTypeValue() {
|
||||||
protected Object createTypeValue(Connection conn, int sqlType, String typeName) throws SQLException {
|
protected Object createTypeValue(Connection conn, int sqlType, String typeName) throws SQLException {
|
||||||
StructDescriptor itemDescriptor = new StructDescriptor(typeName, conn);
|
StructDescriptor itemDescriptor = new StructDescriptor(typeName, conn);
|
||||||
Struct item = new STRUCT(itemDescriptor, conn,
|
Struct item = new STRUCT(itemDescriptor, conn,
|
||||||
|
|
@ -2506,9 +2508,9 @@ clobReader.close();</programlisting>
|
||||||
});
|
});
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
};</programlisting>This <classname>SqlTypeValue</classname> can now be added
|
};]]></programlisting>This <classname>SqlTypeValue</classname> can now be
|
||||||
to the Map containing the input parameters for the execute call of the
|
added to the Map containing the input parameters for the execute call of
|
||||||
stored procedure.</para>
|
the stored procedure.</para>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
</chapter>
|
</chapter>
|
||||||
Loading…
Reference in New Issue