jdbi和jdbc_数据库中间件-jdbi

Java 的数据库原生使用 jdbc,中间件有很多,例如说 hibernate、mybatis、jdbi,这几种是最常用的中间件。

怎么选择

一般情况下,如果始终只会使用到一种数据库,jdbc 就是最好的选择了,使用这种方式,就是直接使用最底层的东西,定位问题等都非常方便。

数据库中间件就是节省开发人力,用很少的代码就可以快速开发。但是也会引入一些复杂度,特别是如果对中间件不熟悉或者中间件存在 bug,会导致更高复杂度。

如果使用数据库中间件,各种中间件都有各自的优劣势,对于相关的东西需要了解清楚,否则会导致不恰当的选择。

jdbi

jdbi 是我比较喜欢的一个数据库中间件,它是非 ORM 的,特别适合于数据库固定不变的场景,即不会对应多种数据库,以后也不会更换数据库的场景。如果不是这种场景,那么使用 jdbc 或者最好选择 hibernate 等对多种数据库兼容较好的中间件。

基于上述使用场景,jdbi 的优点有:

和 jdbci 比较接近,使用和掌握非常简单。

与时俱进,例如说现在最新的 jdbi3,增加了流式编程函数式等编程风格。

源代码的实现思路非常清晰,有一种美感。使用 jdbi 封装出的数据库代码也非常清晰。

jdbi 的两种风格

Fluent Api

handle.createUpdate ("INSERT INTO user (id, name) VALUES (:id, :name)")

.bind ("id", 2)

.bind ("name", "Clarice")

.execute ();

这里就是 java8 的流式风格,用连贯式表达式将一个 sql 实现串在一起

Declarative Api

// Define your own declarative interface

public interface UserDao {

@SqlUpdate ("CREATE TABLE user (id INTEGER PRIMARY KEY, name VARCHAR)")

void createTable ();

@SqlUpdate ("INSERT INTO user (id, name) VALUES (?, ?)")

void insertPositional (int id, String name);

@SqlUpdate ("INSERT INTO user (id, name) VALUES (:id, :name)")

void insertNamed (@Bind ("id") int id, @Bind ("name") String name);

@SqlUpdate ("INSERT INTO user (id, name) VALUES (:id, :name)")

void insertBean (@BindBean User user);

@SqlQuery ("SELECT * FROM user ORDER BY name")

@RegisterBeanMapper (User.class)

List listUsers ();

}

声明式的主要是使用注解来实现,在实际的面向对象风格的代码中,我个人觉得声明式的比较简洁,容易阅读和维护。所以下面都按照 Declarative Api 的方式。

一些关键性的问题

返回自动递增的主键

jdbc 方式怎么做的呢?

try {

Connection conn = DBUtil2.getConnection ();

//PreparedStatement ps =

// conn.prepareStatement (SAVE_SQL, new String [] { "id" });

// 应该返回生成的主键,上下两种方式都可

PreparedStatement ps = conn.prepareStatement (SAVE_SQL,PreparedStatement.RETURN_GENERATED_KEYS);

ps.setString (1, user.getName ());

ps.setFloat (2, user.getSalary ());

ps.setInt (3, user.getAge ());

if (ps.executeUpdate () > 0) {

// 获取主键

ResultSet rs = ps.getGeneratedKeys ();

rs.next ();

int i = rs.getInt (1);

user.setId (i);

ps.close ();

return true;

}

ps.close ();

} catch (SQLException e) {

e.printStackTrace ();

} finally {

DBUtil2.closeConnection ();

}

jdbi 提供的机制:

public interface UserDao {

@SqlBatch ("INSERT INTO users (name) VALUES (?)")

@GetGeneratedKeys

List createUsers (String... names);

}

非常直观简洁

查询

jdbc 方式,我们在查询大数据量时,一般使用数据库游标,逐条查询。

jdbi 的查询是什么样的呢?如下:

public interface UserDao {

@SqlQuery ("select name from users")

List listNames ();

}

但是这个时候,如果遇到大数据量怎么办,jdbi 提供的解决方案:

public interface UserDao {

@SqlQuery ("select name from users")

ResultIterator getNamesAsIterator ();

}

这里使用了迭代器,依次去查询,和 jdbi 游标的作用是一样的。

批量插入

jdbi 的插入,当一个列表插入,如果要提升效率,就是拆分插入,拆分插入 jdbi 提供了机制 SqlBatch

public interface UserDao {

@SqlBatch ("insert into users (tenant_id, id, name)" + "values (:tenantId, :user.id, :user.name)")

void bulkInsert (@Bind ("tenantId") long tenantId,

@BindBean ("user") User... users);

}

小结

jdbi 是非常简洁优美的数据库中间件组件,当在数据库唯一特别是 pg 数据库,个人认为是首选方式,有效的把 jdbc 封装了一下,更加适合于开发。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值