I want to set up the database connection on Spring MVC with PostgreSQL, how do I do it?
I have tried google search but still, I have not found what I am looking for, so far I have added a PostgreSQL dependency on my project and here are the codes
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1206-jdbc42</version>
</dependency>
So where do I go from here?
how do I create the configuration files for db?
What is the default login credentials for db?
Where do I see the database table?
You need to configure your database connection. You can create a classe to configure this. For example:
#Configuration
public class DatabaseConfig {
#Bean
public DriverManagerDataSource getDataSource() {
DriverManagerDataSource bds = new DriverManagerDataSource();
bds.setDriverClassName("org.postgresql.Drive");
bds.setUrl("jdbc:mysql://localhost:5432/dbname");
bds.setUsername("user");
bds.setPassword("pass");
return bds;
}
}
And then, you can inject the datasource in your bens.
#Controller
public class MyController {
#Autowired
private DataSource dataSource;
}
Try to use Spring boot with spring data. Is very simple to configure a database connection and create repositories for data manipulations (CRUD). See this https://dzone.com/articles/spring-boot-with-spring-data-jpa
Related
I am working with spring boot. I have properties defined in application.yml.
spring:
datasource:
username: username
password: password
username and password values are stored externally which program fetches during startup. let's say the bean which fetches them during startup is dbConfig
How can I inject values from dbConfgig to application.yml?
I am using spring-data-jpa autoconfigure which automatically connects to database at startup. I want these values to be loaded to application.yml before spring connects to database.
There is no need to inject the user/password in application.yml. You can set them programmatically like this:
#Configuration
public class DataSourceConfig {
#Bean
public DataSource getDataSource() {
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.h2.Driver");
dataSourceBuilder.url("jdbc:h2:mem:test");
// Take the values from external source, then set them
dataSourceBuilder.username("username");
dataSourceBuilder.password("password");
return dataSourceBuilder.build();
}
}
I think that first, you must create a thread to detect the change at your db Config file and then may you must re-init your bean (data source) to make your change effect.
See:
how-to-reinitialize-a-spring-bean
You may also try spring cloud to store properties. And you can then use with the help of placeholders.
https://cloud.spring.io/spring-cloud-config/reference/html/
I am working on a Spring Boot web application and I am implementing the "Remember me" function.
I defined in my Web Security Configuration this:
http.authorizeRequests().and()
.rememberMe().tokenRepository(this.persistentTokenRepository())
.tokenValiditySeconds(1 * 24 * 60 * 60); // 24h
and
#Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
db.setDataSource(dataSource);
return db;
}
The problem is that when I flag the option on the html page, Spring try to add a token in the default schema of my database -> "public".
Is there any way to change the default schema for that option? Everything else is linked correctly on the right schema through this property:
spring.jpa.properties.hibernate.default_schema=another_schema_name
I tried to make a personal implement of the class JdbcTokenRepositoryImpl but I can't find a way to change the schema. I looked it up online but I didn't find nothing..
Thank you
Regards,
Mohamad
You may initialize differently your dataSource variable what you use in your PersistentTokenRepository bean. Most data sources support schema setting. For instance Spring's org.springframework.jdbc.datasource.DriverManagerDataSource :
#Bean(name = "dataSource")
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
// ... tipicly set username, password, driver class name, jdbc Url
dataSource.setSchema(schema);
return dataSource;
}
You could control the schema through the mentioned property: (spring.jpa.properties.hibernate.default_schema)
#Value("${spring.jpa.properties.hibernate.default_schema}")
private String schema;
I want to get data from oracle database in spring boot, but I dont want to use JPA. Can you give me an example, how I should do it? Thank you.
Using a Database without JPA in Spring-Boot you can use the JDBC starter of Spring-Boot.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
For Oracle you also need to use the JDBC driver. For example this one:
<dependency>
<groupId>oracle.jdbc</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2</version>
<classifier>jdk17</classifier>
</dependency>
In the application.properties file you have to configure the datasource:
spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
This is all you need for the configuration. To make a select to the database you have to autowire JdbcTemplate in any of your spring bean classes.
#Component
public class DataDao {
private final JdbcTemplate jdbcTemplate;
public DataDao(JdbcTemplate jdbcTemplate) {
super();
this.jdbcTemplate = jdbcTemplate;
}
After autowiring the jdbcTemplate you are able to query the database:
jdbcTemplate.query(yourQuery, RowMapper<?>);
I am trying to update datasource in Spring Boot when the DB property like DB name, password or hostname changes in the spring configuration file or custom DB property file. When the property changes the application has to update by its own by listening changes to property.
I was using Spring actuator to /restart beans once the DB configuration is changed. But user has to explicitly make a post request to restart. This step has to be avoided by listening to the changes and update datasource.
Can you tell me the best way to do this in Spring boot?
Found a way to update datasource on-the-fly,
I have given external spring config file which contains DB properties to the application and then refreshed the properties using #RefreshScope for the datasource bean.
A thread monitors the file changes and makes a call to actuator refresh() method.
database.properties
dburl=jdbc://localhost:5432/dbname
dbusername=user1
dbpassword=userpwd
Creating datasource,
#RefreshScope
public class DBPropRefresh {
#Value("${dburl}")
private String dbUrl;
#Value("${dbusername}")
private String dbUserName;
#Value("${dbpassword}")
private String dbPassword;
#Bean
#RefreshScope
public DataSource getDatasource() {
return new DatasourceBuilder().create().url(dbUrl).username(dbUserName).password(dbPassword);
}
}
Giving external config file to the application,
java -jar myapplication.jar --spring.config.location=database.properties
I have created a Java thread class to monitor database.properties file changes. Followed https://dzone.com/articles/how-watch-file-system-changes
When there are changes then it makes call to refreshEndPoint.refresh().
In pom.xml,
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>1.5.6.RELEASE</version>
</dependency>
You can use Spring's Dynamic Data Source routing and check if it helps? It's a very old technique and might come handy, if that serves your purpose.
But please note that - this is data source routing and not new data source configuration.
https://spring.io/blog/2007/01/23/dynamic-datasource-routing/
In my project I used multitenancy . Basically I defined several datasources in properties like this:
primary.datasource.url=jdbc:postgresql://localhost:5432/db_name?currentSchema=schema_name
primary.datasource.username=user
primary.datasource.password=password
primary.datasource.driverClassName=org.postgresql.Driver
primary.datasource.driver-class-name=org.postgresql.Driver
secondary.datasource.url=jdbc:postgresql://localhost:5432/other_db?currentSchema=schema
secondary.datasource.username=user
secondary.datasource.password=password
secondary.datasource.driverClassName=org.postgresql.Driver
secondary.datasource.driver-class-name=org.postgresql.Driver
default.datasource.url=jdbc:postgresql://localhost:5432/default_db?currentSchema=public
default.datasource.username=user
default.datasource.password=password
default.datasource.driverClassName=org.postgresql.Driver
default.datasource.driver-class-name=org.postgresql.Driver
then in configuration class defined multiple datasources:
#Bean
#Primary
#ConfigurationProperties(prefix="primary.datasource")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
#ConfigurationProperties(prefix="secondary.datasource")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
#ConfigurationProperties(prefix="default.datasource")
public DataSource defaultDataSource(){
return DataSourceBuilder.create().build();
}
and configured multitenancy basing on this and this article.
Pros:
Easy tenant switch which could be triggered manually or even configured to be triggered on some specific header in request (filters).
Could be cofigured to switch between schemas or databases.
Happens dynamically ( you don't have to restart your beans )
Cons:
You have to define all db possibilities in property file.
You have to turn off schema validation because it will go nuts.
I would like to know if Spring offers any support for Auto Fail over of Data Sources? For example, if the primary data source is down, connect to secondary. Any suggestions to effectively configure auto fail over of Data sources is greatly appreciated.
Thanks.
The Primary/DR setup for DB should be managed at DB level. Its not right to switch that in code. But to answer your question "can connect to 2 Data sources in Spring". Yes you can easier if you are using Spring-boot.
Few details from spring documentation.
Mark one of them as #Primary if you are using the default auto-configuration for JDBC or JPA (then that one will be picked up by any #Autowired injections).
#Bean
#Primary
#ConfigurationProperties(prefix="datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
#ConfigurationProperties(prefix="datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}