@@ -1223,4 +1223,288 @@ Spring Boot 包括对以下内嵌响应式 Web 服务器的支持:Reactor Nett
1223
1223
1224
1224
您可以在 [ WebClient Runtime] ( #boot-features-webclient-runtime ) 章节中了解有关客户端资源配置的更多内容。
1225
1225
1226
+ <a id =" boot-features-sql " ></a >
1227
+
1228
+ ## 30、使用 SQL 数据库
1229
+
1230
+ [ Spring Framework] ( https://projects.spring.io/spring-framework/ ) 为 SQL 数据库提供了广泛的支持。从直接使用 ` JdbcTemplate ` 进行 JDBC 访问到完全的** 对象关系映射** (object relational mapping)技术,比如 Hibernate。[ Spring Data] ( https://projects.spring.io/spring-data/ ) 提供了更多级别的功能,直接从接口创建的 ` Repository ` 实现,并使用了约定从方法名生成查询。
1231
+
1232
+ <a id =" boot-features-configure-datasource " ></a >
1233
+
1234
+ ### 30.1、配置数据源
1235
+
1236
+ Java 的 ` javax.sql.DataSource ` 接口提供了一个使用数据库连接的标准方法。通常,数据源使用 ` URL ` 和一些凭据信息来建立数据库连接。
1237
+
1238
+ ** 提示**
1239
+
1240
+ > 查看 [ How-to] ( #howto-configure-a-datasource ) 部分获取更多高级示例,通常您可以完全控制数据库的配置。
1241
+
1242
+ <a id =" boot-features-embedded-database-support " ></a >
1243
+
1244
+ #### 30.1.1、内嵌数据库支持
1245
+
1246
+ 使用内嵌内存数据库来开发应用程序非常方便的。显然,内存数据库不提供持久存储。在应用启动时,您需要填充数据库,并在应用程序结束时丢弃数据。
1247
+
1248
+ ** 提示**
1249
+
1250
+ > ** How-to** 部分包含了[ 如何初始化数据库] ( #howto-database-initialization ) 部分
1251
+
1252
+ Spring Boot 可以自动配置内嵌 [ H2] ( http://www.h2database.com/ ) 、[ HSQL] ( http://hsqldb.org/ ) 和 [ Derby] ( https://db.apache.org/derby/ ) 数据库。您不需要提供任何连接 URL,只需为您想要使用的内嵌数据库引入特定的构建依赖。
1253
+
1254
+ ** 注意**
1255
+
1256
+ > 如果您在测试中使用此功能,您可能会注意到,无论使用了多少应用程序上下文,整个测试套件都会重复使用相同的数据库。如果您想确保每个上下文都有一个单独的内嵌数据库,则应该将 ` spring.datasource.generate-unique-name ` 设置为 ` true ` 。
1257
+
1258
+ 以下是 POM 依赖示例:
1259
+
1260
+ ``` xml
1261
+ <dependency >
1262
+ <groupId >org.springframework.boot</groupId >
1263
+ <artifactId >spring-boot-starter-data-jpa</artifactId >
1264
+ </dependency >
1265
+ <dependency >
1266
+ <groupId >org.hsqldb</groupId >
1267
+ <artifactId >hsqldb</artifactId >
1268
+ <scope >runtime</scope >
1269
+ </dependency >
1270
+ ```
1271
+
1272
+ ** 注意**
1273
+
1274
+ > 要自动配置内嵌数据库,您需要一个 ` spring-jdbc ` 依赖。在这个例子中,它是通过 ` spring-boot-starter-data-jpa ` 引入。
1275
+
1276
+ ** 提示**
1277
+
1278
+ > 如果出于某些原因,您需要配置内嵌数据库的连接 URL,则应注意确保禁用数据库的自动关闭功能。如果您使用 H2,则应该使用 ` DB_CLOSE_ON_EXIT=FALSE ` 来设置。如果您使用 ` HSQLDB ` ,则确保不使用 ` shutdown=true ` 。禁用数据库的自动关闭功能允许 Spring Boot 控制数据库何时关闭,从而确保一旦不再需要访问数据库时就触发。
1279
+
1280
+ <a id =" boot-features-connect-to-production-database " ></a >
1281
+
1282
+ #### 30.1.2、连接生产数据库
1283
+
1284
+ 生产数据库连接也可以使用使用 ` DataSource ` 自动配置。Spring Boot 使用以下算法来选择一个特定的实现:
1285
+
1286
+ - 出于性能和并发性的考虑,我们更喜欢 [ HikariCP] ( https://github.com/brettwooldridge/HikariCP ) 连接池。如果 HikariCP 可用,我们总是选择它。
1287
+ - 否则,如果 Tomcat 池 ` DataSource ` 可用,我们将使用它。
1288
+ - 如果 HikariCP 和 Tomcat 池数据源不可用,但 [ Commons DBCP] ( https://commons.apache.org/proper/commons-dbcp/ ) 可用,我们将使用它。
1289
+
1290
+ 如果您使用了 ` spring-boot-starter-jdbc ` 或者 ` spring-boot-starter-data-jpa ` starter,您将自动得到 ` HikariCP ` 依赖。
1291
+
1292
+ ** 注意**
1293
+
1294
+ > 您完全可以绕过该算法,并通过 ` spring.datasource.type ` 属性指定要使用的连接池。如果您在 Tomcat 容器中运行应用程序,默认提供 ` tomcat-jdbc ` ,这点尤其重要。
1295
+
1296
+ ** 提示**
1297
+
1298
+ > 可以手动配置其他连接池。如果您定义了自己的 ` DataSource ` bean,则自动配置将不会触发。
1299
+
1300
+ 数据源配置由 ` spring.datasource.* ` 中的外部属性所控制。例如,您可以在 ` application.properties ` 中声明以下部分:
1301
+
1302
+ ``` ini
1303
+ spring.datasource.url =jdbc:mysql://localhost/test
1304
+ spring.datasource.username =dbuser
1305
+ spring.datasource.password =dbpass
1306
+ spring.datasource.driver-class-name =com.mysql.jdbc.Driver
1307
+ ```
1308
+
1309
+ ** 注意**
1310
+
1311
+ > 您至少应该使用 ` spring.datasource.url ` 属性来指定 URL,否则 Spring Boot 将尝试自动配置内嵌数据库。
1312
+
1313
+ ** 提示**
1314
+
1315
+ > 通常您不需要指定 ` driver-class-name ` ,因为 Spring boot 可以从 ` url ` 推导出大多数数据库。
1316
+
1317
+ ** 注意**
1318
+
1319
+ 对于要创建的池 ` DataSource ` ,我们需要能够验证有效的 ` Driver ` 类是否可用,因此我们在使用之前进行检查。例如,如果您设置了 ` spring.datasource.driver-class-name=com.mysql.jdbc.Driver ` ,那么该类必须可加载。
1320
+
1321
+ 有关更多支持选项,请参阅 [ DataSourceProperties] ( https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java ) 。这些都是标准选项,与实际的实现无关。还可以使用各自的前缀(` spring.datasource.hikari.* ` 、` spring.datasource.tomcat.* ` 和 ` spring.datasource.dbcp2.* ` )微调实现特定的设置。请参考您现在使用的连接池实现的文档来获取更多信息。
1322
+
1323
+ 例如,如果你使用 [ Tomcat 连接池] ( https://tomcat.apache.org/tomcat-8.0-doc/jdbc-pool.html#Common_Attributes ) ,则可以自定义许多其他设置,如下:
1324
+
1325
+ ``` ini
1326
+ # Number of ms to wait before throwing an exception if no connection is available.
1327
+ spring.datasource.tomcat.max-wait =10000
1328
+
1329
+ # Maximum number of active connections that can be allocated from this pool at the same time.
1330
+ spring.datasource.tomcat.max-active =50
1331
+
1332
+ # Validate the connection before borrowing it from the pool.
1333
+ spring.datasource.tomcat.test-on-borrow =true
1334
+ ```
1335
+
1336
+ <a id =" boot-features-connecting-to-a-jndi-datasource " ></a >
1337
+
1338
+ #### 30.1.3、连接 JNDI 数据源
1339
+
1340
+ 如果要将 Spring Boot 应用程序部署到应用服务器(Application Server)上,您可能想使用应用服务器的内置功能和 JNDI 访问方式来配置和管理数据源。
1341
+
1342
+ ` spring.datasource.jndi-name ` 属性可作为 ` spring.datasource.url ` 、` spring.datasource.username ` 和 ` spring.datasource.password ` 属性的替代方法,用于从特定的 JNDI 位置访问 ` DataSource ` 。例如,` application.properties ` 中的以下部分展示了如何访问 JBoss AS 定义的 ` DataSource ` :
1343
+
1344
+ ``` ini
1345
+ spring.datasource.jndi-name =java:jboss/datasources/customers
1346
+ ```
1347
+
1348
+ <a id =" boot-features-using-jdbc-template " ></a >
1349
+
1350
+ ### 30.2、使用 JdbcTemplate
1351
+
1352
+ Spring 的 ` JdbcTemplate ` 和 ` NamedParameterJdbcTemplate ` 类是自动配置的,您可以使用 ` @Autowire ` 将它们直接注入您的 bean 中:
1353
+
1354
+ ``` java
1355
+ import org.springframework.beans.factory.annotation.Autowired ;
1356
+ import org.springframework.jdbc.core.JdbcTemplate ;
1357
+ import org.springframework.stereotype.Component ;
1358
+
1359
+ @Component
1360
+ public class MyBean {
1361
+
1362
+ private final JdbcTemplate jdbcTemplate;
1363
+
1364
+ @Autowired
1365
+ public MyBean (JdbcTemplate jdbcTemplate ) {
1366
+ this . jdbcTemplate = jdbcTemplate;
1367
+ }
1368
+
1369
+ // ...
1370
+
1371
+ }
1372
+ ```
1373
+
1374
+ 您可以使用 ` spring.jdbc.template.* ` 属性来自定义一些 template 的属性,如下:
1375
+
1376
+ ``` ini
1377
+ spring.jdbc.template.max-rows =500
1378
+ ```
1379
+
1380
+ ** 注意**
1381
+
1382
+ > ` NamedParameterJdbcTemplate ` 在底层重用了相同的 ` JdbcTemplate ` 实例。如果定义了多个 ` JdbcTemplate ` 且没有声明 primary 主候选,则不会自动配置 ` NamedParameterJdbcTemplate ` 。
1383
+
1384
+ <a id =" boot-features-jpa-and-spring-data " ></a >
1385
+
1386
+ ### 30.3、JPA 与 Spring Data JPA
1387
+
1388
+ Java Persistence API(Java 持久化 API)是一项标准技术,可让您将对象** 映射** 到关系数据库。` spring-boot-starter-data-jpa ` POM 提供了一个快速起步的方法。它提供了以下关键依赖:
1389
+
1390
+ - ** Hibernate** —— 最受欢迎的 JPA 实现之一。
1391
+ - ** Spring Data JPA ** —— 可以轻松地实现基于 JPA 的资源库。
1392
+ - ** Spring ORM** —— Spring Framework 的核心 ORM 支持
1393
+
1394
+ ** 提示**
1395
+
1396
+ 我们不会在这里介绍太多关于 JPA 或者 [ Spring Data] ( https://projects.spring.io/spring-data/ ) 的相关内容。您可以在 [ spring.io] ( https://spring.io/ ) 上查看[ 使用 JPA 访问数据] ( https://spring.io/guides/gs/accessing-data-jpa/ ) ,获取阅读 [ Spring Data JPA] ( https://projects.spring.io/spring-data-jpa/ ) 和 [ Hibernate] ( https://hibernate.org/orm/documentation/ ) 的参考文档。
1397
+
1398
+ <a id =" boot-features-jpa-and-spring-data " ></a >
1399
+
1400
+ #### 30.3.1、实体类
1401
+
1402
+ 通常,JPA ** Entity** (实体)类是在 ` persistence.xml ` 文件中指定的。使用了 Spring Boot,该文件将不是必需的,可以使用 ** Entity Scanning** (实体扫描)来代替。默认情况下,将搜索主配置类(使用了 ` @EnableAutoConfiguration ` 或 ` @SpringBootApplication ` 注解)下面的所有包。
1403
+
1404
+ 任何用了 ` @Entity ` 、` @Embeddable ` 或者 ` @MappedSuperclass ` 注解的类将被考虑。一个典型的实体类如下:
1405
+
1406
+ ``` java
1407
+ package com.example.myapp.domain ;
1408
+
1409
+ import java.io.Serializable ;
1410
+ import javax.persistence.* ;
1411
+
1412
+ @Entity
1413
+ public class City implements Serializable {
1414
+
1415
+ @Id
1416
+ @GeneratedValue
1417
+ private Long id;
1418
+
1419
+ @Column (nullable = false )
1420
+ private String name;
1421
+
1422
+ @Column (nullable = false )
1423
+ private String state;
1424
+
1425
+ // ... additional members, often include @OneToMany mappings
1426
+
1427
+ protected City () {
1428
+ // no-args constructor required by JPA spec
1429
+ // this one is protected since it shouldn't be used directly
1430
+ }
1431
+
1432
+ public City (String name , String state ) {
1433
+ this . name = name;
1434
+ this . state = state;
1435
+ }
1436
+
1437
+ public String getName () {
1438
+ return this . name;
1439
+ }
1440
+
1441
+ public String getState () {
1442
+ return this . state;
1443
+ }
1444
+
1445
+ // ... etc
1446
+
1447
+ }
1448
+ ```
1449
+
1450
+ ** 提示**
1451
+
1452
+ > 您可以使用 ` @EntityScan ` 注解自定义实体类的扫描位置。请参见[ 84.4、从 Spring configuration 配置中分离 @Entity 定义] ( https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#howto-separate-entity-definitions-from-spring-configuration ) 章节。
1453
+
1454
+ <a id =" boot-features-spring-data-jpa-repositories " ></a >
1455
+
1456
+ #### 30.3.2、Spring Data JPA 资源库
1457
+
1458
+ [ Spring Data JPA] ( https://projects.spring.io/spring-data-jpa/ ) 资源库(repository)是接口,您可以定义用于访问数据。JAP 查询是根据您的方法名自动创建。例如,` CityRepository ` 接口可以声明 ` findAllByState(String state) ` 方法来查找指定状态下的所有城市。
1459
+
1460
+ 对于更加复杂的查询,您可以使用 Spring Data 的 [ ` Query ` ] ( https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/Query.html ) 注解
1461
+
1462
+ Spring Data 资源库通常继承自 [ Repository] ( https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/Repository.html ) 或者 [ CrudRepository] ( https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html ) 接口。如果您使用了自动配置,则将从包含主配置类(使用了 ` @EnableAutoConfiguration ` 或 ` @SpringBootApplication ` 注解)的包中搜索资源库:
1463
+
1464
+ 以下是一个典型的 Spring Data 资源库接口定义:
1465
+
1466
+ ``` java
1467
+ package com.example.myapp.domain ;
1468
+
1469
+ import org.springframework.data.domain.* ;
1470
+ import org.springframework.data.repository.* ;
1471
+
1472
+ public interface CityRepository extends Repository<City , Long > {
1473
+
1474
+ Page<City > findAll (Pageable pageable );
1475
+
1476
+ City findByNameAndStateAllIgnoringCase (String name , String state );
1477
+
1478
+ }
1479
+ ```
1480
+
1481
+ Spring Data JPA 资源库支持三种不同的引导模式:default、deferred 和 lazy。要启用延迟或懒惰引导,请将 ` spring.data.jpa.repositories.bootstrap-mode ` 分别设置为 ` deferred ` 或 ` lazy ` 。使用延迟或延迟引导时,自动配置的 ` EntityManagerFactoryBuilder ` 将使用上下文的异步任务执行器(如果有)作为引导程序执行器。
1482
+
1483
+ ** 提示**
1484
+
1485
+ > 我们几乎没有接触到 Spring Data JPA 的表面内容。有关详细信息,请查阅 [ Spring Data JPA 参考文档] ( https://docs.spring.io/spring-data/jpa/docs/current/reference/html/ ) 。
1486
+
1487
+
1488
+ <a id =" boot-features-creating-and-dropping-jpa-databases " ></a >
1489
+
1490
+ #### 30.3.3、创建和删除 JPA 数据库
1491
+
1492
+ 默认情况下,** 仅** 当您使用了内嵌数据库(H2、HSQL 或 Derby)时才会自动创建 JPA 数据库。您可以使用 ` spring.jpa.* ` 属性显式配置 JPA 设置。例如,要创建和删除表,您可以将以下内容添加到 ` application.properties ` 中:
1493
+
1494
+ ``` ini
1495
+ spring.jpa.hibernate.ddl-auto =create-drop
1496
+ ```
1497
+
1498
+ ** 注意**
1499
+
1500
+ > 关于上述功能,Hibernate 自己的内部属性名称(如果您记住更好)为 ` hibernate.hbm2ddl.auto ` 。您可以使用 ` spring.jpa.properties.* ` (在添加到实体管理器之前,该前缀将被删除)来将 Hibernate 原生属性一同设置:
1501
+
1502
+ ``` ini
1503
+ spring.jpa.properties.hibernate.globally_quoted_identifiers =true
1504
+ ```
1505
+
1506
+ 上面示例中将 ` true ` 值设置给 ` hibernate.globally_quoted_identifiers ` 属性,该属性将传给 Hibernate 实体管理器。
1507
+
1508
+ 默认情况下,DDL 执行(或验证)将延迟到 ` ApplicationContext ` 启动后。还有一个 ` spring.jpa.generate-ddl ` 标志,如果 Hibernate 自动配置是激活的,那么它将不会被使用,因为 ` ddl-auto ` 设置更细粒度。
1509
+
1226
1510
** 待续……**
0 commit comments