29

有没有人尝试过将 JOOQ 与 Spring 框架一起使用,或者我是否正在开辟新天地?

http://www.jooq.org

4

8 回答 8

24

是的,很多人(现在)都有。jOOQ 手册包括一个关于如何开始使用jOOQ、Spring、Spring-TX 和BoneCP的教程:

Petri Kainulainen 也有一个非常好的教程,解释了设置项目的每一步,这里:

这是一篇关于如何在 Spring Boot 中使用 jOOQ 的博客文章,当您需要 jOOQ 的商业发行版时特别有用:

于 2010-12-19T10:00:35.913 回答
17

我希望使用 jOOQ 作为构建器库来提供对 Spring 的 JdbcTemplate 和相关类的查询。不幸的是,jOOQ 似乎将两个概念结合到同一组类中:SQL 生成和查询执行。就我而言,我想要前者,但想让 Spring 处理后者。不过,它确实有效。例如,您可以执行以下操作(使用 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);
于 2011-07-22T22:19:28.283 回答
9

使用 jOOQ 运行 spring 事务要简单得多(除非我忘记了什么):

只需将您的数据源包装到

org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy

可选:延迟打开 jdbc 连接,直到第一个实际的 sql 语句发生使用

org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy

所以作为一个示例,这样做是为了创建一个应用了“事务”和“懒惰”的 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!
于 2013-01-09T17:37:20.843 回答
7

为了使 jOOQ 与 spring 一起工作,您需要做/知道的所有事情:

  1. java.sql.Connection通过事务管理器获取到线程的绑定。
  2. 通过异常翻译正确处理事务
  3. 了解 jOOQ Factory对象(尽管有名称)不是线程安全的。因此每次使用都需要实例化一个新对象(不要这样做其他答案)。

因此,对于第一种和第二种情况,我提供了这个要点:https ://gist.github.com/3669307符合Lukas 的建议

对于第三种情况,您可以基本上创建一个工厂的工厂(其中包含),或者使用spring 组件中的连线在每个方法中DataSource实例化一个新对象。FactoryDataSource

@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 的配置支持来避免编程创建。

我不会介绍您如何DataSource在 Spring 中设置 a,因为它在无数其他/更好的地方都有介绍。

于 2012-09-08T00:08:30.560 回答
3

假设你正在使用 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
}

您可能希望通过 Spring 的依赖注入获取 DataSource,因为您的 Web 容器 Tomcat 或其他任何东西都在提供 DataSource 并进行连接池。在你的一个弹簧配置文件中,你会有类似的东西

<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/>

上述代码所在的对象(或为该代码提供数据源的某个对象)可以在 spring 文件中配置以使用数据源实例化它,例如

<bean id="fooService" class="com.fubar.FooServiceImpl">
  <constructor-arg ref="dataSource" type="javax.sql.DataSource" />
</bean>

字符串“jdbc/datasource”的部分将对应于 Web 容器中配置的资源名称。这会有所不同,但对于 Tomcat,它可能是 Tomcat 主页下 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>
于 2012-04-04T21:39:41.323 回答
3

希望这对某人有帮助....

Spring 应用程序上下文配置。

 <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 类以获得更详细的配置)。现在,publicFactory。注意:不需要修改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);
                }

完毕!

于 2012-04-06T06:42:46.990 回答
3

对于 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());
}
于 2015-07-06T16:37:46.933 回答
0

最简单的方法,(我发现)将 Spring Transactions 与 jOOQ 一起使用,在这里给出:http: //blog.liftoffllc.in/2014/06/jooq-and-transactions.html

看看这个答案以获得更好的解释:https ://stackoverflow.com/a/24380508/542108

于 2014-06-24T07:31:48.727 回答