Cuando hablamos de acceso a bases de datos en Java, solemos pensar en JDBC puro o en frameworks pesados como Hibernate.
Pero existe una opción intermedia muy interesante: Jdbi.
JDBI busca mantener la simplicidad y el control de SQL, pero eliminando gran parte del código repetitivo de JDBC.
¿Qué es JDBI?
JDBI es una librería que se construye sobre JDBC y agrega:
- Mapeo automático de objetos
- Queries más limpias
- Manejo simplificado de parámetros
- Integración con transacciones
- APIs modernas y funcionales
La idea es poder escribir SQL real sin tener que pelear con ResultSet, PreparedStatement y toneladas de try/catch.
Dependencia Maven:
<dependency>
<groupId>org.jdbi</groupId>
<artifactId>jdbi3-core</artifactId>
<version>3.49.6</version>
</dependency>
Si usamos una base de datos específica, agregamos el driver correspondiente.
Por ejemplo para MySQL:
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
Crear una conexión:
Jdbi jdbi = Jdbi.create(
"jdbc:mysql://localhost:3306/test",
"root",
"password"
);
Ejecutar una consulta
Supongamos esta tabla:
CREATE TABLE users (
id BIGINT PRIMARY KEY,
name VARCHAR(100),
age INT
);
Y esta clase:
public class User {
private Long id;
private String name;
private Integer age;
// getters y setters
}
Ahora podemos consultar así:
List<User> users = jdbi.withHandle(handle ->
handle.createQuery("SELECT * FROM users")
.mapToBean(User.class)
.list()
);
Fijate que desaparece todo el manejo manual de ResultSet.
Insertar datos:
jdbi.useHandle(handle ->
handle.createUpdate("""
INSERT INTO users(id, name, age)
VALUES(:id, :name, :age)
""")
.bind("id", 1L)
.bind("name", "Emanuel")
.bind("age", 30)
.execute()
);
Parámetros nombrados
Una de las mejores cosas de JDBI es evitar los clásicos:
statement.setString(1, ...);
statement.setInt(2, ...);
En su lugar:
.bind("name", "Juan")
Mucho más legible.
JDBI también permite definir interfaces tipo DAO.
public interface UserDao {
@SqlQuery("SELECT * FROM users WHERE id = :id")
User findById(@Bind("id") Long id);
@SqlUpdate("""
INSERT INTO users(id, name, age)
VALUES(:id, :name, :age)
""")
void insert(
@Bind("id") Long id,
@Bind("name") String name,
@Bind("age") Integer age
);
}
Y luego:
UserDao dao = jdbi.onDemand(UserDao.class);
User user = dao.findById(1L);
¿Por qué mucha gente lo elige?
Porque queda en un punto muy cómodo. No es tan automático como JPA y permite hacer optimizaciones fácilmente, pero no es tan trabajoso como JDBC.
JDBI se integra muy bien con Spring Framework.
Dependencia:
<dependency>
<groupId>org.jdbi</groupId>
<artifactId>jdbi3-spring5</artifactId>
<version>3.49.6</version>
</dependency>
Configuración:
@Configuration
public class JdbiConfig {
@Bean
public Jdbi jdbi(DataSource dataSource) {
Jdbi jdbi = Jdbi.create(dataSource);
jdbi.installPlugin(new SqlObjectPlugin());
return jdbi;
}
}
Crear el DAO como Bean
@Configuration
public class DaoConfig {
@Bean
public UserDao userDao(Jdbi jdbi) {
return jdbi.onDemand(UserDao.class);
}
}
Usarlo desde un Service
@Service
public class UserService {
private final UserDao userDao;
public UserService(UserDao userDao) {
this.userDao = userDao;
}
public User getUser(Long id) {
return userDao.findById(id);
}
}
¿Cuándo conviene usar JDBI?
JDBI suele ser una muy buena opción cuando:
- querés escribir SQL manualmente
- necesitás buena performance
- no querés la complejidad de Hibernate
- trabajás con consultas complejas
- querés algo más moderno que JDBC puro
Especialmente en microservicios o aplicaciones donde el modelo relacional es importante, JDBI puede resultar mucho más simple y transparente que un ORM completo.
Dejo link: https://jdbi.org













