YDB Dialect for Spring Data JDBC
This guide is intended for use with Spring Data JDBC and YDB.
Spring Data JDBC is part of the Spring Data ecosystem, providing a simplified way to interact with relational databases using SQL and Java objects. Unlike Spring JPA, which relies on JPA (Java Persistence API), Spring Data offers a direct approach to working with databases, bypassing complex ORM (Object-Relational Mapping) for simpler methods.
Installing the YDB dialect
To integrate YDB with a Spring Data JDBC project, it needs two dependencies: the YDB JDBC driver and the Spring Data JDBC extension for YDB.
Examples for different build systems:
<!-- Set actual versions -->
<dependency>
    <groupId>tech.ydb.jdbc</groupId>
    <artifactId>ydb-jdbc-driver</artifactId>
    <version>${ydb.jdbc.version}</version>
</dependency>
<dependency>
    <groupId>tech.ydb.dialects</groupId>
    <artifactId>spring-data-jdbc-ydb</artifactId>
    <version>${spring.data.jdbc.ydb}</version>
</dependency>
        
    dependencies {
    // Set actual versions
    implementation "tech.ydb.dialects:spring-data-jdbc-ydb:$ydbDialectVersion"
    implementation "tech.ydb.jdbc:ydb-jdbc-driver:$ydbJdbcVersion"
}
        
    Usage
After importing all the necessary dependencies, the dialect is ready for use. Below is a simple example of a Spring Data JDBC application.
spring.datasource.driver-class-name=tech.ydb.jdbc.YdbDriver
spring.datasource.url=jdbc:ydb:<grpc/grpcs>://<host>:<2135/2136>/path/to/database[?saFile=file:~/sa_key.json]
        
    @Table(name = "Users")
public class User implements Persistable<Long> {
    @Id
    private Long id = ThreadLocalRandom.current().nextLong();
    private String login;
    private String firstname;
    private String lastname;
    @Transient
    private boolean isNew;
    // Constructors, getters and setters
    @Override
    public Long getId() {
      return id;
    }
    @Override
    public boolean isNew() {
      return isNew;
    }
    public void setNew(boolean isNew) {
      this.isNew = isNew;
    }
}
        
    Creating a repository for the User entity in the Users table:
public interface SimpleUserRepository extends CrudRepository<User, Long> {
}
        
    Saving a new user and verifying that it has been successfully saved:
@Component
public class UserRepositoryCommandLineRunner implements CommandLineRunner {
    @Autowired
    private SimpleUserRepository repository;
    @Override
    public void run(String... args) {
        User user = new User();
        user.setLogin("johndoe");
        user.setFirstname("John");
        user.setLastname("Doe");
        user.setNew(true);  // Setting the flag for the new entity
        // Save user
        User savedUser = repository.save(user);
        // Check saved user
        assertThat(repository.findById(savedUser.getId())).contains(savedUser);
        System.out.println("User saved with ID: " + savedUser.getId());
    }
}
        
    View Index
To generate VIEW INDEX statements from repository methods, use the @ViewIndex annotation. The @ViewIndex annotation has two fields:
indexName: The index name.tableName: The table name to which theVIEW INDEXis bound, which is particularly useful when using the@MappedCollectionannotation.
Here is an example of an index on the Users table by the login field:
public interface SimpleUserRepository extends CrudRepository<User, Long> {
    @ViewIndex(indexName = "login_index")
    User findByLogin(String login);
}
        
    The query generated by this method will look as follows:
SELECT
    `Users`.`id` AS `id`,
    `Users`.`login` AS `login`,
    `Users`.`lastname` AS `lastname`,
    `Users`.`firstname` AS `firstname`
FROM `Users` VIEW login_index AS `Users` WHERE `Users`.`login` = ?
        
    YdbType
The @YdbType annotation allows you to declare a specific YDB data type for an entity field. Here is an example of its usage:
    @YdbType("Json")
    private String jsonColumn;
    @YdbType("JsonDocument")
    private String jsonDocumentColumn;
    @YdbType("Uint8")
    private byte uint8Column;
    @YdbType("Uint16")
    private short uint16Column;
    @YdbType("Uint32")
    private int uint32Column;
    @YdbType("Uint64")
    private long uint64Column;
        
    Using the @YdbType annotation allows you to accurately specify the data types supported by YDB, ensuring proper interaction with the database.
A complete example of a simple Spring Data JDBC repository is available on GitHub.