Guice,JDBC和管理数据库连接

Guice,JDBC和管理数据库连接,第1张

Guice,JDBC和管理数据库连接

如果您的数据库很少更改,则可以使用数据库JDBC驱动程序随附的数据源,并在提供程序中隔离对第3方库的调用(我的示例使用H2
dataabse提供的方法,但是所有JDBC提供程序都应具有一个)。如果更改为DataSource的其他实现(例如c3PO,Apache
DBCP或由应用服务器容器提供的实现),则只需编写新的Provider实现即可从适当的位置获取数据源。在这里,我使用单例作用域来允许DataSource实例在依赖它的那些类之间共享(池化所必需)。

public class DataSourceModule extends AbstractModule {    @Override    protected void configure() {        Names.bindProperties(binder(), loadProperties());        bind(DataSource.class).toProvider(H2DataSourceProvider.class).in(Scopes.SINGLETON);        bind(MyService.class);    }    static class H2DataSourceProvider implements Provider<DataSource> {        private final String url;        private final String username;        private final String password;        public H2DataSourceProvider(@Named("url") final String url,   @Named("username") final String username,   @Named("password") final String password) { this.url = url; this.username = username; this.password = password;        }        @Override        public DataSource get() { final JdbcDataSource dataSource = new JdbcDataSource(); dataSource.setURL(url); dataSource.setUser(username); dataSource.setPassword(password); return dataSource;        }    }    static class MyService {        private final DataSource dataSource;        @Inject        public MyService(final DataSource dataSource) { this.dataSource = dataSource;        }        public void singleUnitOfWork() { Connection cn = null; try {     cn = dataSource.getConnection();     // Use the connection } finally {     try {         cn.close();     } catch (Exception e) {} }        }    }    private Properties loadProperties() {        // Load properties from appropriate place...        // should contain definitions for:        // url=...        // username=...        // password=...        return new Properties();    }}

要处理事务,应使用“事务感知”数据源。我不建议手动执行此 *** 作。使用诸如warp-persist或容器提供的事务管理之类的东西,看起来像这样:

public class TxModule extends AbstractModule {    @Override    protected void configure() {        Names.bindProperties(binder(), loadProperties());        final TransactionManager tm = getTransactionManager();        bind(DataSource.class).annotatedWith(Real.class).toProvider(H2DataSourceProvider.class).in(Scopes.SINGLETON);        bind(DataSource.class).annotatedWith(TxAware.class).to(TxAwareDataSource.class).in(Scopes.SINGLETON);        bind(TransactionManager.class).toInstance(tm);        bindInterceptor(Matchers.any(), Matchers.annotatedWith(Transactional.class), new TxMethodInterceptor(tm));        bind(MyService.class);    }    private TransactionManager getTransactionManager() {        // Get the transaction manager        return null;    }    static class TxMethodInterceptor implements MethodInterceptor {        private final TransactionManager tm;        public TxMethodInterceptor(final TransactionManager tm) { this.tm = tm;        }        @Override        public Object invoke(final MethodInvocation invocation) throws Throwable { // Start tx if necessary return invocation.proceed(); // Commit tx if started here.        }    }    static class TxAwareDataSource implements DataSource {        static ThreadLocal<Connection> txConnection = new ThreadLocal<Connection>();        private final DataSource ds;        private final TransactionManager tm;        @Inject        public TxAwareDataSource(@Real final DataSource ds, final TransactionManager tm) { this.ds = ds; this.tm = tm;        }        public Connection getConnection() throws SQLException { try {     final Transaction transaction = tm.getTransaction();     if (transaction != null && transaction.getStatus() == Status.STATUS_ACTIVE) {         Connection cn = txConnection.get();         if (cn == null) {  cn = new TxAwareConnection(ds.getConnection());  txConnection.set(cn);         }         return cn;     } else {         return ds.getConnection();     } } catch (final SystemException e) {     throw new SQLException(e); }        }        // Omitted delegate methods.    }    static class TxAwareConnection implements Connection {        private final Connection cn;        public TxAwareConnection(final Connection cn) { this.cn = cn;        }        public void close() throws SQLException { try {     cn.close(); } finally {     TxAwareDataSource.txConnection.set(null); }        }        // Omitted delegate methods.    }    static class MyService {        private final DataSource dataSource;        @Inject        public MyService(@TxAware final DataSource dataSource) { this.dataSource = dataSource;        }        @Transactional        public void singleUnitOfWork() { Connection cn = null; try {     cn = dataSource.getConnection();     // Use the connection } catch (final SQLException e) {     throw new RuntimeException(e); } finally {     try {         cn.close();     } catch (final Exception e) {} }        }    }}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5132189.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-17
下一篇 2022-11-17

发表评论

登录后才能评论

评论列表(0条)

保存