(window.webpackJsonp=window.webpackJsonp||[]).push([[47],{475:function(e,t,a){"use strict";a.r(t);var o=a(56),n=Object(o.a)({},(function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[a("h1",{attrs:{id:"data"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#data"}},[e._v("#")]),e._v(" Data")]),e._v(" "),a("p",[e._v("Spring Boot integrates with a number of data technologies, both SQL and NoSQL.")]),e._v(" "),a("h1",{attrs:{id:"_1-sql-databases"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-sql-databases"}},[e._v("#")]),e._v(" 1. SQL Databases")]),e._v(" "),a("hr"),e._v(" "),a("p",[e._v("The "),a("a",{attrs:{href:"https://spring.io/projects/spring-framework",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Framework"),a("OutboundLink")],1),e._v(" provides extensive support for working with SQL databases, from direct JDBC access using "),a("code",[e._v("JdbcTemplate")]),e._v(" to complete “object relational mapping” technologies such as Hibernate."),a("a",{attrs:{href:"https://spring.io/projects/spring-data",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data"),a("OutboundLink")],1),e._v(" provides an additional level of functionality: creating "),a("code",[e._v("Repository")]),e._v(" implementations directly from interfaces and using conventions to generate queries from your method names.")]),e._v(" "),a("h3",{attrs:{id:"_1-1-configure-a-datasource"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-configure-a-datasource"}},[e._v("#")]),e._v(" 1.1. Configure a DataSource")]),e._v(" "),a("p",[e._v("Java’s "),a("code",[e._v("javax.sql.DataSource")]),e._v(" interface provides a standard method of working with database connections.\nTraditionally, a 'DataSource' uses a "),a("code",[e._v("URL")]),e._v(" along with some credentials to establish a database connection.")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("See "),a("RouterLink",{attrs:{to:"/en/spring-boot/howto.html#howto.data-access.configure-custom-datasource"}},[e._v("the “How-to” section")]),e._v(" for more advanced examples, typically to take full control over the configuration of the DataSource.")],1)])]),e._v(" "),a("tbody")]),e._v(" "),a("h4",{attrs:{id:"_1-1-1-embedded-database-support"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-1-embedded-database-support"}},[e._v("#")]),e._v(" 1.1.1. Embedded Database Support")]),e._v(" "),a("p",[e._v("It is often convenient to develop applications by using an in-memory embedded database.\nObviously, in-memory databases do not provide persistent storage.\nYou need to populate your database when your application starts and be prepared to throw away data when your application ends.")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("The “How-to” section includes a "),a("RouterLink",{attrs:{to:"/en/spring-boot/howto.html#howto.data-initialization"}},[e._v("section on how to initialize a database")]),e._v(".")],1)])]),e._v(" "),a("tbody")]),e._v(" "),a("p",[e._v("Spring Boot can auto-configure embedded "),a("a",{attrs:{href:"https://www.h2database.com",target:"_blank",rel:"noopener noreferrer"}},[e._v("H2"),a("OutboundLink")],1),e._v(", "),a("a",{attrs:{href:"http://hsqldb.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("HSQL"),a("OutboundLink")],1),e._v(", and "),a("a",{attrs:{href:"https://db.apache.org/derby/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Derby"),a("OutboundLink")],1),e._v(" databases.\nYou need not provide any connection URLs.\nYou need only include a build dependency to the embedded database that you want to use.\nIf there are multiple embedded databases on the classpath, set the "),a("code",[e._v("spring.datasource.embedded-database-connection")]),e._v(" configuration property to control which one is used.\nSetting the property to "),a("code",[e._v("none")]),e._v(" disables auto-configuration of an embedded database.")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("If you are using this feature in your tests, you may notice that the same database is reused by your whole test suite regardless of the number of application contexts that you use."),a("br"),e._v("If you want to make sure that each context has a separate embedded database, you should set "),a("code",[e._v("spring.datasource.generate-unique-name")]),e._v(" to "),a("code",[e._v("true")]),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("p",[e._v("For example, the typical POM dependencies would be as follows:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("\n org.springframework.boot\n spring-boot-starter-data-jpa\n\n\n org.hsqldb\n hsqldb\n runtime\n\n")])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("You need a dependency on "),a("code",[e._v("spring-jdbc")]),e._v(" for an embedded database to be auto-configured."),a("br"),e._v("In this example, it is pulled in transitively through "),a("code",[e._v("spring-boot-starter-data-jpa")]),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("If, for whatever reason, you do configure the connection URL for an embedded database, take care to ensure that the database’s automatic shutdown is disabled."),a("br"),e._v("If you use H2, you should use "),a("code",[e._v("DB_CLOSE_ON_EXIT=FALSE")]),e._v(" to do so."),a("br"),e._v("If you use HSQLDB, you should ensure that "),a("code",[e._v("shutdown=true")]),e._v(" is not used."),a("br"),e._v("Disabling the database’s automatic shutdown lets Spring Boot control when the database is closed, thereby ensuring that it happens once access to the database is no longer needed.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h4",{attrs:{id:"_1-1-2-connection-to-a-production-database"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-2-connection-to-a-production-database"}},[e._v("#")]),e._v(" 1.1.2. Connection to a Production Database")]),e._v(" "),a("p",[e._v("Production database connections can also be auto-configured by using a pooling "),a("code",[e._v("DataSource")]),e._v(".")]),e._v(" "),a("h4",{attrs:{id:"_1-1-3-datasource-configuration"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-3-datasource-configuration"}},[e._v("#")]),e._v(" 1.1.3. DataSource Configuration")]),e._v(" "),a("p",[e._v("DataSource configuration is controlled by external configuration properties in "),a("code",[e._v("spring.datasource.*")]),e._v(".\nFor example, you might declare the following section in "),a("code",[e._v("application.properties")]),e._v(":")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.datasource.url=jdbc:mysql://localhost/test\nspring.datasource.username=dbuser\nspring.datasource.password=dbpass\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n datasource:\n url: "jdbc:mysql://localhost/test"\n username: "dbuser"\n password: "dbpass"\n')])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("You should at least specify the URL by setting the "),a("code",[e._v("spring.datasource.url")]),e._v(" property."),a("br"),e._v("Otherwise, Spring Boot tries to auto-configure an embedded database.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("Spring Boot can deduce the JDBC driver class for most databases from the URL."),a("br"),e._v("If you need to specify a specific class, you can use the "),a("code",[e._v("spring.datasource.driver-class-name")]),e._v(" property.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("For a pooling "),a("code",[e._v("DataSource")]),e._v(" to be created, we need to be able to verify that a valid "),a("code",[e._v("Driver")]),e._v(" class is available, so we check for that before doing anything."),a("br"),e._v("In other words, if you set "),a("code",[e._v("spring.datasource.driver-class-name=com.mysql.jdbc.Driver")]),e._v(", then that class has to be loadable.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("p",[e._v("See "),a("a",{attrs:{href:"https://github.com/spring-projects/spring-boot/tree/v2.6.4/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java",target:"_blank",rel:"noopener noreferrer"}},[a("code",[e._v("DataSourceProperties")]),a("OutboundLink")],1),e._v(" for more of the supported options.\nThese are the standard options that work regardless of "),a("RouterLink",{attrs:{to:"/en/spring-boot/features.html#data.sql.datasource.connection-pool"}},[e._v("the actual implementation")]),e._v(".\nIt is also possible to fine-tune implementation-specific settings by using their respective prefix ("),a("code",[e._v("spring.datasource.hikari.*")]),e._v(", "),a("code",[e._v("spring.datasource.tomcat.*")]),e._v(", "),a("code",[e._v("spring.datasource.dbcp2.*")]),e._v(", and "),a("code",[e._v("spring.datasource.oracleucp.*")]),e._v(").\nSee the documentation of the connection pool implementation you are using for more details.")],1),e._v(" "),a("p",[e._v("For instance, if you use the "),a("a",{attrs:{href:"https://tomcat.apache.org/tomcat-9.0-doc/jdbc-pool.html#Common_Attributes",target:"_blank",rel:"noopener noreferrer"}},[e._v("Tomcat connection pool"),a("OutboundLink")],1),e._v(", you could customize many additional settings, as shown in the following example:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.datasource.tomcat.max-wait=10000\nspring.datasource.tomcat.max-active=50\nspring.datasource.tomcat.test-on-borrow=true\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring:\n datasource:\n tomcat:\n max-wait: 10000\n max-active: 50\n test-on-borrow: true\n")])])]),a("p",[e._v("This will set the pool to wait 10000ms before throwing an exception if no connection is available, limit the maximum number of connections to 50 and validate the connection before borrowing it from the pool.")]),e._v(" "),a("h4",{attrs:{id:"_1-1-4-supported-connection-pools"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-4-supported-connection-pools"}},[e._v("#")]),e._v(" 1.1.4. Supported Connection Pools")]),e._v(" "),a("p",[e._v("Spring Boot uses the following algorithm for choosing a specific implementation:")]),e._v(" "),a("ol",[a("li",[a("p",[e._v("We prefer "),a("a",{attrs:{href:"https://github.com/brettwooldridge/HikariCP",target:"_blank",rel:"noopener noreferrer"}},[e._v("HikariCP"),a("OutboundLink")],1),e._v(" for its performance and concurrency.\nIf HikariCP is available, we always choose it.")])]),e._v(" "),a("li",[a("p",[e._v("Otherwise, if the Tomcat pooling "),a("code",[e._v("DataSource")]),e._v(" is available, we use it.")])]),e._v(" "),a("li",[a("p",[e._v("Otherwise, if "),a("a",{attrs:{href:"https://commons.apache.org/proper/commons-dbcp/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Commons DBCP2"),a("OutboundLink")],1),e._v(" is available, we use it.")])]),e._v(" "),a("li",[a("p",[e._v("If none of HikariCP, Tomcat, and DBCP2 are available and if Oracle UCP is available, we use it.")])])]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("If you use the "),a("code",[e._v("spring-boot-starter-jdbc")]),e._v(" or "),a("code",[e._v("spring-boot-starter-data-jpa")]),e._v(" “starters”, you automatically get a dependency to "),a("code",[e._v("HikariCP")]),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("p",[e._v("You can bypass that algorithm completely and specify the connection pool to use by setting the "),a("code",[e._v("spring.datasource.type")]),e._v(" property.\nThis is especially important if you run your application in a Tomcat container, as "),a("code",[e._v("tomcat-jdbc")]),e._v(" is provided by default.")]),e._v(" "),a("p",[e._v("Additional connection pools can always be configured manually, using "),a("code",[e._v("DataSourceBuilder")]),e._v(".\nIf you define your own "),a("code",[e._v("DataSource")]),e._v(" bean, auto-configuration does not occur.\nThe following connection pools are supported by "),a("code",[e._v("DataSourceBuilder")]),e._v(":")]),e._v(" "),a("ul",[a("li",[a("p",[e._v("HikariCP")])]),e._v(" "),a("li",[a("p",[e._v("Tomcat pooling "),a("code",[e._v("Datasource")])])]),e._v(" "),a("li",[a("p",[e._v("Commons DBCP2")])]),e._v(" "),a("li",[a("p",[e._v("Oracle UCP & "),a("code",[e._v("OracleDataSource")])])]),e._v(" "),a("li",[a("p",[e._v("Spring Framework’s "),a("code",[e._v("SimpleDriverDataSource")])])]),e._v(" "),a("li",[a("p",[e._v("H2 "),a("code",[e._v("JdbcDataSource")])])]),e._v(" "),a("li",[a("p",[e._v("PostgreSQL "),a("code",[e._v("PGSimpleDataSource")])])])]),e._v(" "),a("h4",{attrs:{id:"_1-1-5-connection-to-a-jndi-datasource"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-5-connection-to-a-jndi-datasource"}},[e._v("#")]),e._v(" 1.1.5. Connection to a JNDI DataSource")]),e._v(" "),a("p",[e._v("If you deploy your Spring Boot application to an Application Server, you might want to configure and manage your DataSource by using your Application Server’s built-in features and access it by using JNDI.")]),e._v(" "),a("p",[e._v("The "),a("code",[e._v("spring.datasource.jndi-name")]),e._v(" property can be used as an alternative to the "),a("code",[e._v("spring.datasource.url")]),e._v(", "),a("code",[e._v("spring.datasource.username")]),e._v(", and "),a("code",[e._v("spring.datasource.password")]),e._v(" properties to access the "),a("code",[e._v("DataSource")]),e._v(" from a specific JNDI location.\nFor example, the following section in "),a("code",[e._v("application.properties")]),e._v(" shows how you can access a JBoss AS defined "),a("code",[e._v("DataSource")]),e._v(":")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.datasource.jndi-name=java:jboss/datasources/customers\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n datasource:\n jndi-name: "java:jboss/datasources/customers"\n')])])]),a("h3",{attrs:{id:"_1-2-using-jdbctemplate"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-using-jdbctemplate"}},[e._v("#")]),e._v(" 1.2. Using JdbcTemplate")]),e._v(" "),a("p",[e._v("Spring’s "),a("code",[e._v("JdbcTemplate")]),e._v(" and "),a("code",[e._v("NamedParameterJdbcTemplate")]),e._v(" classes are auto-configured, and you can "),a("code",[e._v("@Autowire")]),e._v(" them directly into your own beans, as shown in the following example:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("import org.springframework.jdbc.core.JdbcTemplate;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class MyBean {\n\n private final JdbcTemplate jdbcTemplate;\n\n public MyBean(JdbcTemplate jdbcTemplate) {\n this.jdbcTemplate = jdbcTemplate;\n }\n\n public void doSomething() {\n this.jdbcTemplate ...\n }\n\n}\n\n")])])]),a("p",[e._v("You can customize some properties of the template by using the "),a("code",[e._v("spring.jdbc.template.*")]),e._v(" properties, as shown in the following example:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.jdbc.template.max-rows=500\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring:\n jdbc:\n template:\n max-rows: 500\n")])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("The "),a("code",[e._v("NamedParameterJdbcTemplate")]),e._v(" reuses the same "),a("code",[e._v("JdbcTemplate")]),e._v(" instance behind the scenes."),a("br"),e._v("If more than one "),a("code",[e._v("JdbcTemplate")]),e._v(" is defined and no primary candidate exists, the "),a("code",[e._v("NamedParameterJdbcTemplate")]),e._v(" is not auto-configured.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h3",{attrs:{id:"_1-3-jpa-and-spring-data-jpa"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-jpa-and-spring-data-jpa"}},[e._v("#")]),e._v(" 1.3. JPA and Spring Data JPA")]),e._v(" "),a("p",[e._v("The Java Persistence API is a standard technology that lets you “map” objects to relational databases.\nThe "),a("code",[e._v("spring-boot-starter-data-jpa")]),e._v(" POM provides a quick way to get started.\nIt provides the following key dependencies:")]),e._v(" "),a("ul",[a("li",[a("p",[e._v("Hibernate: One of the most popular JPA implementations.")])]),e._v(" "),a("li",[a("p",[e._v("Spring Data JPA: Helps you to implement JPA-based repositories.")])]),e._v(" "),a("li",[a("p",[e._v("Spring ORM: Core ORM support from the Spring Framework.")])])]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("We do not go into too many details of JPA or "),a("a",{attrs:{href:"https://spring.io/projects/spring-data",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data"),a("OutboundLink")],1),e._v(" here."),a("br"),e._v("You can follow the "),a("a",{attrs:{href:"https://spring.io/guides/gs/accessing-data-jpa/",target:"_blank",rel:"noopener noreferrer"}},[e._v("“Accessing Data with JPA”"),a("OutboundLink")],1),e._v(" guide from "),a("a",{attrs:{href:"https://spring.io",target:"_blank",rel:"noopener noreferrer"}},[e._v("spring.io"),a("OutboundLink")],1),e._v(" and read the "),a("a",{attrs:{href:"https://spring.io/projects/spring-data-jpa",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data JPA"),a("OutboundLink")],1),e._v(" and "),a("a",{attrs:{href:"https://hibernate.org/orm/documentation/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Hibernate"),a("OutboundLink")],1),e._v(" reference documentation.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h4",{attrs:{id:"_1-3-1-entity-classes"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-1-entity-classes"}},[e._v("#")]),e._v(" 1.3.1. Entity Classes")]),e._v(" "),a("p",[e._v("Traditionally, JPA “Entity” classes are specified in a "),a("code",[e._v("persistence.xml")]),e._v(" file.\nWith Spring Boot, this file is not necessary and “Entity Scanning” is used instead.\nBy default, all packages below your main configuration class (the one annotated with "),a("code",[e._v("@EnableAutoConfiguration")]),e._v(" or "),a("code",[e._v("@SpringBootApplication")]),e._v(") are searched.")]),e._v(" "),a("p",[e._v("Any classes annotated with "),a("code",[e._v("@Entity")]),e._v(", "),a("code",[e._v("@Embeddable")]),e._v(", or "),a("code",[e._v("@MappedSuperclass")]),e._v(" are considered.\nA typical entity class resembles the following example:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("import java.io.Serializable;\n\nimport javax.persistence.Column;\nimport javax.persistence.Entity;\nimport javax.persistence.GeneratedValue;\nimport javax.persistence.Id;\n\n@Entity\npublic class City implements Serializable {\n\n @Id\n @GeneratedValue\n private Long id;\n\n @Column(nullable = false)\n private String name;\n\n @Column(nullable = false)\n private String state;\n\n // ... additional members, often include @OneToMany mappings\n\n protected City() {\n // no-args constructor required by JPA spec\n // this one is protected since it should not be used directly\n }\n\n public City(String name, String state) {\n this.name = name;\n this.state = state;\n }\n\n public String getName() {\n return this.name;\n }\n\n public String getState() {\n return this.state;\n }\n\n // ... etc\n\n}\n\n")])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("You can customize entity scanning locations by using the "),a("code",[e._v("@EntityScan")]),e._v(" annotation."),a("br"),e._v("See the “"),a("RouterLink",{attrs:{to:"/en/spring-boot/howto.html#howto.data-access.separate-entity-definitions-from-spring-configuration"}},[e._v("howto.html")]),e._v("” how-to.")],1)])]),e._v(" "),a("tbody")]),e._v(" "),a("h4",{attrs:{id:"_1-3-2-spring-data-jpa-repositories"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-2-spring-data-jpa-repositories"}},[e._v("#")]),e._v(" 1.3.2. Spring Data JPA Repositories")]),e._v(" "),a("p",[a("a",{attrs:{href:"https://spring.io/projects/spring-data-jpa",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data JPA"),a("OutboundLink")],1),e._v(" repositories are interfaces that you can define to access data.\nJPA queries are created automatically from your method names.\nFor example, a "),a("code",[e._v("CityRepository")]),e._v(" interface might declare a "),a("code",[e._v("findAllByState(String state)")]),e._v(" method to find all the cities in a given state.")]),e._v(" "),a("p",[e._v("For more complex queries, you can annotate your method with Spring Data’s "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/jpa/docs/2.6.2/api/org/springframework/data/jpa/repository/Query.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[e._v("Query")]),a("OutboundLink")],1),e._v(" annotation.")]),e._v(" "),a("p",[e._v("Spring Data repositories usually extend from the "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/commons/docs/2.6.2/api/org/springframework/data/repository/Repository.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[e._v("Repository")]),a("OutboundLink")],1),e._v(" or "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/commons/docs/2.6.2/api/org/springframework/data/repository/CrudRepository.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[e._v("CrudRepository")]),a("OutboundLink")],1),e._v(" interfaces.\nIf you use auto-configuration, repositories are searched from the package containing your main configuration class (the one annotated with "),a("code",[e._v("@EnableAutoConfiguration")]),e._v(" or "),a("code",[e._v("@SpringBootApplication")]),e._v(") down.")]),e._v(" "),a("p",[e._v("The following example shows a typical Spring Data repository interface definition:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("import org.springframework.boot.docs.data.sql.jpaandspringdata.entityclasses.City;\nimport org.springframework.data.domain.Page;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.data.repository.Repository;\n\npublic interface CityRepository extends Repository {\n\n Page findAll(Pageable pageable);\n\n City findByNameAndStateAllIgnoringCase(String name, String state);\n\n}\n\n")])])]),a("p",[e._v("Spring Data JPA repositories support three different modes of bootstrapping: default, deferred, and lazy.\nTo enable deferred or lazy bootstrapping, set the "),a("code",[e._v("spring.data.jpa.repositories.bootstrap-mode")]),e._v(" property to "),a("code",[e._v("deferred")]),e._v(" or "),a("code",[e._v("lazy")]),e._v(" respectively.\nWhen using deferred or lazy bootstrapping, the auto-configured "),a("code",[e._v("EntityManagerFactoryBuilder")]),e._v(" will use the context’s "),a("code",[e._v("AsyncTaskExecutor")]),e._v(", if any, as the bootstrap executor.\nIf more than one exists, the one named "),a("code",[e._v("applicationTaskExecutor")]),e._v(" will be used.")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("When using deferred or lazy bootstrapping, make sure to defer any access to the JPA infrastructure after the application context bootstrap phase."),a("br"),e._v("You can use "),a("code",[e._v("SmartInitializingSingleton")]),e._v(" to invoke any initialization that requires the JPA infrastructure."),a("br"),e._v("For JPA components (such as converters) that are created as Spring beans, use "),a("code",[e._v("ObjectProvider")]),e._v(" to delay the resolution of dependencies, if any.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("We have barely scratched the surface of Spring Data JPA."),a("br"),e._v("For complete details, see the "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/jpa/docs/2.6.2/reference/html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data JPA reference documentation"),a("OutboundLink")],1),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h4",{attrs:{id:"_1-3-3-spring-data-envers-repositories"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-3-spring-data-envers-repositories"}},[e._v("#")]),e._v(" 1.3.3. Spring Data Envers Repositories")]),e._v(" "),a("p",[e._v("If "),a("a",{attrs:{href:"https://spring.io/projects/spring-data-envers",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data Envers"),a("OutboundLink")],1),e._v(" is available, JPA repositories are auto-configured to support typical Envers queries.")]),e._v(" "),a("p",[e._v("To use Spring Data Envers, make sure your repository extends from "),a("code",[e._v("RevisionRepository")]),e._v(" as show in the following example:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("import org.springframework.boot.docs.data.sql.jpaandspringdata.entityclasses.Country;\nimport org.springframework.data.domain.Page;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.data.repository.Repository;\nimport org.springframework.data.repository.history.RevisionRepository;\n\npublic interface CountryRepository extends RevisionRepository, Repository {\n\n Page findAll(Pageable pageable);\n\n}\n\n")])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("For more details, check the "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/envers/docs/2.6.2/reference/html/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data Envers reference documentation"),a("OutboundLink")],1),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h4",{attrs:{id:"_1-3-4-creating-and-dropping-jpa-databases"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-4-creating-and-dropping-jpa-databases"}},[e._v("#")]),e._v(" 1.3.4. Creating and Dropping JPA Databases")]),e._v(" "),a("p",[e._v("By default, JPA databases are automatically created "),a("strong",[e._v("only")]),e._v(" if you use an embedded database (H2, HSQL, or Derby).\nYou can explicitly configure JPA settings by using "),a("code",[e._v("spring.jpa.*")]),e._v(" properties.\nFor example, to create and drop tables you can add the following line to your "),a("code",[e._v("application.properties")]),e._v(":")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.jpa.hibernate.ddl-auto=create-drop\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n jpa:\n hibernate.ddl-auto: "create-drop"\n')])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("Hibernate’s own internal property name for this (if you happen to remember it better) is "),a("code",[e._v("hibernate.hbm2ddl.auto")]),e._v("."),a("br"),e._v("You can set it, along with other Hibernate native properties, by using "),a("code",[e._v("spring.jpa.properties.*")]),e._v(" (the prefix is stripped before adding them to the entity manager)."),a("br"),e._v("The following line shows an example of setting JPA properties for Hibernate:")])])]),e._v(" "),a("tbody")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.jpa.properties.hibernate[globally_quoted_identifiers]=true\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n jpa:\n properties:\n hibernate:\n "globally_quoted_identifiers": "true"\n')])])]),a("p",[e._v("The line in the preceding example passes a value of "),a("code",[e._v("true")]),e._v(" for the "),a("code",[e._v("hibernate.globally_quoted_identifiers")]),e._v(" property to the Hibernate entity manager.")]),e._v(" "),a("p",[e._v("By default, the DDL execution (or validation) is deferred until the "),a("code",[e._v("ApplicationContext")]),e._v(" has started.\nThere is also a "),a("code",[e._v("spring.jpa.generate-ddl")]),e._v(" flag, but it is not used if Hibernate auto-configuration is active, because the "),a("code",[e._v("ddl-auto")]),e._v(" settings are more fine-grained.")]),e._v(" "),a("h4",{attrs:{id:"_1-3-5-open-entitymanager-in-view"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-5-open-entitymanager-in-view"}},[e._v("#")]),e._v(" 1.3.5. Open EntityManager in View")]),e._v(" "),a("p",[e._v("If you are running a web application, Spring Boot by default registers "),a("a",{attrs:{href:"https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/orm/jpa/support/OpenEntityManagerInViewInterceptor.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[e._v("OpenEntityManagerInViewInterceptor")]),a("OutboundLink")],1),e._v(" to apply the “Open EntityManager in View” pattern, to allow for lazy loading in web views.\nIf you do not want this behavior, you should set "),a("code",[e._v("spring.jpa.open-in-view")]),e._v(" to "),a("code",[e._v("false")]),e._v(" in your "),a("code",[e._v("application.properties")]),e._v(".")]),e._v(" "),a("h3",{attrs:{id:"_1-4-spring-data-jdbc"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-4-spring-data-jdbc"}},[e._v("#")]),e._v(" 1.4. Spring Data JDBC")]),e._v(" "),a("p",[e._v("Spring Data includes repository support for JDBC and will automatically generate SQL for the methods on "),a("code",[e._v("CrudRepository")]),e._v(".\nFor more advanced queries, a "),a("code",[e._v("@Query")]),e._v(" annotation is provided.")]),e._v(" "),a("p",[e._v("Spring Boot will auto-configure Spring Data’s JDBC repositories when the necessary dependencies are on the classpath.\nThey can be added to your project with a single dependency on "),a("code",[e._v("spring-boot-starter-data-jdbc")]),e._v(".\nIf necessary, you can take control of Spring Data JDBC’s configuration by adding the "),a("code",[e._v("@EnableJdbcRepositories")]),e._v(" annotation or a "),a("code",[e._v("JdbcConfiguration")]),e._v(" subclass to your application.")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("For complete details of Spring Data JDBC, see the "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/jdbc/docs/2.3.2/reference/html/",target:"_blank",rel:"noopener noreferrer"}},[e._v("reference documentation"),a("OutboundLink")],1),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h3",{attrs:{id:"_1-5-using-h2-s-web-console"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-5-using-h2-s-web-console"}},[e._v("#")]),e._v(" 1.5. Using H2’s Web Console")]),e._v(" "),a("p",[e._v("The "),a("a",{attrs:{href:"https://www.h2database.com",target:"_blank",rel:"noopener noreferrer"}},[e._v("H2 database"),a("OutboundLink")],1),e._v(" provides a "),a("a",{attrs:{href:"https://www.h2database.com/html/quickstart.html#h2_console",target:"_blank",rel:"noopener noreferrer"}},[e._v("browser-based console"),a("OutboundLink")],1),e._v(" that Spring Boot can auto-configure for you.\nThe console is auto-configured when the following conditions are met:")]),e._v(" "),a("ul",[a("li",[a("p",[e._v("You are developing a servlet-based web application.")])]),e._v(" "),a("li",[a("p",[a("code",[e._v("com.h2database:h2")]),e._v(" is on the classpath.")])]),e._v(" "),a("li",[a("p",[e._v("You are using "),a("RouterLink",{attrs:{to:"/en/spring-boot/using.html#using.devtools"}},[e._v("Spring Boot’s developer tools")]),e._v(".")],1)])]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("If you are not using Spring Boot’s developer tools but would still like to make use of H2’s console, you can configure the "),a("code",[e._v("spring.h2.console.enabled")]),e._v(" property with a value of "),a("code",[e._v("true")]),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("The H2 console is only intended for use during development, so you should take care to ensure that "),a("code",[e._v("spring.h2.console.enabled")]),e._v(" is not set to "),a("code",[e._v("true")]),e._v(" in production.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h4",{attrs:{id:"_1-5-1-changing-the-h2-console-s-path"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-5-1-changing-the-h2-console-s-path"}},[e._v("#")]),e._v(" 1.5.1. Changing the H2 Console’s Path")]),e._v(" "),a("p",[e._v("By default, the console is available at "),a("code",[e._v("/h2-console")]),e._v(".\nYou can customize the console’s path by using the "),a("code",[e._v("spring.h2.console.path")]),e._v(" property.")]),e._v(" "),a("h3",{attrs:{id:"_1-6-using-jooq"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-6-using-jooq"}},[e._v("#")]),e._v(" 1.6. Using jOOQ")]),e._v(" "),a("p",[e._v("jOOQ Object Oriented Querying ("),a("a",{attrs:{href:"https://www.jooq.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("jOOQ"),a("OutboundLink")],1),e._v(") is a popular product from "),a("a",{attrs:{href:"https://www.datageekery.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Data Geekery"),a("OutboundLink")],1),e._v(" which generates Java code from your database and lets you build type-safe SQL queries through its fluent API.\nBoth the commercial and open source editions can be used with Spring Boot.")]),e._v(" "),a("h4",{attrs:{id:"_1-6-1-code-generation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-6-1-code-generation"}},[e._v("#")]),e._v(" 1.6.1. Code Generation")]),e._v(" "),a("p",[e._v("In order to use jOOQ type-safe queries, you need to generate Java classes from your database schema.\nYou can follow the instructions in the "),a("a",{attrs:{href:"https://www.jooq.org/doc/3.14.15/manual-single-page/#jooq-in-7-steps-step3",target:"_blank",rel:"noopener noreferrer"}},[e._v("jOOQ user manual"),a("OutboundLink")],1),e._v(".\nIf you use the "),a("code",[e._v("jooq-codegen-maven")]),e._v(" plugin and you also use the "),a("code",[e._v("spring-boot-starter-parent")]),e._v(" “parent POM”, you can safely omit the plugin’s "),a("code",[e._v("")]),e._v(" tag.\nYou can also use Spring Boot-defined version variables (such as "),a("code",[e._v("h2.version")]),e._v(") to declare the plugin’s database dependency.\nThe following listing shows an example:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("\n org.jooq\n jooq-codegen-maven\n \n ...\n \n \n \n com.h2database\n h2\n ${h2.version}\n \n \n \n \n org.h2.Driver\n jdbc:h2:~/yourdatabase\n \n \n ...\n \n \n\n")])])]),a("h4",{attrs:{id:"_1-6-2-using-dslcontext"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-6-2-using-dslcontext"}},[e._v("#")]),e._v(" 1.6.2. Using DSLContext")]),e._v(" "),a("p",[e._v("The fluent API offered by jOOQ is initiated through the "),a("code",[e._v("org.jooq.DSLContext")]),e._v(" interface.\nSpring Boot auto-configures a "),a("code",[e._v("DSLContext")]),e._v(" as a Spring Bean and connects it to your application "),a("code",[e._v("DataSource")]),e._v(".\nTo use the "),a("code",[e._v("DSLContext")]),e._v(", you can inject it, as shown in the following example:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("import java.util.GregorianCalendar;\nimport java.util.List;\n\nimport org.jooq.DSLContext;\n\nimport org.springframework.stereotype.Component;\n\nimport static org.springframework.boot.docs.data.sql.jooq.dslcontext.Tables.AUTHOR;\n\n@Component\npublic class MyBean {\n\n private final DSLContext create;\n\n public MyBean(DSLContext dslContext) {\n this.create = dslContext;\n }\n\n}\n\n")])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("The jOOQ manual tends to use a variable named "),a("code",[e._v("create")]),e._v(" to hold the "),a("code",[e._v("DSLContext")]),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("p",[e._v("You can then use the "),a("code",[e._v("DSLContext")]),e._v(" to construct your queries, as shown in the following example:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("public List authorsBornAfter1980() {\n return this.create.selectFrom(AUTHOR)\n .where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1)))\n .fetch(AUTHOR.DATE_OF_BIRTH);\n\n")])])]),a("h4",{attrs:{id:"_1-6-3-jooq-sql-dialect"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-6-3-jooq-sql-dialect"}},[e._v("#")]),e._v(" 1.6.3. jOOQ SQL Dialect")]),e._v(" "),a("p",[e._v("Unless the "),a("code",[e._v("spring.jooq.sql-dialect")]),e._v(" property has been configured, Spring Boot determines the SQL dialect to use for your datasource.\nIf Spring Boot could not detect the dialect, it uses "),a("code",[e._v("DEFAULT")]),e._v(".")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("Spring Boot can only auto-configure dialects supported by the open source version of jOOQ.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h4",{attrs:{id:"_1-6-4-customizing-jooq"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-6-4-customizing-jooq"}},[e._v("#")]),e._v(" 1.6.4. Customizing jOOQ")]),e._v(" "),a("p",[e._v("More advanced customizations can be achieved by defining your own "),a("code",[e._v("DefaultConfigurationCustomizer")]),e._v(" bean that will be invoked prior to creating the "),a("code",[e._v("org.jooq.Configuration")]),e._v(" "),a("code",[e._v("@Bean")]),e._v(".\nThis takes precedence to anything that is applied by the auto-configuration.")]),e._v(" "),a("p",[e._v("You can also create your own "),a("code",[e._v("org.jooq.Configuration")]),e._v(" "),a("code",[e._v("@Bean")]),e._v(" if you want to take complete control of the jOOQ configuration.")]),e._v(" "),a("h3",{attrs:{id:"_1-7-using-r2dbc"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-7-using-r2dbc"}},[e._v("#")]),e._v(" 1.7. Using R2DBC")]),e._v(" "),a("p",[e._v("The Reactive Relational Database Connectivity ("),a("a",{attrs:{href:"https://r2dbc.io",target:"_blank",rel:"noopener noreferrer"}},[e._v("R2DBC"),a("OutboundLink")],1),e._v(") project brings reactive programming APIs to relational databases.\nR2DBC’s "),a("code",[e._v("io.r2dbc.spi.Connection")]),e._v(" provides a standard method of working with non-blocking database connections.\nConnections are provided by using a "),a("code",[e._v("ConnectionFactory")]),e._v(", similar to a "),a("code",[e._v("DataSource")]),e._v(" with jdbc.")]),e._v(" "),a("p",[a("code",[e._v("ConnectionFactory")]),e._v(" configuration is controlled by external configuration properties in "),a("code",[e._v("spring.r2dbc.*")]),e._v(".\nFor example, you might declare the following section in "),a("code",[e._v("application.properties")]),e._v(":")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.r2dbc.url=r2dbc:postgresql://localhost/test\nspring.r2dbc.username=dbuser\nspring.r2dbc.password=dbpass\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n r2dbc:\n url: "r2dbc:postgresql://localhost/test"\n username: "dbuser"\n password: "dbpass"\n')])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("You do not need to specify a driver class name, since Spring Boot obtains the driver from R2DBC’s Connection Factory discovery.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("At least the url should be provided."),a("br"),e._v("Information specified in the URL takes precedence over individual properties, that is "),a("code",[e._v("name")]),e._v(", "),a("code",[e._v("username")]),e._v(", "),a("code",[e._v("password")]),e._v(" and pooling options.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("The “How-to” section includes a "),a("RouterLink",{attrs:{to:"/en/spring-boot/howto.html#howto.data-initialization.using-basic-sql-scripts"}},[e._v("section on how to initialize a database")]),e._v(".")],1)])]),e._v(" "),a("tbody")]),e._v(" "),a("p",[e._v("To customize the connections created by a "),a("code",[e._v("ConnectionFactory")]),e._v(", that is, set specific parameters that you do not want (or cannot) configure in your central database configuration, you can use a "),a("code",[e._v("ConnectionFactoryOptionsBuilderCustomizer")]),e._v(" "),a("code",[e._v("@Bean")]),e._v(".\nThe following example shows how to manually override the database port while the rest of the options is taken from the application configuration:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("import io.r2dbc.spi.ConnectionFactoryOptions;\n\nimport org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration(proxyBeanMethods = false)\npublic class MyR2dbcConfiguration {\n\n @Bean\n public ConnectionFactoryOptionsBuilderCustomizer connectionFactoryPortCustomizer() {\n return (builder) -> builder.option(ConnectionFactoryOptions.PORT, 5432);\n }\n\n}\n\n")])])]),a("p",[e._v("The following examples show how to set some PostgreSQL connection options:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('import java.util.HashMap;\nimport java.util.Map;\n\nimport io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider;\n\nimport org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration(proxyBeanMethods = false)\npublic class MyPostgresR2dbcConfiguration {\n\n @Bean\n public ConnectionFactoryOptionsBuilderCustomizer postgresCustomizer() {\n Map options = new HashMap<>();\n options.put("lock_timeout", "30s");\n options.put("statement_timeout", "60s");\n return (builder) -> builder.option(PostgresqlConnectionFactoryProvider.OPTIONS, options);\n }\n\n}\n\n')])])]),a("p",[e._v("When a "),a("code",[e._v("ConnectionFactory")]),e._v(" bean is available, the regular JDBC "),a("code",[e._v("DataSource")]),e._v(" auto-configuration backs off.\nIf you want to retain the JDBC "),a("code",[e._v("DataSource")]),e._v(" auto-configuration, and are comfortable with the risk of using the blocking JDBC API in a reactive application, add "),a("code",[e._v("@Import(DataSourceAutoConfiguration.class)")]),e._v(" on a "),a("code",[e._v("@Configuration")]),e._v(" class in your application to re-enable it.")]),e._v(" "),a("h4",{attrs:{id:"_1-7-1-embedded-database-support"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-7-1-embedded-database-support"}},[e._v("#")]),e._v(" 1.7.1. Embedded Database Support")]),e._v(" "),a("p",[e._v("Similarly to "),a("RouterLink",{attrs:{to:"/en/spring-boot/features.html#data.sql.datasource.embedded"}},[e._v("the JDBC support")]),e._v(", Spring Boot can automatically configure an embedded database for reactive usage.\nYou need not provide any connection URLs.\nYou need only include a build dependency to the embedded database that you want to use, as shown in the following example:")],1),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("\n io.r2dbc\n r2dbc-h2\n runtime\n\n")])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("If you are using this feature in your tests, you may notice that the same database is reused by your whole test suite regardless of the number of application contexts that you use."),a("br"),e._v("If you want to make sure that each context has a separate embedded database, you should set "),a("code",[e._v("spring.r2dbc.generate-unique-name")]),e._v(" to "),a("code",[e._v("true")]),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h4",{attrs:{id:"_1-7-2-using-databaseclient"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-7-2-using-databaseclient"}},[e._v("#")]),e._v(" 1.7.2. Using DatabaseClient")]),e._v(" "),a("p",[e._v("A "),a("code",[e._v("DatabaseClient")]),e._v(" bean is auto-configured, and you can "),a("code",[e._v("@Autowire")]),e._v(" it directly into your own beans, as shown in the following example:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('import java.util.Map;\n\nimport reactor.core.publisher.Flux;\n\nimport org.springframework.r2dbc.core.DatabaseClient;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class MyBean {\n\n private final DatabaseClient databaseClient;\n\n public MyBean(DatabaseClient databaseClient) {\n this.databaseClient = databaseClient;\n }\n\n // ...\n\n public Flux> someMethod() {\n return this.databaseClient.sql("select * from user").fetch().all();\n }\n\n}\n\n')])])]),a("h4",{attrs:{id:"_1-7-3-spring-data-r2dbc-repositories"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1-7-3-spring-data-r2dbc-repositories"}},[e._v("#")]),e._v(" 1.7.3. Spring Data R2DBC Repositories")]),e._v(" "),a("p",[a("a",{attrs:{href:"https://spring.io/projects/spring-data-r2dbc",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data R2DBC"),a("OutboundLink")],1),e._v(" repositories are interfaces that you can define to access data.\nQueries are created automatically from your method names.\nFor example, a "),a("code",[e._v("CityRepository")]),e._v(" interface might declare a "),a("code",[e._v("findAllByState(String state)")]),e._v(" method to find all the cities in a given state.")]),e._v(" "),a("p",[e._v("For more complex queries, you can annotate your method with Spring Data’s "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/r2dbc/docs/1.4.2/api/org/springframework/data/r2dbc/repository/Query.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[e._v("Query")]),a("OutboundLink")],1),e._v(" annotation.")]),e._v(" "),a("p",[e._v("Spring Data repositories usually extend from the "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/commons/docs/2.6.2/api/org/springframework/data/repository/Repository.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[e._v("Repository")]),a("OutboundLink")],1),e._v(" or "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/commons/docs/2.6.2/api/org/springframework/data/repository/CrudRepository.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[e._v("CrudRepository")]),a("OutboundLink")],1),e._v(" interfaces.\nIf you use auto-configuration, repositories are searched from the package containing your main configuration class (the one annotated with "),a("code",[e._v("@EnableAutoConfiguration")]),e._v(" or "),a("code",[e._v("@SpringBootApplication")]),e._v(") down.")]),e._v(" "),a("p",[e._v("The following example shows a typical Spring Data repository interface definition:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("import reactor.core.publisher.Mono;\n\nimport org.springframework.data.repository.Repository;\n\npublic interface CityRepository extends Repository {\n\n Mono findByNameAndStateAllIgnoringCase(String name, String state);\n\n}\n\n")])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("We have barely scratched the surface of Spring Data R2DBC. For complete details, see the "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/r2dbc/docs/1.4.2/reference/html/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data R2DBC reference documentation"),a("OutboundLink")],1),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h2",{attrs:{id:"_2-working-with-nosql-technologies"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-working-with-nosql-technologies"}},[e._v("#")]),e._v(" 2. Working with NoSQL Technologies")]),e._v(" "),a("hr"),e._v(" "),a("p",[e._v("Spring Data provides additional projects that help you access a variety of NoSQL technologies, including:")]),e._v(" "),a("ul",[a("li",[a("p",[a("a",{attrs:{href:"https://spring.io/projects/spring-data-mongodb",target:"_blank",rel:"noopener noreferrer"}},[e._v("MongoDB"),a("OutboundLink")],1)])]),e._v(" "),a("li",[a("p",[a("a",{attrs:{href:"https://spring.io/projects/spring-data-neo4j",target:"_blank",rel:"noopener noreferrer"}},[e._v("Neo4J"),a("OutboundLink")],1)])]),e._v(" "),a("li",[a("p",[a("a",{attrs:{href:"https://spring.io/projects/spring-data-elasticsearch",target:"_blank",rel:"noopener noreferrer"}},[e._v("Elasticsearch"),a("OutboundLink")],1)])]),e._v(" "),a("li",[a("p",[a("a",{attrs:{href:"https://spring.io/projects/spring-data-redis",target:"_blank",rel:"noopener noreferrer"}},[e._v("Redis"),a("OutboundLink")],1)])]),e._v(" "),a("li",[a("p",[a("a",{attrs:{href:"https://spring.io/projects/spring-data-gemfire",target:"_blank",rel:"noopener noreferrer"}},[e._v("GemFire"),a("OutboundLink")],1),e._v(" or "),a("a",{attrs:{href:"https://spring.io/projects/spring-data-geode",target:"_blank",rel:"noopener noreferrer"}},[e._v("Geode"),a("OutboundLink")],1)])]),e._v(" "),a("li",[a("p",[a("a",{attrs:{href:"https://spring.io/projects/spring-data-cassandra",target:"_blank",rel:"noopener noreferrer"}},[e._v("Cassandra"),a("OutboundLink")],1)])]),e._v(" "),a("li",[a("p",[a("a",{attrs:{href:"https://spring.io/projects/spring-data-couchbase",target:"_blank",rel:"noopener noreferrer"}},[e._v("Couchbase"),a("OutboundLink")],1)])]),e._v(" "),a("li",[a("p",[a("a",{attrs:{href:"https://spring.io/projects/spring-data-ldap",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDAP"),a("OutboundLink")],1)])])]),e._v(" "),a("p",[e._v("Spring Boot provides auto-configuration for Redis, MongoDB, Neo4j, Solr, Elasticsearch, Cassandra, Couchbase, LDAP and InfluxDB.\nYou can make use of the other projects, but you must configure them yourself.\nSee the appropriate reference documentation at "),a("a",{attrs:{href:"https://spring.io/projects/spring-data",target:"_blank",rel:"noopener noreferrer"}},[e._v("spring.io/projects/spring-data"),a("OutboundLink")],1),e._v(".")]),e._v(" "),a("h3",{attrs:{id:"_2-1-redis"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-redis"}},[e._v("#")]),e._v(" 2.1. Redis")]),e._v(" "),a("p",[a("a",{attrs:{href:"https://redis.io/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Redis"),a("OutboundLink")],1),e._v(" is a cache, message broker, and richly-featured key-value store.\nSpring Boot offers basic auto-configuration for the "),a("a",{attrs:{href:"https://github.com/lettuce-io/lettuce-core/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Lettuce"),a("OutboundLink")],1),e._v(" and "),a("a",{attrs:{href:"https://github.com/xetorthio/jedis/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Jedis"),a("OutboundLink")],1),e._v(" client libraries and the abstractions on top of them provided by "),a("a",{attrs:{href:"https://github.com/spring-projects/spring-data-redis",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data Redis"),a("OutboundLink")],1),e._v(".")]),e._v(" "),a("p",[e._v("There is a "),a("code",[e._v("spring-boot-starter-data-redis")]),e._v(" “Starter” for collecting the dependencies in a convenient way.\nBy default, it uses "),a("a",{attrs:{href:"https://github.com/lettuce-io/lettuce-core/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Lettuce"),a("OutboundLink")],1),e._v(".\nThat starter handles both traditional and reactive applications.")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("We also provide a "),a("code",[e._v("spring-boot-starter-data-redis-reactive")]),e._v(" “Starter” for consistency with the other stores with reactive support.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h4",{attrs:{id:"_2-1-1-connecting-to-redis"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-1-connecting-to-redis"}},[e._v("#")]),e._v(" 2.1.1. Connecting to Redis")]),e._v(" "),a("p",[e._v("You can inject an auto-configured "),a("code",[e._v("RedisConnectionFactory")]),e._v(", "),a("code",[e._v("StringRedisTemplate")]),e._v(", or vanilla "),a("code",[e._v("RedisTemplate")]),e._v(" instance as you would any other Spring Bean.\nBy default, the instance tries to connect to a Redis server at "),a("code",[e._v("localhost:6379")]),e._v(".\nThe following listing shows an example of such a bean:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('import org.springframework.data.redis.core.StringRedisTemplate;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class MyBean {\n\n private final StringRedisTemplate template;\n\n public MyBean(StringRedisTemplate template) {\n this.template = template;\n }\n\n // ...\n\n public Boolean someMethod() {\n return this.template.hasKey("spring");\n }\n\n}\n\n')])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("You can also register an arbitrary number of beans that implement "),a("code",[e._v("LettuceClientConfigurationBuilderCustomizer")]),e._v(" for more advanced customizations."),a("code",[e._v("ClientResources")]),e._v(" can also be customized using "),a("code",[e._v("ClientResourcesBuilderCustomizer")]),e._v("."),a("br"),e._v("If you use Jedis, "),a("code",[e._v("JedisClientConfigurationBuilderCustomizer")]),e._v(" is also available."),a("br"),e._v("Alternatively, you can register a bean of type "),a("code",[e._v("RedisStandaloneConfiguration")]),e._v(", "),a("code",[e._v("RedisSentinelConfiguration")]),e._v(", or "),a("code",[e._v("RedisClusterConfiguration")]),e._v(" to take full control over the configuration.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("p",[e._v("If you add your own "),a("code",[e._v("@Bean")]),e._v(" of any of the auto-configured types, it replaces the default (except in the case of "),a("code",[e._v("RedisTemplate")]),e._v(", when the exclusion is based on the bean name, "),a("code",[e._v("redisTemplate")]),e._v(", not its type).")]),e._v(" "),a("p",[e._v("By default, a pooled connection factory is auto-configured if "),a("code",[e._v("commons-pool2")]),e._v(" is on the classpath.")]),e._v(" "),a("h3",{attrs:{id:"_2-2-mongodb"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-mongodb"}},[e._v("#")]),e._v(" 2.2. MongoDB")]),e._v(" "),a("p",[a("a",{attrs:{href:"https://www.mongodb.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("MongoDB"),a("OutboundLink")],1),e._v(" is an open-source NoSQL document database that uses a JSON-like schema instead of traditional table-based relational data.\nSpring Boot offers several conveniences for working with MongoDB, including the "),a("code",[e._v("spring-boot-starter-data-mongodb")]),e._v(" and "),a("code",[e._v("spring-boot-starter-data-mongodb-reactive")]),e._v(" “Starters”.")]),e._v(" "),a("h4",{attrs:{id:"_2-2-1-connecting-to-a-mongodb-database"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-1-connecting-to-a-mongodb-database"}},[e._v("#")]),e._v(" 2.2.1. Connecting to a MongoDB Database")]),e._v(" "),a("p",[e._v("To access MongoDB databases, you can inject an auto-configured "),a("code",[e._v("org.springframework.data.mongodb.MongoDatabaseFactory")]),e._v(".\nBy default, the instance tries to connect to a MongoDB server at "),a("code",[e._v("mongodb://localhost/test")]),e._v(".\nThe following example shows how to connect to a MongoDB database:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('import com.mongodb.client.MongoCollection;\nimport com.mongodb.client.MongoDatabase;\nimport org.bson.Document;\n\nimport org.springframework.data.mongodb.MongoDatabaseFactory;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class MyBean {\n\n private final MongoDatabaseFactory mongo;\n\n public MyBean(MongoDatabaseFactory mongo) {\n this.mongo = mongo;\n }\n\n // ...\n\n public MongoCollection someMethod() {\n MongoDatabase db = this.mongo.getMongoDatabase();\n return db.getCollection("users");\n }\n\n}\n\n')])])]),a("p",[e._v("If you have defined your own "),a("code",[e._v("MongoClient")]),e._v(", it will be used to auto-configure a suitable "),a("code",[e._v("MongoDatabaseFactory")]),e._v(".")]),e._v(" "),a("p",[e._v("The auto-configured "),a("code",[e._v("MongoClient")]),e._v(" is created using a "),a("code",[e._v("MongoClientSettings")]),e._v(" bean.\nIf you have defined your own "),a("code",[e._v("MongoClientSettings")]),e._v(", it will be used without modification and the "),a("code",[e._v("spring.data.mongodb")]),e._v(" properties will be ignored.\nOtherwise a "),a("code",[e._v("MongoClientSettings")]),e._v(" will be auto-configured and will have the "),a("code",[e._v("spring.data.mongodb")]),e._v(" properties applied to it.\nIn either case, you can declare one or more "),a("code",[e._v("MongoClientSettingsBuilderCustomizer")]),e._v(" beans to fine-tune the "),a("code",[e._v("MongoClientSettings")]),e._v(" configuration.\nEach will be called in order with the "),a("code",[e._v("MongoClientSettings.Builder")]),e._v(" that is used to build the "),a("code",[e._v("MongoClientSettings")]),e._v(".")]),e._v(" "),a("p",[e._v("You can set the "),a("code",[e._v("spring.data.mongodb.uri")]),e._v(" property to change the URL and configure additional settings such as the "),a("em",[e._v("replica set")]),e._v(", as shown in the following example:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.data.mongodb.uri=mongodb://user:[email protected]:12345,mongo2.example.com:23456/test\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n data:\n mongodb:\n uri: "mongodb://user:[email protected]:12345,mongo2.example.com:23456/test"\n')])])]),a("p",[e._v("Alternatively, you can specify connection details using discrete properties.\nFor example, you might declare the following settings in your "),a("code",[e._v("application.properties")]),e._v(":")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.data.mongodb.host=mongoserver.example.com\nspring.data.mongodb.port=27017\nspring.data.mongodb.database=test\nspring.data.mongodb.username=user\nspring.data.mongodb.password=secret\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n data:\n mongodb:\n host: "mongoserver.example.com"\n port: 27017\n database: "test"\n username: "user"\n password: "secret"\n')])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("If "),a("code",[e._v("spring.data.mongodb.port")]),e._v(" is not specified, the default of "),a("code",[e._v("27017")]),e._v(" is used."),a("br"),e._v("You could delete this line from the example shown earlier.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("If you do not use Spring Data MongoDB, you can inject a "),a("code",[e._v("MongoClient")]),e._v(" bean instead of using "),a("code",[e._v("MongoDatabaseFactory")]),e._v("."),a("br"),e._v("If you want to take complete control of establishing the MongoDB connection, you can also declare your own "),a("code",[e._v("MongoDatabaseFactory")]),e._v(" or "),a("code",[e._v("MongoClient")]),e._v(" bean.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("If you are using the reactive driver, Netty is required for SSL."),a("br"),e._v("The auto-configuration configures this factory automatically if Netty is available and the factory to use has not been customized already.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h4",{attrs:{id:"_2-2-2-mongotemplate"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-2-mongotemplate"}},[e._v("#")]),e._v(" 2.2.2. MongoTemplate")]),e._v(" "),a("p",[a("a",{attrs:{href:"https://spring.io/projects/spring-data-mongodb",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data MongoDB"),a("OutboundLink")],1),e._v(" provides a "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/mongodb/docs/3.3.2/api/org/springframework/data/mongodb/core/MongoTemplate.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[e._v("MongoTemplate")]),a("OutboundLink")],1),e._v(" class that is very similar in its design to Spring’s "),a("code",[e._v("JdbcTemplate")]),e._v(".\nAs with "),a("code",[e._v("JdbcTemplate")]),e._v(", Spring Boot auto-configures a bean for you to inject the template, as follows:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('import com.mongodb.client.MongoCollection;\nimport org.bson.Document;\n\nimport org.springframework.data.mongodb.core.MongoTemplate;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class MyBean {\n\n private final MongoTemplate mongoTemplate;\n\n public MyBean(MongoTemplate mongoTemplate) {\n this.mongoTemplate = mongoTemplate;\n }\n\n // ...\n\n public MongoCollection someMethod() {\n return this.mongoTemplate.getCollection("users");\n }\n\n}\n\n')])])]),a("p",[e._v("See the "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/mongodb/docs/3.3.2/api/org/springframework/data/mongodb/core/MongoOperations.html",target:"_blank",rel:"noopener noreferrer"}},[a("code",[e._v("MongoOperations")]),e._v(" Javadoc"),a("OutboundLink")],1),e._v(" for complete details.")]),e._v(" "),a("h4",{attrs:{id:"_2-2-3-spring-data-mongodb-repositories"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-3-spring-data-mongodb-repositories"}},[e._v("#")]),e._v(" 2.2.3. Spring Data MongoDB Repositories")]),e._v(" "),a("p",[e._v("Spring Data includes repository support for MongoDB.\nAs with the JPA repositories discussed earlier, the basic principle is that queries are constructed automatically, based on method names.")]),e._v(" "),a("p",[e._v("In fact, both Spring Data JPA and Spring Data MongoDB share the same common infrastructure.\nYou could take the JPA example from earlier and, assuming that "),a("code",[e._v("City")]),e._v(" is now a MongoDB data class rather than a JPA "),a("code",[e._v("@Entity")]),e._v(", it works in the same way, as shown in the following example:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("import org.springframework.data.domain.Page;\nimport org.springframework.data.domain.Pageable;\nimport org.springframework.data.repository.Repository;\n\npublic interface CityRepository extends Repository {\n\n Page findAll(Pageable pageable);\n\n City findByNameAndStateAllIgnoringCase(String name, String state);\n\n}\n\n")])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("You can customize document scanning locations by using the "),a("code",[e._v("@EntityScan")]),e._v(" annotation.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("For complete details of Spring Data MongoDB, including its rich object mapping technologies, see its "),a("a",{attrs:{href:"https://spring.io/projects/spring-data-mongodb",target:"_blank",rel:"noopener noreferrer"}},[e._v("reference documentation"),a("OutboundLink")],1),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h4",{attrs:{id:"_2-2-4-embedded-mongo"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-4-embedded-mongo"}},[e._v("#")]),e._v(" 2.2.4. Embedded Mongo")]),e._v(" "),a("p",[e._v("Spring Boot offers auto-configuration for "),a("a",{attrs:{href:"https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo",target:"_blank",rel:"noopener noreferrer"}},[e._v("Embedded Mongo"),a("OutboundLink")],1),e._v(".\nTo use it in your Spring Boot application, add a dependency on "),a("code",[e._v("de.flapdoodle.embed:de.flapdoodle.embed.mongo")]),e._v(" and set the "),a("code",[e._v("spring.mongodb.embedded.version")]),e._v(" property to match the version of MongoDB that your application will use in production.")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("The default download configuration allows access to most of the versions listed in "),a("a",{attrs:{href:"https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo/blob/de.flapdoodle.embed.mongo-3.0.0/src/main/java/de/flapdoodle/embed/mongo/distribution/Version.java",target:"_blank",rel:"noopener noreferrer"}},[e._v("Embedded Mongo’s "),a("code",[e._v("Version")]),e._v(" class"),a("OutboundLink")],1),e._v(" as well as some others."),a("br"),e._v("Configuring an inaccessible version will result in an error when attempting to download the server."),a("br"),e._v("Such an error can be corrected by defining an appropriately configured "),a("code",[e._v("DownloadConfigBuilderCustomizer")]),e._v(" bean.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("p",[e._v("The port that Mongo listens on can be configured by setting the "),a("code",[e._v("spring.data.mongodb.port")]),e._v(" property.\nTo use a randomly allocated free port, use a value of 0.\nThe "),a("code",[e._v("MongoClient")]),e._v(" created by "),a("code",[e._v("MongoAutoConfiguration")]),e._v(" is automatically configured to use the randomly allocated port.")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("If you do not configure a custom port, the embedded support uses a random port (rather than 27017) by default.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("p",[e._v("If you have SLF4J on the classpath, the output produced by Mongo is automatically routed to a logger named "),a("code",[e._v("org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongo")]),e._v(".")]),e._v(" "),a("p",[e._v("You can declare your own "),a("code",[e._v("IMongodConfig")]),e._v(" and "),a("code",[e._v("IRuntimeConfig")]),e._v(" beans to take control of the Mongo instance’s configuration and logging routing.\nThe download configuration can be customized by declaring a "),a("code",[e._v("DownloadConfigBuilderCustomizer")]),e._v(" bean.")]),e._v(" "),a("h3",{attrs:{id:"_2-3-neo4j"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-neo4j"}},[e._v("#")]),e._v(" 2.3. Neo4j")]),e._v(" "),a("p",[a("a",{attrs:{href:"https://neo4j.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Neo4j"),a("OutboundLink")],1),e._v(" is an open-source NoSQL graph database that uses a rich data model of nodes connected by first class relationships, which is better suited for connected big data than traditional RDBMS approaches.\nSpring Boot offers several conveniences for working with Neo4j, including the "),a("code",[e._v("spring-boot-starter-data-neo4j")]),e._v(" “Starter”.")]),e._v(" "),a("h4",{attrs:{id:"_2-3-1-connecting-to-a-neo4j-database"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-1-connecting-to-a-neo4j-database"}},[e._v("#")]),e._v(" 2.3.1. Connecting to a Neo4j Database")]),e._v(" "),a("p",[e._v("To access a Neo4j server, you can inject an auto-configured "),a("code",[e._v("org.neo4j.driver.Driver")]),e._v(".\nBy default, the instance tries to connect to a Neo4j server at "),a("code",[e._v("localhost:7687")]),e._v(" using the Bolt protocol.\nThe following example shows how to inject a Neo4j "),a("code",[e._v("Driver")]),e._v(" that gives you access, amongst other things, to a "),a("code",[e._v("Session")]),e._v(":")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('import org.neo4j.driver.Driver;\nimport org.neo4j.driver.Session;\nimport org.neo4j.driver.Values;\n\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class MyBean {\n\n private final Driver driver;\n\n public MyBean(Driver driver) {\n this.driver = driver;\n }\n\n // ...\n\n public String someMethod(String message) {\n try (Session session = this.driver.session()) {\n return session.writeTransaction((transaction) -> transaction\n .run("CREATE (a:Greeting) SET a.message = $message RETURN a.message + \', from node \' + id(a)",\n Values.parameters("message", message))\n .single().get(0).asString());\n }\n }\n\n}\n\n')])])]),a("p",[e._v("You can configure various aspects of the driver using "),a("code",[e._v("spring.neo4j.*")]),e._v(" properties.\nThe following example shows how to configure the uri and credentials to use:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.neo4j.uri=bolt://my-server:7687\nspring.neo4j.authentication.username=neo4j\nspring.neo4j.authentication.password=secret\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n neo4j:\n uri: "bolt://my-server:7687"\n authentication:\n username: "neo4j"\n password: "secret"\n')])])]),a("p",[e._v("The auto-configured "),a("code",[e._v("Driver")]),e._v(" is created using "),a("code",[e._v("ConfigBuilder")]),e._v(".\nTo fine-tune its configuration, declare one or more "),a("code",[e._v("ConfigBuilderCustomizer")]),e._v(" beans.\nEach will be called in order with the "),a("code",[e._v("ConfigBuilder")]),e._v(" that is used to build the "),a("code",[e._v("Driver")]),e._v(".")]),e._v(" "),a("h4",{attrs:{id:"_2-3-2-spring-data-neo4j-repositories"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-2-spring-data-neo4j-repositories"}},[e._v("#")]),e._v(" 2.3.2. Spring Data Neo4j Repositories")]),e._v(" "),a("p",[e._v("Spring Data includes repository support for Neo4j.\nFor complete details of Spring Data Neo4j, see the "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/neo4j/docs/6.2.2/reference/html/",target:"_blank",rel:"noopener noreferrer"}},[e._v("reference documentation"),a("OutboundLink")],1),e._v(".")]),e._v(" "),a("p",[e._v("Spring Data Neo4j shares the common infrastructure with Spring Data JPA as many other Spring Data modules do.\nYou could take the JPA example from earlier and define "),a("code",[e._v("City")]),e._v(" as Spring Data Neo4j "),a("code",[e._v("@Node")]),e._v(" rather than JPA "),a("code",[e._v("@Entity")]),e._v(" and the repository abstraction works in the same way, as shown in the following example:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("import java.util.Optional;\n\nimport org.springframework.data.neo4j.repository.Neo4jRepository;\n\npublic interface CityRepository extends Neo4jRepository {\n\n Optional findOneByNameAndState(String name, String state);\n\n}\n\n")])])]),a("p",[e._v("The "),a("code",[e._v("spring-boot-starter-data-neo4j")]),e._v(" “Starter” enables the repository support as well as transaction management.\nSpring Boot supports both classic and reactive Neo4j repositories, using the "),a("code",[e._v("Neo4jTemplate")]),e._v(" or "),a("code",[e._v("ReactiveNeo4jTemplate")]),e._v(" beans.\nWhen Project Reactor is available on the classpath, the reactive style is also auto-configured.")]),e._v(" "),a("p",[e._v("You can customize the locations to look for repositories and entities by using "),a("code",[e._v("@EnableNeo4jRepositories")]),e._v(" and "),a("code",[e._v("@EntityScan")]),e._v(" respectively on a "),a("code",[e._v("@Configuration")]),e._v("-bean.")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("In an application using the reactive style, a "),a("code",[e._v("ReactiveTransactionManager")]),e._v(" is not auto-configured."),a("br"),e._v("To enable transaction management, the following bean must be defined in your configuration:"),a("br"),a("br"),a("code",[e._v("
import org.neo4j.driver.Driver;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.core.ReactiveDatabaseSelectionProvider;
import org.springframework.data.neo4j.core.transaction.ReactiveNeo4jTransactionManager;

@Configuration(proxyBeanMethods = false)
public class MyNeo4jConfiguration {

@Bean
public ReactiveNeo4jTransactionManager reactiveTransactionManager(Driver driver,
ReactiveDatabaseSelectionProvider databaseNameProvider) {
return new ReactiveNeo4jTransactionManager(driver, databaseNameProvider);
}

}

")])])])]),e._v(" "),a("tbody")]),e._v(" "),a("h3",{attrs:{id:"_2-4-solr"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-4-solr"}},[e._v("#")]),e._v(" 2.4. Solr")]),e._v(" "),a("p",[a("a",{attrs:{href:"https://lucene.apache.org/solr/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Apache Solr"),a("OutboundLink")],1),e._v(" is a search engine.\nSpring Boot offers basic auto-configuration for the Solr 5 client library.")]),e._v(" "),a("h4",{attrs:{id:"_2-4-1-connecting-to-solr"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-4-1-connecting-to-solr"}},[e._v("#")]),e._v(" 2.4.1. Connecting to Solr")]),e._v(" "),a("p",[e._v("You can inject an auto-configured "),a("code",[e._v("SolrClient")]),e._v(" instance as you would any other Spring bean.\nBy default, the instance tries to connect to a server at "),a("code",[e._v("[localhost:8983/solr](http://localhost:8983/solr)")]),e._v(".\nThe following example shows how to inject a Solr bean:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('import java.io.IOException;\n\nimport org.apache.solr.client.solrj.SolrClient;\nimport org.apache.solr.client.solrj.SolrServerException;\nimport org.apache.solr.client.solrj.response.SolrPingResponse;\n\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class MyBean {\n\n private final SolrClient solr;\n\n public MyBean(SolrClient solr) {\n this.solr = solr;\n }\n\n // ...\n\n public SolrPingResponse someMethod() throws SolrServerException, IOException {\n return this.solr.ping("users");\n }\n\n}\n\n')])])]),a("p",[e._v("If you add your own "),a("code",[e._v("@Bean")]),e._v(" of type "),a("code",[e._v("SolrClient")]),e._v(", it replaces the default.")]),e._v(" "),a("h3",{attrs:{id:"_2-5-elasticsearch"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-elasticsearch"}},[e._v("#")]),e._v(" 2.5. Elasticsearch")]),e._v(" "),a("p",[a("a",{attrs:{href:"https://www.elastic.co/products/elasticsearch",target:"_blank",rel:"noopener noreferrer"}},[e._v("Elasticsearch"),a("OutboundLink")],1),e._v(" is an open source, distributed, RESTful search and analytics engine.\nSpring Boot offers basic auto-configuration for Elasticsearch clients.")]),e._v(" "),a("p",[e._v("Spring Boot supports several clients:")]),e._v(" "),a("ul",[a("li",[a("p",[e._v('The official Java "Low Level" and "High Level" REST clients')])]),e._v(" "),a("li",[a("p",[e._v("The "),a("code",[e._v("ReactiveElasticsearchClient")]),e._v(" provided by Spring Data Elasticsearch")])])]),e._v(" "),a("p",[e._v("Spring Boot provides a dedicated “Starter”, "),a("code",[e._v("spring-boot-starter-data-elasticsearch")]),e._v(".")]),e._v(" "),a("h4",{attrs:{id:"_2-5-1-connecting-to-elasticsearch-using-rest-clients"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-1-connecting-to-elasticsearch-using-rest-clients"}},[e._v("#")]),e._v(" 2.5.1. Connecting to Elasticsearch using REST clients")]),e._v(" "),a("p",[e._v("Elasticsearch ships "),a("a",{attrs:{href:"https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("two different REST clients"),a("OutboundLink")],1),e._v(' that you can use to query a cluster: the "Low Level" client and the "High Level" client.\nSpring Boot provides support for the "High Level" client, which ships with '),a("code",[e._v("org.elasticsearch.client:elasticsearch-rest-high-level-client")]),e._v(".\nAdditionally, Spring Boot provides support for a reactive client, based on Spring Framework’s "),a("code",[e._v("WebClient")]),e._v(", that ships with "),a("code",[e._v("org.springframework.data:spring-data-elasticsearch")]),e._v(".\nBy default, the clients will target "),a("code",[e._v("[localhost:9200](http://localhost:9200)")]),e._v(".\nYou can use "),a("code",[e._v("spring.elasticsearch.*")]),e._v(" properties to further tune how the clients are configured, as shown in the following example:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.elasticsearch.uris=https://search.example.com:9200\nspring.elasticsearch.socket-timeout=10s\nspring.elasticsearch.username=user\nspring.elasticsearch.password=secret\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n elasticsearch:\n uris: "https://search.example.com:9200"\n socket-timeout: "10s"\n username: "user"\n password: "secret"\n')])])]),a("h5",{attrs:{id:"connecting-to-elasticsearch-using-resthighlevelclient"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#connecting-to-elasticsearch-using-resthighlevelclient"}},[e._v("#")]),e._v(" Connecting to Elasticsearch using RestHighLevelClient")]),e._v(" "),a("p",[e._v("If you have "),a("code",[e._v("elasticsearch-rest-high-level-client")]),e._v(" on the classpath, Spring Boot will auto-configure and register a "),a("code",[e._v("RestHighLevelClient")]),e._v(" bean.\nIn addition to the properties described previously, to fine-tune the "),a("code",[e._v("RestHighLevelClient")]),e._v(", you can register an arbitrary number of beans that implement "),a("code",[e._v("RestClientBuilderCustomizer")]),e._v(" for more advanced customizations.\nTo take full control over its registration, define a "),a("code",[e._v("RestClientBuilder")]),e._v(" bean.")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v('If your application needs access to a "Low Level" '),a("code",[e._v("RestClient")]),e._v(", you can get it by calling "),a("code",[e._v("client.getLowLevelClient()")]),e._v(" on the auto-configured "),a("code",[e._v("RestHighLevelClient")]),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("p",[e._v("Additionally, if "),a("code",[e._v("elasticsearch-rest-client-sniffer")]),e._v(" is on the classpath, a "),a("code",[e._v("Sniffer")]),e._v(" is auto-configured to automatically discover nodes from a running Elasticsearch cluster and set them on the "),a("code",[e._v("RestHighLevelClient")]),e._v(" bean.\nYou can further tune how "),a("code",[e._v("Sniffer")]),e._v(" is configured, as shown in the following example:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.elasticsearch.restclient.sniffer.interval=10m\nspring.elasticsearch.restclient.sniffer.delay-after-failure=30s\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n elasticsearch:\n restclient:\n sniffer:\n interval: "10m"\n delay-after-failure: "30s"\n')])])]),a("h5",{attrs:{id:"connecting-to-elasticsearch-using-reactiveelasticsearchclient"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#connecting-to-elasticsearch-using-reactiveelasticsearchclient"}},[e._v("#")]),e._v(" Connecting to Elasticsearch using ReactiveElasticsearchClient")]),e._v(" "),a("p",[a("a",{attrs:{href:"https://spring.io/projects/spring-data-elasticsearch",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data Elasticsearch"),a("OutboundLink")],1),e._v(" ships "),a("code",[e._v("ReactiveElasticsearchClient")]),e._v(" for querying Elasticsearch instances in a reactive fashion.\nIt is built on top of WebFlux’s "),a("code",[e._v("WebClient")]),e._v(", so both "),a("code",[e._v("spring-boot-starter-elasticsearch")]),e._v(" and "),a("code",[e._v("spring-boot-starter-webflux")]),e._v(" dependencies are useful to enable this support.")]),e._v(" "),a("p",[e._v("By default, Spring Boot will auto-configure and register a "),a("code",[e._v("ReactiveElasticsearchClient")]),e._v(".\nIn addition to the properties described previously, the "),a("code",[e._v("spring.elasticsearch.webclient.*")]),e._v(" properties can be used to configure reactive-specific settings, as shown in the following example:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.elasticsearch.webclient.max-in-memory-size=1MB\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n elasticsearch:\n webclient:\n max-in-memory-size: "1MB"\n')])])]),a("p",[e._v("If the "),a("code",[e._v("spring.elasticsearch.")]),e._v(" "),a("strong",[e._v("and "),a("code",[e._v("spring.elasticsearch.webclient.")])]),e._v(" configuration properties are not enough and you’d like to fully control the client configuration, you can register a custom "),a("code",[e._v("ClientConfiguration")]),e._v(" bean.")]),e._v(" "),a("h4",{attrs:{id:"_2-5-2-connecting-to-elasticsearch-by-using-spring-data"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-2-connecting-to-elasticsearch-by-using-spring-data"}},[e._v("#")]),e._v(" 2.5.2. Connecting to Elasticsearch by Using Spring Data")]),e._v(" "),a("p",[e._v("To connect to Elasticsearch, a "),a("code",[e._v("RestHighLevelClient")]),e._v(" bean must be defined,\nauto-configured by Spring Boot or manually provided by the application (see previous sections).\nWith this configuration in place, an"),a("code",[e._v("ElasticsearchRestTemplate")]),e._v(" can be injected like any other Spring bean,\nas shown in the following example:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class MyBean {\n\n private final ElasticsearchRestTemplate template;\n\n public MyBean(ElasticsearchRestTemplate template) {\n this.template = template;\n }\n\n // ...\n\n public boolean someMethod(String id) {\n return this.template.exists(id, User.class);\n }\n\n}\n\n")])])]),a("p",[e._v("In the presence of "),a("code",[e._v("spring-data-elasticsearch")]),e._v(" and the required dependencies for using a "),a("code",[e._v("WebClient")]),e._v(" (typically "),a("code",[e._v("spring-boot-starter-webflux")]),e._v("), Spring Boot can also auto-configure a "),a("RouterLink",{attrs:{to:"/en/spring-boot/features.html#data.nosql.elasticsearch.connecting-using-rest.webclient"}},[e._v("ReactiveElasticsearchClient")]),e._v(" and a "),a("code",[e._v("ReactiveElasticsearchTemplate")]),e._v(" as beans.\nThey are the reactive equivalent of the other REST clients.")],1),e._v(" "),a("h4",{attrs:{id:"_2-5-3-spring-data-elasticsearch-repositories"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-3-spring-data-elasticsearch-repositories"}},[e._v("#")]),e._v(" 2.5.3. Spring Data Elasticsearch Repositories")]),e._v(" "),a("p",[e._v("Spring Data includes repository support for Elasticsearch.\nAs with the JPA repositories discussed earlier, the basic principle is that queries are constructed for you automatically based on method names.")]),e._v(" "),a("p",[e._v("In fact, both Spring Data JPA and Spring Data Elasticsearch share the same common infrastructure.\nYou could take the JPA example from earlier and, assuming that "),a("code",[e._v("City")]),e._v(" is now an Elasticsearch "),a("code",[e._v("@Document")]),e._v(" class rather than a JPA "),a("code",[e._v("@Entity")]),e._v(", it works in the same way.")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("For complete details of Spring Data Elasticsearch, see the "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/",target:"_blank",rel:"noopener noreferrer"}},[e._v("reference documentation"),a("OutboundLink")],1),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("p",[e._v("Spring Boot supports both classic and reactive Elasticsearch repositories, using the "),a("code",[e._v("ElasticsearchRestTemplate")]),e._v(" or "),a("code",[e._v("ReactiveElasticsearchTemplate")]),e._v(" beans.\nMost likely those beans are auto-configured by Spring Boot given the required dependencies are present.")]),e._v(" "),a("p",[e._v("If you wish to use your own template for backing the Elasticsearch repositories, you can add your own "),a("code",[e._v("ElasticsearchRestTemplate")]),e._v(" or "),a("code",[e._v("ElasticsearchOperations")]),e._v(" "),a("code",[e._v("@Bean")]),e._v(", as long as it is named "),a("code",[e._v('"elasticsearchTemplate"')]),e._v(".\nSame applies to "),a("code",[e._v("ReactiveElasticsearchTemplate")]),e._v(" and "),a("code",[e._v("ReactiveElasticsearchOperations")]),e._v(", with the bean name "),a("code",[e._v('"reactiveElasticsearchTemplate"')]),e._v(".")]),e._v(" "),a("p",[e._v("You can choose to disable the repositories support with the following property:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.data.elasticsearch.repositories.enabled=false\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring:\n data:\n elasticsearch:\n repositories:\n enabled: false\n")])])]),a("h3",{attrs:{id:"_2-6-cassandra"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-cassandra"}},[e._v("#")]),e._v(" 2.6. Cassandra")]),e._v(" "),a("p",[a("a",{attrs:{href:"https://cassandra.apache.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Cassandra"),a("OutboundLink")],1),e._v(" is an open source, distributed database management system designed to handle large amounts of data across many commodity servers.\nSpring Boot offers auto-configuration for Cassandra and the abstractions on top of it provided by "),a("a",{attrs:{href:"https://github.com/spring-projects/spring-data-cassandra",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data Cassandra"),a("OutboundLink")],1),e._v(".\nThere is a "),a("code",[e._v("spring-boot-starter-data-cassandra")]),e._v(" “Starter” for collecting the dependencies in a convenient way.")]),e._v(" "),a("h4",{attrs:{id:"_2-6-1-connecting-to-cassandra"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-1-connecting-to-cassandra"}},[e._v("#")]),e._v(" 2.6.1. Connecting to Cassandra")]),e._v(" "),a("p",[e._v("You can inject an auto-configured "),a("code",[e._v("CassandraTemplate")]),e._v(" or a Cassandra "),a("code",[e._v("CqlSession")]),e._v(" instance as you would with any other Spring Bean.\nThe "),a("code",[e._v("spring.data.cassandra.*")]),e._v(" properties can be used to customize the connection.\nGenerally, you provide "),a("code",[e._v("keyspace-name")]),e._v(" and "),a("code",[e._v("contact-points")]),e._v(" as well the local datacenter name, as shown in the following example:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.data.cassandra.keyspace-name=mykeyspace\nspring.data.cassandra.contact-points=cassandrahost1:9042,cassandrahost2:9042\nspring.data.cassandra.local-datacenter=datacenter1\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n data:\n cassandra:\n keyspace-name: "mykeyspace"\n contact-points: "cassandrahost1:9042,cassandrahost2:9042"\n local-datacenter: "datacenter1"\n')])])]),a("p",[e._v("If the port is the same for all your contact points you can use a shortcut and only specify the host names, as shown in the following example:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.data.cassandra.keyspace-name=mykeyspace\nspring.data.cassandra.contact-points=cassandrahost1,cassandrahost2\nspring.data.cassandra.local-datacenter=datacenter1\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n data:\n cassandra:\n keyspace-name: "mykeyspace"\n contact-points: "cassandrahost1,cassandrahost2"\n local-datacenter: "datacenter1"\n')])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("Those two examples are identical as the port default to "),a("code",[e._v("9042")]),e._v("."),a("br"),e._v("If you need to configure the port, use "),a("code",[e._v("spring.data.cassandra.port")]),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("The Cassandra driver has its own configuration infrastructure that loads an "),a("code",[e._v("application.conf")]),e._v(" at the root of the classpath."),a("br"),a("br"),e._v("Spring Boot does not look for such a file by default but can load one using "),a("code",[e._v("spring.data.cassandra.config")]),e._v("."),a("br"),e._v("If a property is both present in "),a("code",[e._v("spring.data.cassandra.*")]),e._v(" and the configuration file, the value in "),a("code",[e._v("spring.data.cassandra.*")]),e._v(" takes precedence."),a("br"),a("br"),e._v("For more advanced driver customizations, you can register an arbitrary number of beans that implement "),a("code",[e._v("DriverConfigLoaderBuilderCustomizer")]),e._v("."),a("br"),e._v("The "),a("code",[e._v("CqlSession")]),e._v(" can be customized with a bean of type "),a("code",[e._v("CqlSessionBuilderCustomizer")]),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("If you use "),a("code",[e._v("CqlSessionBuilder")]),e._v(" to create multiple "),a("code",[e._v("CqlSession")]),e._v(" beans, keep in mind the builder is mutable so make sure to inject a fresh copy for each session.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("p",[e._v("The following code listing shows how to inject a Cassandra bean:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("import org.springframework.data.cassandra.core.CassandraTemplate;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class MyBean {\n\n private final CassandraTemplate template;\n\n public MyBean(CassandraTemplate template) {\n this.template = template;\n }\n\n // ...\n\n public long someMethod() {\n return this.template.count(User.class);\n }\n\n}\n\n")])])]),a("p",[e._v("If you add your own "),a("code",[e._v("@Bean")]),e._v(" of type "),a("code",[e._v("CassandraTemplate")]),e._v(", it replaces the default.")]),e._v(" "),a("h4",{attrs:{id:"_2-6-2-spring-data-cassandra-repositories"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-2-spring-data-cassandra-repositories"}},[e._v("#")]),e._v(" 2.6.2. Spring Data Cassandra Repositories")]),e._v(" "),a("p",[e._v("Spring Data includes basic repository support for Cassandra.\nCurrently, this is more limited than the JPA repositories discussed earlier and needs to annotate finder methods with "),a("code",[e._v("@Query")]),e._v(".")]),e._v(" "),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("For complete details of Spring Data Cassandra, see the "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/cassandra/docs/",target:"_blank",rel:"noopener noreferrer"}},[e._v("reference documentation"),a("OutboundLink")],1),e._v(".")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h3",{attrs:{id:"_2-7-couchbase"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-7-couchbase"}},[e._v("#")]),e._v(" 2.7. Couchbase")]),e._v(" "),a("p",[a("a",{attrs:{href:"https://www.couchbase.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Couchbase"),a("OutboundLink")],1),e._v(" is an open-source, distributed, multi-model NoSQL document-oriented database that is optimized for interactive applications.\nSpring Boot offers auto-configuration for Couchbase and the abstractions on top of it provided by "),a("a",{attrs:{href:"https://github.com/spring-projects/spring-data-couchbase",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data Couchbase"),a("OutboundLink")],1),e._v(".\nThere are "),a("code",[e._v("spring-boot-starter-data-couchbase")]),e._v(" and "),a("code",[e._v("spring-boot-starter-data-couchbase-reactive")]),e._v(" “Starters” for collecting the dependencies in a convenient way.")]),e._v(" "),a("h4",{attrs:{id:"_2-7-1-connecting-to-couchbase"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-7-1-connecting-to-couchbase"}},[e._v("#")]),e._v(" 2.7.1. Connecting to Couchbase")]),e._v(" "),a("p",[e._v("You can get a "),a("code",[e._v("Cluster")]),e._v(" by adding the Couchbase SDK and some configuration.\nThe "),a("code",[e._v("spring.couchbase.*")]),e._v(" properties can be used to customize the connection.\nGenerally, you provide the "),a("a",{attrs:{href:"https://github.com/couchbaselabs/sdk-rfcs/blob/master/rfc/0011-connection-string.md",target:"_blank",rel:"noopener noreferrer"}},[e._v("connection string"),a("OutboundLink")],1),e._v(", username, and password, as shown in the following example:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.couchbase.connection-string=couchbase://192.168.1.123\nspring.couchbase.username=user\nspring.couchbase.password=secret\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n couchbase:\n connection-string: "couchbase://192.168.1.123"\n username: "user"\n password: "secret"\n')])])]),a("p",[e._v("It is also possible to customize some of the "),a("code",[e._v("ClusterEnvironment")]),e._v(" settings.\nFor instance, the following configuration changes the timeout to use to open a new "),a("code",[e._v("Bucket")]),e._v(" and enables SSL support:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.couchbase.env.timeouts.connect=3s\nspring.couchbase.env.ssl.key-store=/location/of/keystore.jks\nspring.couchbase.env.ssl.key-store-password=secret\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n couchbase:\n env:\n timeouts:\n connect: "3s"\n ssl:\n key-store: "/location/of/keystore.jks"\n key-store-password: "secret"\n')])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("Check the "),a("code",[e._v("spring.couchbase.env.*")]),e._v(" properties for more details."),a("br"),e._v("To take more control, one or more "),a("code",[e._v("ClusterEnvironmentBuilderCustomizer")]),e._v(" beans can be used.")])])]),e._v(" "),a("tbody")]),e._v(" "),a("h4",{attrs:{id:"_2-7-2-spring-data-couchbase-repositories"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-7-2-spring-data-couchbase-repositories"}},[e._v("#")]),e._v(" 2.7.2. Spring Data Couchbase Repositories")]),e._v(" "),a("p",[e._v("Spring Data includes repository support for Couchbase.\nFor complete details of Spring Data Couchbase, see the "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/couchbase/docs/4.3.2/reference/html/",target:"_blank",rel:"noopener noreferrer"}},[e._v("reference documentation"),a("OutboundLink")],1),e._v(".")]),e._v(" "),a("p",[e._v("You can inject an auto-configured "),a("code",[e._v("CouchbaseTemplate")]),e._v(" instance as you would with any other Spring Bean, provided a "),a("code",[e._v("CouchbaseClientFactory")]),e._v(" bean is available.\nThis happens when a "),a("code",[e._v("Cluster")]),e._v(" is available, as described above, and a bucket name has been specified:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.data.couchbase.bucket-name=my-bucket\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n data:\n couchbase:\n bucket-name: "my-bucket"\n')])])]),a("p",[e._v("The following examples shows how to inject a "),a("code",[e._v("CouchbaseTemplate")]),e._v(" bean:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("import org.springframework.data.couchbase.core.CouchbaseTemplate;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class MyBean {\n\n private final CouchbaseTemplate template;\n\n public MyBean(CouchbaseTemplate template) {\n this.template = template;\n }\n\n // ...\n\n public String someMethod() {\n return this.template.getBucketName();\n }\n\n}\n\n")])])]),a("p",[e._v("There are a few beans that you can define in your own configuration to override those provided by the auto-configuration:")]),e._v(" "),a("ul",[a("li",[a("p",[e._v("A "),a("code",[e._v("CouchbaseMappingContext")]),e._v(" "),a("code",[e._v("@Bean")]),e._v(" with a name of "),a("code",[e._v("couchbaseMappingContext")]),e._v(".")])]),e._v(" "),a("li",[a("p",[e._v("A "),a("code",[e._v("CustomConversions")]),e._v(" "),a("code",[e._v("@Bean")]),e._v(" with a name of "),a("code",[e._v("couchbaseCustomConversions")]),e._v(".")])]),e._v(" "),a("li",[a("p",[e._v("A "),a("code",[e._v("CouchbaseTemplate")]),e._v(" "),a("code",[e._v("@Bean")]),e._v(" with a name of "),a("code",[e._v("couchbaseTemplate")]),e._v(".")])])]),e._v(" "),a("p",[e._v("To avoid hard-coding those names in your own config, you can reuse "),a("code",[e._v("BeanNames")]),e._v(" provided by Spring Data Couchbase.\nFor instance, you can customize the converters to use, as follows:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("import org.assertj.core.util.Arrays;\n\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.data.couchbase.config.BeanNames;\nimport org.springframework.data.couchbase.core.convert.CouchbaseCustomConversions;\n\n@Configuration(proxyBeanMethods = false)\npublic class MyCouchbaseConfiguration {\n\n @Bean(BeanNames.COUCHBASE_CUSTOM_CONVERSIONS)\n public CouchbaseCustomConversions myCustomConversions() {\n return new CouchbaseCustomConversions(Arrays.asList(new MyConverter()));\n }\n\n}\n\n")])])]),a("h3",{attrs:{id:"_2-8-ldap"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-8-ldap"}},[e._v("#")]),e._v(" 2.8. LDAP")]),e._v(" "),a("p",[a("a",{attrs:{href:"https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol",target:"_blank",rel:"noopener noreferrer"}},[e._v("LDAP"),a("OutboundLink")],1),e._v(" (Lightweight Directory Access Protocol) is an open, vendor-neutral, industry standard application protocol for accessing and maintaining distributed directory information services over an IP network.\nSpring Boot offers auto-configuration for any compliant LDAP server as well as support for the embedded in-memory LDAP server from "),a("a",{attrs:{href:"https://ldap.com/unboundid-ldap-sdk-for-java/",target:"_blank",rel:"noopener noreferrer"}},[e._v("UnboundID"),a("OutboundLink")],1),e._v(".")]),e._v(" "),a("p",[e._v("LDAP abstractions are provided by "),a("a",{attrs:{href:"https://github.com/spring-projects/spring-data-ldap",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data LDAP"),a("OutboundLink")],1),e._v(".\nThere is a "),a("code",[e._v("spring-boot-starter-data-ldap")]),e._v(" “Starter” for collecting the dependencies in a convenient way.")]),e._v(" "),a("h4",{attrs:{id:"_2-8-1-connecting-to-an-ldap-server"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-8-1-connecting-to-an-ldap-server"}},[e._v("#")]),e._v(" 2.8.1. Connecting to an LDAP Server")]),e._v(" "),a("p",[e._v("To connect to an LDAP server, make sure you declare a dependency on the "),a("code",[e._v("spring-boot-starter-data-ldap")]),e._v(" “Starter” or "),a("code",[e._v("spring-ldap-core")]),e._v(" and then declare the URLs of your server in your application.properties, as shown in the following example:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.ldap.urls=ldap://myserver:1235\nspring.ldap.username=admin\nspring.ldap.password=secret\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n ldap:\n urls: "ldap://myserver:1235"\n username: "admin"\n password: "secret"\n')])])]),a("p",[e._v("If you need to customize connection settings, you can use the "),a("code",[e._v("spring.ldap.base")]),e._v(" and "),a("code",[e._v("spring.ldap.base-environment")]),e._v(" properties.")]),e._v(" "),a("p",[e._v("An "),a("code",[e._v("LdapContextSource")]),e._v(" is auto-configured based on these settings.\nIf a "),a("code",[e._v("DirContextAuthenticationStrategy")]),e._v(" bean is available, it is associated to the auto-configured "),a("code",[e._v("LdapContextSource")]),e._v(".\nIf you need to customize it, for instance to use a "),a("code",[e._v("PooledContextSource")]),e._v(", you can still inject the auto-configured "),a("code",[e._v("LdapContextSource")]),e._v(".\nMake sure to flag your customized "),a("code",[e._v("ContextSource")]),e._v(" as "),a("code",[e._v("@Primary")]),e._v(" so that the auto-configured "),a("code",[e._v("LdapTemplate")]),e._v(" uses it.")]),e._v(" "),a("h4",{attrs:{id:"_2-8-2-spring-data-ldap-repositories"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-8-2-spring-data-ldap-repositories"}},[e._v("#")]),e._v(" 2.8.2. Spring Data LDAP Repositories")]),e._v(" "),a("p",[e._v("Spring Data includes repository support for LDAP.\nFor complete details of Spring Data LDAP, see the "),a("a",{attrs:{href:"https://docs.spring.io/spring-data/ldap/docs/1.0.x/reference/html/",target:"_blank",rel:"noopener noreferrer"}},[e._v("reference documentation"),a("OutboundLink")],1),e._v(".")]),e._v(" "),a("p",[e._v("You can also inject an auto-configured "),a("code",[e._v("LdapTemplate")]),e._v(" instance as you would with any other Spring Bean, as shown in the following example:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("import java.util.List;\n\nimport org.springframework.ldap.core.LdapTemplate;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class MyBean {\n\n private final LdapTemplate template;\n\n public MyBean(LdapTemplate template) {\n this.template = template;\n }\n\n // ...\n\n public List someMethod() {\n return this.template.findAll(User.class);\n }\n\n}\n\n")])])]),a("h4",{attrs:{id:"_2-8-3-embedded-in-memory-ldap-server"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-8-3-embedded-in-memory-ldap-server"}},[e._v("#")]),e._v(" 2.8.3. Embedded In-memory LDAP Server")]),e._v(" "),a("p",[e._v("For testing purposes, Spring Boot supports auto-configuration of an in-memory LDAP server from "),a("a",{attrs:{href:"https://ldap.com/unboundid-ldap-sdk-for-java/",target:"_blank",rel:"noopener noreferrer"}},[e._v("UnboundID"),a("OutboundLink")],1),e._v(".\nTo configure the server, add a dependency to "),a("code",[e._v("com.unboundid:unboundid-ldapsdk")]),e._v(" and declare a "),a("code",[e._v("spring.ldap.embedded.base-dn")]),e._v(" property, as follows:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.ldap.embedded.base-dn=dc=spring,dc=io\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n ldap:\n embedded:\n base-dn: "dc=spring,dc=io"\n')])])]),a("table",[a("thead",[a("tr",[a("th"),e._v(" "),a("th",[e._v("It is possible to define multiple base-dn values, however, since distinguished names usually contain commas, they must be defined using the correct notation."),a("br"),a("br"),e._v("In yaml files, you can use the yaml list notation. In properties files, you must include the index as part of the property name:"),a("br"),a("br"),e._v("Properties"),a("br"),a("br"),a("code",[e._v("
spring.ldap.embedded.base-dn[0]=dc=spring,dc=io
spring.ldap.embedded.base-dn[1]=dc=pivotal,dc=io
")]),a("br"),a("br"),e._v("Yaml"),a("br"),a("br"),a("code",[e._v('
spring.ldap.embedded.base-dn:
- "dc=spring,dc=io"
- "dc=pivotal,dc=io"
')])])])]),e._v(" "),a("tbody")]),e._v(" "),a("p",[e._v("By default, the server starts on a random port and triggers the regular LDAP support.\nThere is no need to specify a "),a("code",[e._v("spring.ldap.urls")]),e._v(" property.")]),e._v(" "),a("p",[e._v("If there is a "),a("code",[e._v("schema.ldif")]),e._v(" file on your classpath, it is used to initialize the server.\nIf you want to load the initialization script from a different resource, you can also use the "),a("code",[e._v("spring.ldap.embedded.ldif")]),e._v(" property.")]),e._v(" "),a("p",[e._v("By default, a standard schema is used to validate "),a("code",[e._v("LDIF")]),e._v(" files.\nYou can turn off validation altogether by setting the "),a("code",[e._v("spring.ldap.embedded.validation.enabled")]),e._v(" property.\nIf you have custom attributes, you can use "),a("code",[e._v("spring.ldap.embedded.validation.schema")]),e._v(" to define your custom attribute types or object classes.")]),e._v(" "),a("h3",{attrs:{id:"_2-9-influxdb"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-9-influxdb"}},[e._v("#")]),e._v(" 2.9. InfluxDB")]),e._v(" "),a("p",[a("a",{attrs:{href:"https://www.influxdata.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("InfluxDB"),a("OutboundLink")],1),e._v(" is an open-source time series database optimized for fast, high-availability storage and retrieval of time series data in fields such as operations monitoring, application metrics, Internet-of-Things sensor data, and real-time analytics.")]),e._v(" "),a("h4",{attrs:{id:"_2-9-1-connecting-to-influxdb"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2-9-1-connecting-to-influxdb"}},[e._v("#")]),e._v(" 2.9.1. Connecting to InfluxDB")]),e._v(" "),a("p",[e._v("Spring Boot auto-configures an "),a("code",[e._v("InfluxDB")]),e._v(" instance, provided the "),a("code",[e._v("influxdb-java")]),e._v(" client is on the classpath and the URL of the database is set, as shown in the following example:")]),e._v(" "),a("p",[e._v("Properties")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("spring.influx.url=https://172.0.0.1:8086\n")])])]),a("p",[e._v("Yaml")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v('spring:\n influx:\n url: "https://172.0.0.1:8086"\n')])])]),a("p",[e._v("If the connection to InfluxDB requires a user and password, you can set the "),a("code",[e._v("spring.influx.user")]),e._v(" and "),a("code",[e._v("spring.influx.password")]),e._v(" properties accordingly.")]),e._v(" "),a("p",[e._v("InfluxDB relies on OkHttp.\nIf you need to tune the http client "),a("code",[e._v("InfluxDB")]),e._v(" uses behind the scenes, you can register an "),a("code",[e._v("InfluxDbOkHttpClientBuilderProvider")]),e._v(" bean.")]),e._v(" "),a("p",[e._v("If you need more control over the configuration, consider registering an "),a("code",[e._v("InfluxDbCustomizer")]),e._v(" bean.")]),e._v(" "),a("h2",{attrs:{id:"_3-what-to-read-next"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3-what-to-read-next"}},[e._v("#")]),e._v(" 3. What to Read Next")]),e._v(" "),a("hr"),e._v(" "),a("p",[e._v("You should now have a feeling for how to use Spring Boot with various data technologies.\nFrom here, you can read about Spring Boot’s support for various "),a("RouterLink",{attrs:{to:"/en/spring-boot/messaging.html#messaging"}},[e._v("messaging technologies")]),e._v(" and how to enable them in your application.")],1)])}),[],!1,null,null,null);t.default=n.exports}}]);