Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JOOQ和Spring_Java_Sql_Spring_Jooq - Fatal编程技术网

Java JOOQ和Spring

Java JOOQ和Spring,java,sql,spring,jooq,Java,Sql,Spring,Jooq,有没有人尝试过将JOOQ与Spring框架结合使用,或者我正在开拓新的领域 是的,很多人(现在)都有。jOOQ手册包括一个关于如何开始使用Spring、Spring TX和: Petri Kainulainen还提供了一个非常好的教程,解释了建立项目的每个步骤,如下所示: 下面是一篇关于如何将jOOQ与Spring Boot结合使用的博文,在您需要jOOQ的商业发行版时特别有用: 我希望使用jOOQ作为构建器库,为Spring的JdbcTemplate和相关类提供查询。不幸

有没有人尝试过将JOOQ与Spring框架结合使用,或者我正在开拓新的领域

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

Petri Kainulainen还提供了一个非常好的教程,解释了建立项目的每个步骤,如下所示:

下面是一篇关于如何将jOOQ与Spring Boot结合使用的博文,在您需要jOOQ的商业发行版时特别有用:


我希望使用jOOQ作为构建器库,为Spring的JdbcTemplate和相关类提供查询。不幸的是,jOOQ似乎将两个概念组合到同一组类中:SQL生成和查询执行。在我的例子中,我想要前者,但希望让Spring处理后者。不过,它确实有效。例如,您可以这样做(使用jOOQ 2.x API):


假设您正在使用Spring构建一个Web应用程序,您可能希望执行以下操作:

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的依赖项注入来获取数据源,因为您的web容器Tomcat或whathaveyou正在提供数据源并进行连接池。在您的一个spring配置文件中,您会有如下内容

<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 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>

希望这对某人有所帮助

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>
最后,只需给工厂打电话

 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);
                }
PublicFactory vs=(PublicFactory)SpringLoader.getBean(“PublicFactory”);
SimpleSelectQuery sq=vs.selectQuery(dbLayer.db.tables.Version.Version);
VersionRecord v=null;
试一试{
v=sq.fetchAny();
}捕获(例外e){
log.warn(“似乎版本表不存在!”,e);
}

完成了

让jOOQ与spring一起工作所需做/知道的一切:

  • 获取事务管理器绑定到线程的
    java.sql.Connection
  • 通过异常转换正确处理事务
  • 请理解jOOQ工厂对象(尽管名称不同)不是线程安全的。因此,每次使用都需要实例化一个新对象(不要这样做)
  • 因此,对于第一个和第二个案例,我提供了这个要点:哪个做什么

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

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


    我将不介绍如何在Spring中设置
    数据源,因为有无数其他/更好的地方介绍了这一点。

    使用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!
    
    下面给出了(我发现)将Spring事务用于jOOQ的最简单方法:

    请看这个答案以获得更好的解释:

    对于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本身是全新的,您可能会有新的突破。您希望如何连接这两个库?您是否计划使用spring作为配置jOOQ的手段?我对你的用例很好奇Hi Lukas,我脑子里没有特定的用例。我问这个问题是想看看其他人是否一起使用过这两个图书馆,是否有值得分享的经验。我可以看到,我可以使用Spring配置的数据源来提供到jOOQ工厂的连接。除此之外,我不确定深度集成是否有什么好处,但我是Spring的新手,所以我喜欢通过示例学习。这是一个很好的集成示例。为什么选择spring来执行查询?因为jOOQ缺少行映射功能?还是缺少交易处理?@LukasEder为我介绍了它的交易处理。我广泛使用AspectJ+Spring(很抱歉被跟踪……碰巧遇到另一个问题。由您回答)。@AdamGent:Spring的事务处理可以与jOOQ的查询执行一起使用。这已在jOOQ用户组上得到验证。手册中应该有关于这一点的章节,尽管…@卢卡塞德在理论上似乎很有可能。您可以在工厂中使用try…catch异常装饰器,并将其转换为Spring异常(用于事务管理)。你能为这篇文章添加一个链接吗?因为它对OP来说似乎很有用。@AdamGent:或者只是把一个链接挂到jOOQ上,它负责将jOOQ的
    DataAccessException
    转换成你需要的任何Spring异常。。。这需要大约5-10行代码。看到了!!!!!这是一个非常糟糕的主意。Spring通常假定它创建的bean是单例的,因此是线程安全的。PublicFactory不是线程安全的!你需要正确地标记你的,这样才能工作,即使你这样做了,我也不推荐。一个小的github回购和工作演示将是一个很大的帮助!既然JdbcTemplate可以在更少的线路中为您处理连接,那么您为什么还要自己处理连接呢
    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!
    
    /* 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());
    }