質問
Spring FrameworkでJooqを使用しようとした人もいますか、それとも私は新境地を開いていますか?
他のヒント
SpringのJDBCtemplateおよび関連クラスにクエリを提供するために、Jooqをビルダーライブラリとして使用したいと考えていました。残念ながら、JOOQは2つの概念を同じクラスのセットに組み合わせているように見えます:SQL生成とクエリの実行。私の場合、私は前者が欲しいのですが、後者を春に処理させたいと思っています。ただし、機能します。たとえば、このようなことを行うことができます(JOOQ 2.x APIを使用):
Factory create = new Factory(null, SQLDialect.ORACLE);
getJdbcTemplate().query(
create.select(create.field(ID_COL),
create.field(VALUE_COL))
.from(FOO_TABLE)
.where(create.field(ID_COL).equals("ignored"))
.getSQL(),
myRowMapper,
id);
Jooqを春で機能させるためにあなたがする必要がある/知っている必要があります:
- 取得します
java.sql.Connection
トランザクションマネージャーによってスレッドにバインドされています。 - 例外翻訳を通じてトランザクションを適切に処理します
- jooqを理解してください 工場 オブジェクト(名前にもかかわらず)はスレッドセーフではありません。したがって、使用ごとに新しいオブジェクトをインスタンス化する必要があります(これを他のオブジェクトにしないでください 答え).
したがって、第1および2番目のケースでは、この要点を提供します。 https://gist.github.com/3669307 どちらが何をしますか ルーカスがお勧めします.
3番目のケースでは、基本的に工場の工場を作成できます( DataSource
)または新しいものをインスタンス化するだけです Factory
有線を使用して各メソッドのオブジェクト DataSource
春のコンポーネントで。
@Service
public class MyDaoOrService {
@Autowired
private void DataSource dataSource;
@Transactional
public void doSomeJooq(){
Settings s = new Settings();
//You could instead put this jooq configuration xml
s.getExecuteListeners().add("com.snaphop.jooq.SpringExceptionTranslationExecuteListener");
MyGeneratedFactory f = new MyGeneratedFactory(dataSource, s);
f.select(); //etc
}
}
設定リスナーについては、プログラムの作成を回避するために、JOOQの構成サポートをサポートできます。
私はあなたがどのようにセットアップするかをカバーしませんa DataSource
春には、他の/より良い場所の無数で覆われています。
JOOQでスプリングトランザクションを実行することは、はるかに簡単です(何かを忘れていない限り):
データソースをラップするだけです
org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
オプション: :最初の実際のSQLステートメントが発生するまでJDBC接続の開始を遅らせるには
org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy
したがって、サンプルとしてこれを行い、「トランザクション」と「怠zy性」が適用されたJOOQファクトリーを作成します
DataSource rawDS = /* your actual data source */
// (optional) make access lazy
final DataSource lazyDS = new LazyConnectionDataSourceProxy(rawDataSource);
// make spring transactions available in plain jdbc context
final DataSource txDS = new TransactionAwareDataSourceProxy(lazyDS);
// create jOOQ factory
Factory jooq = new Factory(txDS, /* dialect */, /* settings */)
// voila!
これが誰かに役立つことを願っています....
スプリングアプリケーションコンテキスト構成。
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName">
<value>SYSTEM_PROPERTIES_MODE_OVERRIDE</value>
</property>
<property name="searchSystemEnvironment">
<value type="boolean">true</value>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url"
value="jdbc:h2://${user.home}
${file.separator}tracciabilitaCanarini${file.separator}db${file.separator}basedb"/>
<property name="username" value="sa"/>
<property name="password" value="sa"/>
</bean>
<bean id="datasourceConnection"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
lazy-init="true" depends-on="dataSource">
<property name="targetObject">
<ref bean="dataSource"/>
</property>
<property name="targetMethod">
<value>getConnection</value>
</property>
</bean>
<bean id="publicFactory" class="dbLayer.db.PublicFactory" lazy-init="true"
depends-on="datasourceConnection" >
<constructor-arg index="0" ref="datasourceConnection" />
</bean>
特定の接続で公共工場を自動化します(そして、はい、それはプールされた接続であり、オートクローズなど、より詳細な構成についてはDriverManagerDataSourceクラスを参照してください)。そして今、パブリックファクトリー。注:JOOQによって生成された元の公共工場を変更する必要はありません。
/**
* This class is generated by jOOQ
*/
package dbLayer.db;
/**
* This class is generated by jOOQ.
*/
@javax.annotation.Generated(value = {"http://www.jooq.org", "2.0.5"},
comments = "This class is generated by jOOQ")
public class PublicFactory extends org.jooq.util.h2.H2Factory {
private static final long serialVersionUID = -1930298411;
/**
* Create a factory with a connection
*
* @param connection The connection to use with objects created from this factory
*/
public PublicFactory(java.sql.Connection connection) {
super(connection);
}
/**
* Create a factory with a connection and some settings
*
* @param connection The connection to use with objects created from this factory
* @param settings The settings to apply to objects created from this factory
*/
public PublicFactory(java.sql.Connection connection, org.jooq.conf.Settings settings) {
super(connection, settings);
}
}
最後に、工場に電話するだけです。
PublicFactory vs = (PublicFactory) SpringLoader.getBean("publicFactory");
SimpleSelectQuery<VersionRecord> sq = vs.selectQuery(dbLayer.db.tables.Version.VERSION);
VersionRecord v = null;
try {
v = sq.fetchAny();
} catch (Exception e) {
log.warn("Seems that version table does not exists!", e);
}
終わり!
Springを使用してWebAppを作成していると仮定すると、おそらく次のようなことをしたいと思うでしょう。
try {
Connection conn = dataSource.getConnection();
try {
// Do something with JOOQ
// No need to use a JdbcTemplate!
}
finally {
if (conn != null) {
conn.close();
}
}
} catch (SQLException e) {
// your error handling
}
Webコンテナ、Tomcat、またはWhathaveyouがDataSourceを提供し、接続プーリングを行っているため、Springの依存関係注入を介してデータソースを取得したいと思うでしょう。スプリング構成ファイルの1つでは、
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/>
上記のコードがあるオブジェクト(またはこのコードをDataSourceで提供するオブジェクト)は、Springファイルに構成を持つことができます。
<bean id="fooService" class="com.fubar.FooServiceImpl">
<constructor-arg ref="dataSource" type="javax.sql.DataSource" />
</bean>
文字列「JDBC/DataSource」の部分は、Webコンテナで構成されたリソース名に対応します。これは異なりますが、Tomcatの場合、Tomcat Homeの下にあるConf/Catalina/LocalHostのコンテキストファイルである可能性があります。たとえば
<?xml version="1.0" encoding="UTF-8"?>
<Context debug="10" reloadable="true" useNaming="true" antiJARLocking="true">
<Resource name="jdbc/datasource" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000" validationQuery="SELECT 1"
username="foo" password="fubar" driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost/foobase"/>
</Context>
Java構成(Spring Bootのデフォルト)の場合、次のコードを使用できます。
/* JOOQ Configuration */
@Bean
public DataSourceConnectionProvider dataSourceConnectionProvider() {
return new DataSourceConnectionProvider(dataSource());
}
@Bean
public DefaultConfiguration defaultConfiguration() {
DefaultConfiguration defaultConfiguration = new DefaultConfiguration();
defaultConfiguration.setConnectionProvider(dataSourceConnectionProvider());
defaultConfiguration.setSQLDialect(SQLDialect.POSTGRES);
return defaultConfiguration;
}
@Bean
public DSLContext dslContext() {
return new DefaultDSLContext(defaultConfiguration());
}
最も簡単な方法(私が見つけた)JOOQで春のトランザクションを使用することは、ここに与えられます。 http://blog.liftoffllc.in/2014/06/jooq-and-transactions.html
より良い説明のためにこの答えを見てください: https://stackoverflow.com/a/24380508/542108