Spring Boot dostarcza mechanizm szablonów Jdbc Templates, z wykorzystaniem których możemy w miarę wygodnie operować na bazach Sql ciągle pozostając na poziomie zapytań SQL.
Aby skorzystać z tej funkcjonalności dodaj zależność Spring Data JDBC.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
Pierwszy problem na jaki napotykamy przy próbie podłączenia się do baz InterBase to brak klienta JDBC w Maven Repository. Najlepszym rozwiązaniem będzie dodanie go do lokalnego repozytorium Mavena. Musisz oczywiście mieć zainstalowany klient lub serwer InterBase.
mvn install:install-file
-Dfile="c:\Program Files\Embarcadero\InterBase\SDK\lib\interclient.jar"
-DgroupId=com.embarcadero -DartifactId=interclient
-Dversion=12.0.0
-Dpackaging=jar
-DgeneratePom=true
Możemy teraz dodać zależność do pom.xml
<dependency>
<groupId>com.embarcadero</groupId>
<artifactId>interclient</artifactId>
<version>12.0.0</version>
</dependency>
Dodajmy teraz klasę konfiguracyjną połączenie z bazą danych
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class Config {
@Value("${target.database}")
private String database;
@Value("${target.server}")
private String server;
@Value("${target.charset}")
private String charset;
@Value("${target.port}")
private String port;
@Value("${target.username}")
private String username;
@Value("${target.password}")
private String password;
@Bean
public DataSource interbaseDataSource() {
interbase.interclient.DataSource dataSource = new interbase.interclient.DataSource();
dataSource.setDatabaseName(database);
dataSource.setServerName(server);
dataSource.setCharSet(charset);
dataSource.setPortNumber(Integer.parseInt(port));
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource;
}
}
Spring Data JDBC wymaga jeszcze informacji o dialekcie, dodajmy więc klasę konfiguracyjną:
@Configuration
public class SpringDataJdbcConfiguration extends AbstractJdbcConfiguration {
@Override
public Dialect jdbcDialect(NamedParameterJdbcOperations operations) {
return AnsiDialect.INSTANCE;
}
}
Parametry połączenia ustawiamy w pliku application.properties
target.server=127.0.0.1
target.port=3050
target.charset=Cp1250
target.database=c:\\Users\\All Users\\Application Data\\Embarcadero\\InterBase\\gds_db\\examples\\database\\employee.gdb
target.username=sysdba
target.password=masterkey
spring.jpa.database-platform=org.hibernate.dialect.InterbaseDialect
hibernate.dialect=org.hibernate.dialect.InterbaseDialect
Pobierzmy dane z tabeli pracowników bazy employee.gdb
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import pl.bilansjr.jdbctemplates.demo.domain.Employee;
import pl.bilansjr.jdbctemplates.demo.domain.EmployeeRowMapper;
import java.util.List;
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
private static final String SELECT_COUNT_EMPLOYEE = "SELECT COUNT(*) FROM EMPLOYEE";
private static final String SELECT_ALL_EMPLOYEE = "SELECT * FROM EMPLOYEE";
private static final String SELECT_ALL_EMPLOYEE_WITH_FIELD_ALIAS = "SELECT EMP_NO AS ID, FIRST_NAME, LAST_NAME, SALARY FROM EMPLOYEE";
final JdbcTemplate jdbcTemplate;
public DemoApplication(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
Integer employeeCount = jdbcTemplate.queryForObject(SELECT_COUNT_EMPLOYEE, Integer.class);
System.out.println(employeeCount);
}
}
Spróbujmy teraz wczytać wszystkich pracowników. Stwórzmy encję Employee:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
private Integer id;
private String firstName;
private String lastName;
private BigDecimal salary;
}
oraz mapper, który wykorzystamy podczas tworzenia obiektów Employee
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
public class EmployeeRowMapper implements RowMapper {
@Override
public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
Employee employee = new Employee();
employee.setId(rs.getInt("EMP_NO"));
employee.setFirstName(rs.getString("FIRST_NAME"));
employee.setLastName(rs.getString("LAST_NAME"));
employee.setSalary(rs.getBigDecimal("SALARY"));
return employee;
}
}
Wczytajmy pracowników do listy List<Employee>
String sql = SELECT_ALL_EMPLOYEE;
List employees = jdbcTemplate.query(sql, new EmployeeRowMapper());
employees.forEach(System.out::println);
Możemy również obejść się bez definiowania mappera
employees = jdbcTemplate.query(SELECT_ALL_EMPLOYEE_WITH_FIELD_ALIAS,
new BeanPropertyRowMapper(Employee.class));
employees.forEach(System.out::println);
Jak widzisz, aby skorzystać z BeanPropertyRowMapper
musimy uzyskać zgodność kolumn tabeli z polami encji. W tym celu kolumnę EMP_NO
identyfikujemy jako ID
.
SELECT EMP_NO AS ID, FIRST_NAME, LAST_NAME, SALARY FROM EMPLOYEE