Spring предоставляет отличную абстракцию поверх JDBC API с использованием JdbcTemplate, а также предоставляет отличные возможности управления транзакциями с использованием подхода на основе аннотаций.
Сначала давайте кратко рассмотрим, как мы обычно используем Spring JdbcTemplate ( без SpringBoot ), зарегистрировав bean- компоненты DataSource , TransactionManager и JdbcTemplate, и при желании мы можем зарегистрировать bean-компонент DataSourceInitializer для инициализации нашей базы данных.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
@Configuration @ComponentScan @EnableTransactionManagement @PropertySource (value = { "classpath:application.properties" }) public class AppConfig { @Autowired private Environment env; @Value ( "${init-db:false}" ) private String initDatabase; @Bean public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } @Bean public JdbcTemplate jdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); } @Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean public DataSource dataSource() { BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName(env.getProperty( "jdbc.driverClassName" )); dataSource.setUrl(env.getProperty( "jdbc.url" )); dataSource.setUsername(env.getProperty( "jdbc.username" )); dataSource.setPassword(env.getProperty( "jdbc.password" )); return dataSource; } @Bean public DataSourceInitializer dataSourceInitializer(DataSource dataSource) { DataSourceInitializer dataSourceInitializer = new DataSourceInitializer(); dataSourceInitializer.setDataSource(dataSource); ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); databasePopulator.addScript( new ClassPathResource( "data.sql" )); dataSourceInitializer.setDatabasePopulator(databasePopulator); dataSourceInitializer.setEnabled(Boolean.parseBoolean(initDatabase)); return dataSourceInitializer; } } |
С этой конфигурацией мы можем внедрить JdbcTemplate в компоненты доступа к данным для взаимодействия с базами данных.
1
2
3
4
5
6
7
8
|
public class User { private Integer id; private String name; private String email; // setters & getters } |
01
02
03
04
05
06
07
08
09
10
11
|
@Repository public class UserRepository { @Autowired private JdbcTemplate jdbcTemplate; @Transactional (readOnly= true ) public List<User> findAll() { return jdbcTemplate.query( "select * from users" , new UserRowMapper()); } } |
01
02
03
04
05
06
07
08
09
10
11
12
13
|
class UserRowMapper implements RowMapper<User> { @Override public User mapRow(ResultSet rs, int rowNum) throws SQLException { User user = new User(); user.setId(rs.getInt( "id" )); user.setName(rs.getString( "name" )); user.setEmail(rs.getString( "email" )); return user; } } |
Возможно, вы заметили, что в большинстве случаев мы используем подобную конфигурацию в наших приложениях.
Теперь давайте посмотрим, как использовать JdbcTemplate без необходимости настраивать все эти bean-компоненты вручную с помощью SpringBoot .
Использование JdbcTemplate с SpringBoot
Используя SpringBoot, мы можем воспользоваться функцией автоматической настройки и избавиться от необходимости настраивать компоненты самостоятельно.
Создайте проект на основе SpringBoot maven и добавьте модуль spring-boot-starter-jdbc.
1
2
3
4
|
< dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-jdbc</ artifactId > </ dependency > |
Добавив модуль spring-boot-starter-jdbc , мы получим следующую автоматическую конфигурацию:
- Модуль spring-boot-starter-jdbc транзитивно извлекает tomcat-jdbc- {version} .jar, который используется для настройки bean-компонента DataSource.
- Если вы не определили какой-либо компонент DataSource явно и если у вас есть какой-либо встроенный драйвер базы данных в пути к классам, такой как H2, HSQL или Derby, то SpringBoot автоматически зарегистрирует компонент DataSource с использованием настроек базы данных в памяти.
- Если вы не зарегистрировали ни один из следующих типов бинов, SpringBoot зарегистрирует их автоматически.
- PlatformTransactionManager (DataSourceTransactionManager)
- JdbcTemplate
- NamedParameterJdbcTemplate
- У нас могут быть файлы schema.sql и data.sql в корневом пути к классам, которые SpringBoot будет автоматически использовать для инициализации базы данных. В дополнение к schema.sql и data.sql Spring Boot будет загружать схему — $ {platform} .sql и data- $. Файлы {platform} .sql, если они доступны в корневом пути к классам. Здесь значением платформы является значение свойства spring.datasource.platform, которое может быть hsqldb, h2, oracle, mysql, postgresql и т. Д. Вы можете настроить имена скриптов по умолчанию, используя следующие свойства:
- spring.datasource.schema = создать-db.sql
- spring.datasource.data = семян data.sql
SpringBoot использует значение свойства spring.datasource.initialize , которое по умолчанию имеет значение true , чтобы определить, инициализировать базу данных или нет. Если вы хотите отключить инициализацию базы данных, вы можете установить spring.datasource.initialize = false
Если при выполнении скриптов возникают ошибки, приложение не запустится. Если вы хотите продолжить, вы можете установить spring.datasource.continueOnError = true .
Давайте добавим драйвер базы данных H2 в наш pom.xml .
1
2
3
4
|
< dependency > < groupId >com.h2database</ groupId > < artifactId >h2</ artifactId > </ dependency > |
Создайте schema.sql в src / main / resources следующим образом:
1
2
3
4
5
6
7
|
CREATE TABLE users ( id int (11) NOT NULL AUTO_INCREMENT, name varchar (100) NOT NULL , email varchar (100) DEFAULT NULL , PRIMARY KEY (id) ); |
Создайте data.sql в src / main / resources следующим образом:
1
2
3
|
|
Теперь вы можете добавить JdbcTemplate в UserRepository следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
@Repository public class UserRepository { @Autowired private JdbcTemplate jdbcTemplate; @Transactional (readOnly= true ) public List<User> findAll() { return jdbcTemplate.query( "select * from users" , new UserRowMapper()); } @Transactional (readOnly= true ) public User findUserById( int id) { return jdbcTemplate.queryForObject( "select * from users where id=?" , new Object[]{id}, new UserRowMapper()); } public User create( final User user) { final String sql = "insert into users(name,email) values(?,?)" ; KeyHolder holder = new GeneratedKeyHolder(); jdbcTemplate.update( new PreparedStatementCreator() { @Override public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); ps.setString( 1 , user.getName()); ps.setString( 2 , user.getEmail()); return ps; } }, holder); int newUserId = holder.getKey().intValue(); user.setId(newUserId); return user; } } class UserRowMapper implements RowMapper<User> { @Override public User mapRow(ResultSet rs, int rowNum) throws SQLException { User user = new User(); user.setId(rs.getInt( "id" )); user.setName(rs.getString( "name" )); user.setEmail(rs.getString( "email" )); return user; } } |
Создайте точку входа SpringbootJdbcDemoApplication.java .
1
2
3
4
5
6
7
8
|
@SpringBootApplication public class SpringbootJdbcDemoApplication { public static void main(String[] args) { SpringApplication.run(SpringbootJdbcDemoApplication. class , args); } } |
Давайте создадим класс JUnit Test для тестирования наших методов UserRepository.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
@RunWith (SpringJUnit4ClassRunner. class ) @SpringApplicationConfiguration (SpringbootJdbcDemoApplication. class ) public class SpringbootJdbcDemoApplicationTests { @Autowired private UserRepository userRepository; @Test public void findAllUsers() { List<User> users = userRepository.findAll(); assertNotNull(users); assertTrue(!users.isEmpty()); } @Test public void findUserById() { User user = userRepository.findUserById( 1 ); assertNotNull(user); } @Test public void createUser() { User savedUser = userRepository.create(user); User newUser = userRepository.findUserById(savedUser.getId()); assertNotNull(newUser); assertEquals( "John" , newUser.getName()); } } |
По умолчанию такие функции SpringBoot, как внешние свойства, ведение журналов и т. Д., Доступны в ApplicationContext, только если вы используете SpringApplication . Итак, SpringBoot предоставляет аннотацию @SpringApplicationConfiguration для настройки ApplicationContext для тестов, которые используют SpringApplication за кулисами.
Мы узнали, как быстро начать работу со встроенной базой данных. Что если мы хотим использовать не встроенные базы данных, такие как MySQL, Oracle, PostgreSQL и т. Д.? ,
Мы можем настроить свойства базы данных в файле application.properties, чтобы SpringBoot использовал эти параметры jdbc для настройки bean-компонента DataSource.
1
2
3
4
|
spring.datasource.driver- class -name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql: //localhost:3306/test spring.datasource.username=root spring.datasource.password=admin |
По любой причине, если вы хотите больше контролировать и настраивать компонент DataSource самостоятельно, вы можете настроить компонент DataSource в классе Configuration. Если вы зарегистрируете компонент DataSource, SpringBoot не будет автоматически конфигурировать DataSource с помощью автоконфигурации. Что если вы хотите использовать другую библиотеку пулов соединений?
SpringBoot по умолчанию загружает tomcat-jdbc- {version} .jar и использует org.apache.tomcat.jdbc.pool.DataSource для настройки bean-компонента DataSource .
SpringBoot проверяет доступность следующих классов и использует первый, который доступен в classpath.
- org.apache.tomcat.jdbc.pool.DataSource
- com.zaxxer.hikari.HikariDataSource
- org.apache.commons.dbcp.BasicDataSource
- org.apache.commons.dbcp2.BasicDataSource
Например, если вы хотите использовать HikariDataSource, вы можете исключить tomcat-jdbc и добавить зависимость HikariCP следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
< dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-jdbc</ artifactId > < exclusions > < exclusion > < groupId >org.apache.tomcat</ groupId > < artifactId >tomcat-jdbc</ artifactId > </ exclusion > </ exclusions > </ dependency > < dependency > < groupId >com.zaxxer</ groupId > < artifactId >HikariCP</ artifactId > </ dependency > |
С этой конфигурацией зависимостей SpringBoot будет использовать HikariCP для настройки bean-компонента DataSource .
Ссылка: | SpringBoot: Работа с JdbcTemplate от нашего партнера по JCG Сивы Редди в блоге « Мои эксперименты по технологии» . |