Trying to investigate an alternative to jpa, I came up to spring jdbc:
For my entity:
@Data
@NoArgsConstructor
public class PostDto {
private Long id;
private String title;
public PostDto(String title) {
this.title = title;
}
}
I have defined a custom repository:
@Repository
public interface JdbcRepository<T, ID> {
Optional<T> findById(ID id);
List<T> findALl();
T save(T t);
boolean update(T t);
boolean delete(ID id);
}
With the implementation:
public class PostDtoRepository implements JdbcRepository<PostDto, Long> {
@Autowired
private JdbcClient jdbcClient;
@Override
public Optional<PostDto> findById(Long id) {
return jdbcClient.sql("select * from post where id=:id")
.param("id", id)
.query(PostDto.class)
.optional();
}
@Override
public List<PostDto> findALl() {
return jdbcClient.sql("select * from post")
.query(PostDto.class)
.list();
}
@Override
public PostDto save(PostDto postDto) {
KeyHolder keyHolder = new GeneratedKeyHolder();
int affectedRows = jdbcClient.sql("insert into post(title) values(:title)")
.paramSource(new BeanPropertySqlParameterSource(postDto))
.update(keyHolder);
if (affectedRows > 0) {
postDto.setId(keyHolder.getKey().longValue());
return postDto;
}
throw new RuntimeException("Saving post failed");
}
@Override
public boolean update(PostDto postDto) {
return jdbcClient.sql("update post set title=:title where id=:id")
.paramSource(postDto)
.update() > 0;
}
@Override
public boolean delete(Long id) {
return jdbcClient.sql("delete from post where id=:id")
.param("id", id)
.update() > 0;
}
}
I quite actually like the simplicity and complete control of the jdbc but it has 2 drawbacks:
- code repetition. e.g. essentially every insert is going to look the same expect for the sql query and the mapping of the entity. I am thinking here to create a wrapper of the jdbcclient and address this issue with common methods which will receive the sql query and the pojo mapping class. Thoughts?
- if every developer will create it’s own repository with its own method names it will be havoc. I am think of maybe implementing the CrudRepository in order to have a standard interface base. Although, the drawback may be that I don’t need all the methods. Thoughts?
Or, if I am totally wrong of how I use spring jdbc, tell me about it.