我想将 jdbi3 集成到 spring-boot 中。 但是很难在互联网上找到所有必需的部分来获得全貌。
有没有机会在 github 上提供一个 jdbi-examples-repository,它只是展示了如何使用 jdbi3 设置一个 spring-boot 应用程序?
我会非常感激。 非常感谢。
/塞伯
在一个简单的情况下,如果您不需要与 Spring 的事务工具集成,您只需在 Spring 配置中初始化Jdbi
和您的 DAO:
<strong i="7">@Bean</strong>
public DataSource dataSource() {
// From Spring Boot's connection pool configuration;
}
<strong i="8">@Bean</strong>
public Jdbi createJdbi(DataSource dataSource) {
return Jdbi.create(dataSource);
}
<strong i="9">@Bean</strong>
public UserDao userDao(Jdbi jdbi) {
return jdbi.onDemand(UserDao.class);
}
嗨@ bastman , @alwins0n在#989 中贡献了更好的 Spring 支持 - 您想回顾他迄今为止的工作并评论它是否使您的 Spring 集成更清晰,或者您是否要求稍微不同的东西?
将 jdbi 集成到 spring boot 是微不足道的,你只需要在你的@Configuration
类中设置一个@Bean
注释的方法来返回一个 Jdbi 实例 - 如@arteam所示
更难的事情,就像我在 spring PR 中所做的那样,是将 jdbi 集成到 spring 事务管理中。 如果它是您正在寻找的,您应该绝对检查它。
此外,如果这获得批准,我正在考虑为 spring boot (2) 创建一个自动配置/spring-boot-starter。 如果这就是你要找的。 (如果你想尝试一下,它实际上是一个很好的练习:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html)
我一直在 jdbi2.x 中使用以下方法,没有任何问题。 已经用 jdbi3.x 对其进行了测试,但没有发现任何问题。 这看起来是一种在使用 jdbi 时让 spring 管理事务的更简单的方法。
基本上,您使用 TransactionAwareDataSourceProxy 包装代理并使用它来创建 Jdbi 实例。 (我从@artteam的回答中得到了 c/p'd,以便示例保持一致)
<strong i="8">@Bean</strong>
public DataSource dataSource() {
// From Spring Boot's connection pool configuration;
}
<strong i="9">@Bean</strong>
public TransactionAwareDataSourceProxy txDataSource(DataSource dataSource) {
return new TransactionAwareDataSourceProxy(dataSource);
}
<strong i="10">@Bean</strong>
public PlatformTransactionManager transactionManager(DataSource dataSource) {
//not sure if this is needed
return new DataSourceTransactionManager(dataSource);
}
<strong i="11">@Bean</strong>
public Jdbi createJdbi(TransactionAwareDataSourceProxy dataSource) {
//note that parameter is TransactionAwareDataSourceProxy instead of plain DataSource
return Jdbi.create(dataSource);
}
<strong i="12">@Bean</strong>
public UserDao userDao(Jdbi jdbi) {
return jdbi.onDemand(UserDao.class);
}
看起来不错,我不知道这个类存在。
你能看看前面提到的公关吗? 已经有人提出了关于 jdbi 底层的“事务感知”连接工厂的建议。
iirc 问题仍然是连接和句柄不是同步状态。 所以这个 ds 返回一个在事务结束时关闭的连接(绑定到事务)。 而使用的句柄没有关闭,并在尝试(重新)使用它时抛出异常。
但也许这不是什么大问题,而是极端情况,您的解决方案适用于 99% 的用例。
简而言之:使用您的方法,事务管理资源是连接。 在我的 PR 中,托管资源是句柄。
将 jdbi3 与 stringtemplate4 和组导入一起使用存在相关问题。 查看我的问题https://github.com/jdbi/jdbi/issues/1052
此问题还包括一个链接,指向在 spring boot 2.0.0 中使用 jdbi3 的完全工作的 repo 框架
当我使用 Spring 的@Transactional注释实现@kaandok的解决方案时,由于存在打开的事务时关闭句柄,我得到以下异常。 是否有任何推荐/适用的解决方案?
“检测到不正确的事务处理:具有打开事务的句柄已关闭。在关闭句柄之前,必须明确提交或回滚事务。Jdbi 已自动回滚此事务。”
@cengha你能提供一些代码来证明你的问题吗?
下面是配置类:
<strong i="6">@Bean</strong>
public HikariDataSource hikariDataSource() {
HikariConfig dataSourceConfig = new HikariConfig();
dataSourceConfig.setDriverClassName(driverClassName);
dataSourceConfig.setJdbcUrl(jdbcUrl);
dataSourceConfig.setUsername(username);
dataSourceConfig.setPassword(password);
dataSourceConfig.setAutoCommit(true);
return new HikariDataSource(dataSourceConfig);
}
<strong i="7">@Bean</strong>
public TransactionAwareDataSourceProxy transactionAwareDataSourceProxy(HikariDataSource dataSource) {
return new TransactionAwareDataSourceProxy(dataSource);
}
<strong i="8">@Bean</strong>
public PlatformTransactionManager platformTransactionManager(HikariDataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
<strong i="9">@Bean</strong>
public Jdbi jdbi(TransactionAwareDataSourceProxy transactionAwareDataSourceProxy) {
Jdbi jdbi = Jdbi.create(transactionAwareDataSourceProxy);
jdbi.installPlugin(new SqlObjectPlugin());
return jdbi;
}
这里是服务层
<strong i="13">@Override</strong>
<strong i="14">@Transactional</strong>
public Long createX(X x) {
Long aLong = XDao.insertX(x);
if(true) throw new RuntimeException();
return aLong;
}
当自动提交设置为 false 时,我提到了事务错误,但如果它设置为 true,则没有任何事务错误,但这次回滚不起作用(在运行时异常之后),因此 X 对象被持久化到数据库。 我使用 spring 2.0.3, JDBI 3.0.0-beta2 。
问题解决了。 我使用的是旧版本的 JDBI,在注意到这个线程更新了库并且一切都解决了之后。
最有用的评论
我一直在 jdbi2.x 中使用以下方法,没有任何问题。 已经用 jdbi3.x 对其进行了测试,但没有发现任何问题。 这看起来是一种在使用 jdbi 时让 spring 管理事务的更简单的方法。
基本上,您使用 TransactionAwareDataSourceProxy 包装代理并使用它来创建 Jdbi 实例。 (我从@artteam的回答中得到了 c/p'd,以便示例保持一致)