@@ -3779,7 +3779,7 @@ as input. See the next section for details on how to define an `SqlParameter`.
3779
3779
Explicit declarations are necessary if the database you use is not a Spring-supported
3780
3780
database. Currently Spring supports metadata lookup of stored procedure calls for the
3781
3781
following databases: Apache Derby, DB2, MySQL, Microsoft SQL Server, Oracle, and Sybase.
3782
- We also support metadata lookup of stored functions for: MySQL, Microsoft SQL Server,
3782
+ We also support metadata lookup of stored functions for MySQL, Microsoft SQL Server,
3783
3783
and Oracle.
3784
3784
====
3785
3785
@@ -4615,9 +4615,10 @@ testability, and the ability to rapidly evolve SQL during development.
4615
4615
4616
4616
4617
4617
[[jdbc-embedded-database-xml]]
4618
- ==== Creating an embedded database instance using Spring XML
4618
+ ==== Creating an embedded database using Spring XML
4619
+
4619
4620
If you want to expose an embedded database instance as a bean in a Spring
4620
- ApplicationContext, use the embedded-database tag in the spring-jdbc namespace:
4621
+ ` ApplicationContext` , use the ` embedded-database` tag in the ` spring-jdbc` namespace:
4621
4622
4622
4623
[source,xml,indent=0]
4623
4624
[subs="verbatim,quotes"]
@@ -4629,37 +4630,66 @@ ApplicationContext, use the embedded-database tag in the spring-jdbc namespace:
4629
4630
----
4630
4631
4631
4632
The preceding configuration creates an embedded HSQL database populated with SQL from
4632
- schema.sql and testdata .sql resources in the classpath. The database instance is made
4633
- available to the Spring container as a bean of type `javax.sql.DataSource`. This bean
4634
- can then be injected into data access objects as needed.
4633
+ ` schema.sql` and `test-data .sql` resources in the root of the root of the classpath. The
4634
+ database instance is made available to the Spring container as a bean of type
4635
+ `javax.sql.DataSource`. This bean can then be injected into data access objects as needed.
4635
4636
4636
4637
4637
4638
4638
4639
[[jdbc-embedded-database-java]]
4639
- ==== Creating an embedded database instance programmatically
4640
+ ==== Creating an embedded database programmatically
4641
+
4640
4642
The `EmbeddedDatabaseBuilder` class provides a fluent API for constructing an embedded
4641
- database programmatically. Use this when you need to create an embedded database
4642
- instance in a standalone environment, such as a data access object unit test:
4643
+ database programmatically. Use this when you need to create an embedded database in a
4644
+ standalone environment or in a standalone integration test:
4643
4645
4644
4646
[source,java,indent=0]
4645
4647
[subs="verbatim,quotes"]
4646
4648
----
4647
- EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
4648
- EmbeddedDatabase db = builder.setType(H2).addScript("my-schema.sql").addScript("my-test-data.sql").build();
4649
- // do stuff against the db (EmbeddedDatabase extends javax.sql.DataSource)
4650
- db.shutdown()
4649
+ EmbeddedDatabase db = new EmbeddedDatabaseBuilder()
4650
+ .setType(H2)
4651
+ .setScriptEncoding("UTF-8")
4652
+ .ignoreFailedDrops(true)
4653
+ .addScript("schema.sql")
4654
+ .addScripts("user_data.sql", "country_data.sql")
4655
+ .build();
4656
+
4657
+ // do stuff against the db (EmbeddedDatabase extends javax.sql.DataSource)
4658
+
4659
+ db.shutdown()
4660
+ ----
4661
+
4662
+ The `EmbeddedDatabaseBuilder` can also be used to create an embedded database using Java
4663
+ Config like in the following example.
4664
+
4665
+ [source,java,indent=0]
4666
+ [subs="verbatim,quotes"]
4651
4667
----
4668
+ @Configuration
4669
+ public class DataSourceConfig {
4652
4670
4671
+ @Bean
4672
+ public DataSource dataSource() {
4673
+ return new EmbeddedDatabaseBuilder()
4674
+ .setType(H2)
4675
+ .setScriptEncoding("UTF-8")
4676
+ .ignoreFailedDrops(true)
4677
+ .addScript("schema.sql")
4678
+ .addScripts("user_data.sql", "country_data.sql")
4679
+ .build();
4680
+ }
4681
+ }
4682
+ ----
4653
4683
4654
4684
4655
4685
[[jdbc-embedded-database-extension]]
4656
4686
==== Extending the embedded database support
4687
+
4657
4688
Spring JDBC embedded database support can be extended in two ways:
4658
4689
4659
- * Implement `EmbeddedDatabaseConfigurer` to support a new embedded database type, such
4660
- as Apache Derby.
4661
- * Implement `DataSourceFactory` to support a new DataSource implementation, such as a
4662
- connection pool, to manage embedded database connections.
4690
+ * Implement `EmbeddedDatabaseConfigurer` to support a new embedded database type.
4691
+ * Implement `DataSourceFactory` to support a new `DataSource` implementation, such as a
4692
+ connection pool to manage embedded database connections.
4663
4693
4664
4694
You are encouraged to contribute back extensions to the Spring community at
4665
4695
https://jira.spring.io/browse/SPR[jira.spring.io].
@@ -4668,8 +4698,8 @@ https://jira.spring.io/browse/SPR[jira.spring.io].
4668
4698
4669
4699
[[jdbc-embedded-database-using-HSQL]]
4670
4700
==== Using HSQL
4671
- Spring supports HSQL 1.8.0 and above. HSQL is the default embedded database if no type
4672
- is specified explicitly. To specify HSQL explicitly, set the `type` attribute of the
4701
+ Spring supports HSQL 1.8.0 and above. HSQL is the default embedded database if no type is
4702
+ specified explicitly. To specify HSQL explicitly, set the `type` attribute of the
4673
4703
`embedded-database` tag to `HSQL`. If you are using the builder API, call the
4674
4704
`setType(EmbeddedDatabaseType)` method with `EmbeddedDatabaseType.HSQL`.
4675
4705
@@ -4686,20 +4716,27 @@ Spring supports the H2 database as well. To enable H2, set the `type` attribute
4686
4716
[[jdbc-embedded-database-using-Derby]]
4687
4717
==== Using Derby
4688
4718
Spring also supports Apache Derby 10.5 and above. To enable Derby, set the `type`
4689
- attribute of the `embedded-database` tag to `Derby `. If using the builder API, call the
4690
- `setType(EmbeddedDatabaseType)` method with `EmbeddedDatabaseType.Derby `.
4719
+ attribute of the `embedded-database` tag to `DERBY `. If you are using the builder API,
4720
+ call the `setType(EmbeddedDatabaseType)` method with `EmbeddedDatabaseType.DERBY `.
4691
4721
4692
4722
4693
4723
4694
4724
[[jdbc-embedded-database-dao-testing]]
4695
4725
==== Testing data access logic with an embedded database
4696
- Embedded databases provide a lightweight way to test data access code. The following is
4697
- a data access unit test template that uses an embedded database:
4726
+
4727
+ Embedded databases provide a lightweight way to test data access code. The following is a
4728
+ data access integration test template that uses an embedded database. Using a template
4729
+ like this can be useful for _one-offs_ when the embedded database does not need to be
4730
+ reused across test classes. However, if you wish to create an embedded database that is
4731
+ shared within a test suite, consider using the <<testcontext-framework,Spring TestContext
4732
+ Framework>> and configuring the embedded database as a bean in the Spring
4733
+ `ApplicationContext` as described in <<jdbc-embedded-database-xml>> and
4734
+ <<jdbc-embedded-database-java>>.
4698
4735
4699
4736
[source,java,indent=0]
4700
4737
[subs="verbatim,quotes"]
4701
4738
----
4702
- public class DataAccessUnitTestTemplate {
4739
+ public class DataAccessIntegrationTestTemplate {
4703
4740
4704
4741
private EmbeddedDatabase db;
4705
4742
@@ -4713,7 +4750,7 @@ a data access unit test template that uses an embedded database:
4713
4750
@Test
4714
4751
public void testDataAccess() {
4715
4752
JdbcTemplate template = new JdbcTemplate(db);
4716
- template.query(...);
4753
+ template.query( /* ... */ );
4717
4754
}
4718
4755
4719
4756
@After
@@ -4726,7 +4763,6 @@ a data access unit test template that uses an embedded database:
4726
4763
4727
4764
4728
4765
4729
-
4730
4766
[[jdbc-intializing-datasource]]
4731
4767
=== Initializing a DataSource
4732
4768
The `org.springframework.jdbc.datasource.init` package provides support for initializing
@@ -4737,8 +4773,8 @@ an instance running on a server somewhere.
4737
4773
4738
4774
4739
4775
[[jdbc-initializing-datasource-xml]]
4740
- ==== Initializing a database instance using Spring XML
4741
- If you want to initialize a database and you can provide a reference to a DataSource
4776
+ ==== Initializing a database using Spring XML
4777
+ If you want to initialize a database and you can provide a reference to a ` DataSource`
4742
4778
bean, use the `initialize-database` tag in the `spring-jdbc` namespace:
4743
4779
4744
4780
[source,xml,indent=0]
@@ -4750,23 +4786,24 @@ bean, use the `initialize-database` tag in the `spring-jdbc` namespace:
4750
4786
</jdbc:initialize-database>
4751
4787
----
4752
4788
4753
- The example above runs the two scripts specified against the database: the first script
4754
- is a schema creation, and the second is a test data set insert. The script locations can
4755
- also be patterns with wildcards in the usual ant style used for resources in Spring
4756
- (e.g. `classpath{asterisk}:/com/foo/{asterisk}{asterisk}/sql/{asterisk}-data.sql`).
4757
- If a pattern is used the scripts are executed in lexical order of their URL or filename.
4789
+ The example above executes the two scripts specified against the database: the first
4790
+ script creates a schema, and the second populates tables with a test data set. The script
4791
+ locations can also be patterns with wildcards in the usual ant style used for resources
4792
+ in Spring (e.g.
4793
+ `classpath{asterisk}:/com/foo/{asterisk}{asterisk}/sql/{asterisk}-data.sql`). If a
4794
+ pattern is used, the scripts are executed in lexical order of their URL or filename.
4758
4795
4759
4796
The default behavior of the database initializer is to unconditionally execute the
4760
- scripts provided. This will not always be what you want, for instance if running against
4761
- an existing database that already has test data in it. The likelihood of accidentally
4762
- deleting data is reduced by the commonest pattern (as shown above) that creates the
4763
- tables first and then inserts the data - the first step will fail if the tables already
4764
- exist.
4797
+ scripts provided. This will not always be what you want, for instance, if you are
4798
+ executing the scripts against a database that already has test data in it. The likelihood
4799
+ of accidentally deleting data is reduced by following the common pattern (as shown above)
4800
+ of creating the tables first and then inserting the data -- the first step will fail if
4801
+ the tables already exist.
4765
4802
4766
- However, to get more control over the creation and deletion of existing data, the XML
4767
- namespace provides a couple more options. The first is flag to switch the initialization
4768
- on and off. This can be set according to the environment (e.g. to pull a boolean value
4769
- from system properties or an environment bean), e.g.
4803
+ However, to gain more control over the creation and deletion of existing data, the XML
4804
+ namespace provides a few additional options. The first is a flag to switch the
4805
+ initialization on and off. This can be set according to the environment (e.g. to pull a
4806
+ boolean value from system properties or an environment bean), for example:
4770
4807
4771
4808
[source,xml,indent=0]
4772
4809
[subs="verbatim,quotes"]
@@ -4779,7 +4816,7 @@ from system properties or an environment bean), e.g.
4779
4816
4780
4817
The second option to control what happens with existing data is to be more tolerant of
4781
4818
failures. To this end you can control the ability of the initializer to ignore certain
4782
- errors in the SQL it executes from the scripts, e.g.
4819
+ errors in the SQL it executes from the scripts, for example:
4783
4820
4784
4821
[source,xml,indent=0]
4785
4822
[subs="verbatim,quotes"]
@@ -4789,62 +4826,68 @@ errors in the SQL it executes from the scripts, e.g.
4789
4826
</jdbc:initialize-database>
4790
4827
----
4791
4828
4792
- In this example we are saying we expect that sometimes the scripts will be run against
4793
- an empty database and there are some DROP statements in the scripts which would
4794
- therefore fail. So failed SQL `DROP` statements will be ignored, but other failures will
4795
- cause an exception. This is useful if your SQL dialect doesn't support `DROP ... IF
4829
+ In this example we are saying we expect that sometimes the scripts will be executed
4830
+ against an empty database, and there are some ` DROP` statements in the scripts which
4831
+ would therefore fail. So failed SQL `DROP` statements will be ignored, but other failures
4832
+ will cause an exception. This is useful if your SQL dialect doesn't support `DROP ... IF
4796
4833
EXISTS` (or similar) but you want to unconditionally remove all test data before
4797
- re-creating it. In that case the first script is usually a set of drops, followed by a
4798
- set of `CREATE` statements.
4834
+ re-creating it. In that case the first script is usually a set of `DROP` statements,
4835
+ followed by a set of `CREATE` statements.
4799
4836
4800
4837
The `ignore-failures` option can be set to `NONE` (the default), `DROPS` (ignore failed
4801
- drops) or `ALL` (ignore all failures).
4838
+ drops), or `ALL` (ignore all failures).
4802
4839
4803
4840
If you need more control than you get from the XML namespace, you can simply use the
4804
- `DataSourceInitializer` directly, and define it as a component in your application.
4841
+ `DataSourceInitializer` directly and define it as a component in your application.
4805
4842
4806
4843
4807
4844
[[jdbc-client-component-initialization]]
4808
- ===== Initialization of Other Components that Depend on the Database
4845
+ ===== Initialization of other components that depend on the database
4846
+
4809
4847
A large class of applications can just use the database initializer with no further
4810
4848
complications: those that do not use the database until after the Spring context has
4811
- started. If your application is __not__ one of those then you might need to read the
4812
- rest of this section.
4849
+ started. If your application is __not__ one of those then you might need to read the rest
4850
+ of this section.
4813
4851
4814
- The database initializer depends on a data source instance and runs the scripts provided
4815
- in its initialization callback (c.f. `init-method` in an XML bean definition or
4816
- `InitializingBean`). If other beans depend on the same data source and also use the data
4817
- source in an initialization callback then there might be a problem because the data has
4818
- not yet been initialized. A common example of this is a cache that initializes eagerly
4819
- and loads up data from the database on application startup.
4852
+ The database initializer depends on a `DataSource` instance and executes the scripts
4853
+ provided in its initialization callback (analogous to an `init-method` in an XML bean
4854
+ definition, a `@PostConstruct` method in a component, or the `afterPropertiesSet()`
4855
+ method in a component that implements `InitializingBean`). If other beans depend on the
4856
+ same data source and also use the data source in an initialization callback, then there
4857
+ might be a problem because the data has not yet been initialized. A common example of
4858
+ this is a cache that initializes eagerly and loads data from the database on application
4859
+ startup.
4820
4860
4821
- To get round this issue you two options: change your cache initialization strategy to a
4822
- later phase, or ensure that the database initializer is initialized first.
4861
+ To get around this issue you have two options: change your cache initialization strategy
4862
+ to a later phase, or ensure that the database initializer is initialized first.
4823
4863
4824
4864
The first option might be easy if the application is in your control, and not otherwise.
4825
- Some suggestions for how to implement this are
4865
+ Some suggestions for how to implement this include:
4826
4866
4827
- * Make the cache initialize lazily on first usage, which improves application startup time
4867
+ * Make the cache initialize lazily on first usage, which improves application startup
4868
+ time.
4828
4869
* Have your cache or a separate component that initializes the cache implement
4829
4870
`Lifecycle` or `SmartLifecycle`. When the application context starts up a
4830
4871
`SmartLifecycle` can be automatically started if its `autoStartup` flag is set, and a
4831
- `Lifecycle` can be started manually by calling
4832
- `ConfigurableApplicationContext.start()` on the enclosing context.
4872
+ `Lifecycle` can be started manually by calling `ConfigurableApplicationContext.start()`
4873
+ on the enclosing context.
4833
4874
* Use a Spring `ApplicationEvent` or similar custom observer mechanism to trigger the
4834
4875
cache initialization. `ContextRefreshedEvent` is always published by the context when
4835
4876
it is ready for use (after all beans have been initialized), so that is often a useful
4836
4877
hook (this is how the `SmartLifecycle` works by default).
4837
4878
4838
- The second option can also be easy. Some suggestions on how to implement this are
4839
-
4840
- * Rely on Spring BeanFactory default behavior, which is that beans are initialized in
4841
- registration order. You can easily arrange that by adopting the common practice of a
4842
- set of <import/> elements that order your application modules, and ensure that the
4843
- database and database initialization are listed first
4844
- * Separate the datasource and the business components that use it and control their
4845
- startup order by putting them in separate ApplicationContext instances (e.g. parent
4846
- has the datasource and child has the business components). This structure is common in
4847
- Spring web applications, but can be more generally applied.
4879
+ The second option can also be easy. Some suggestions on how to implement this include:
4880
+
4881
+ * Rely on the default behavior of the Spring `BeanFactory`, which is that beans are
4882
+ initialized in registration order. You can easily arrange that by adopting the common
4883
+ practice of a set of `<import/>` elements in XML configuration that order your
4884
+ application modules, and ensure that the database and database initialization are
4885
+ listed first.
4886
+ * Separate the `DataSource` and the business components that use it, and control their
4887
+ startup order by putting them in separate `ApplicationContext` instances (e.g. the
4888
+ parent context contains the `DataSource`, and child context contains the business
4889
+ components). This structure is common in Spring web applications but can be more
4890
+ generally applied.
4848
4891
4849
4892
4850
4893
0 commit comments