JOOQ et Spring

est-ce que quelqu'un a essayé D'utiliser le JOOQ avec le cadre à ressorts ou est-ce que je innove?

http://www.jooq.org

22
demandé sur Lukas Eder 2010-12-17 23:06:32

8 réponses

Oui, beaucoup de gens ont (pour l'instant). Et le manuel jOOQ comprend un tutoriel sur la façon de commencer à utiliser jOOQ , Spring, Spring-TX et BoneCP :

il y a aussi un très bon tutoriel de Petri Kainulainen, expliquant chaque étape pour mettre en place un projet, ici:

19
répondu Lukas Eder 2015-04-15 09:48:04

je cherchais à utiliser jOOQ comme une bibliothèque de constructeur pour fournir des requêtes à Jdbctemplate de Spring et les classes connexes. Malheureusement, jOOQ semble combiner deux concepts dans le même ensemble de classes: la génération SQL et l'exécution de requête. Dans mon cas, je veux le premier mais je veux laisser le printemps gérer le second. Il fonctionne, cependant. Par exemple, vous pouvez faire quelque chose comme ceci (en utilisant 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);
15
répondu David 2015-04-18 08:51:41

Tout ce que vous devez faire / savoir pour faire fonctionner jOOQ avec le ressort:

  1. Get java.sql.Connection lié à la thread par le gestionnaire de transactions.
  2. Gérer les transactions correctement à travers l'exception de la traduction
  3. comprendre que le jOOQ usine objets (malgré le nom) ne sont pas threadsafe. et il faudra donc instancier un nouvel objet par utilisation (NE PAS faire cet autre réponse ).

donc pour le premier et le deuxième cas, j'offre ce gist: https://gist.github.com/3669307 qui fait ce que Lukas recommande .

pour le troisième cas, vous pouvez créer essentiellement une usine d'une usine (qui contient le DataSource ) ou instancier tout simplement un nouvel objet Factory dans chaque méthode en utilisant le filaire DataSource dans votre composant de ressort.

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

quant à l'écouteur des paramètres, vous pouvez prendre en charge la configuration de JOOQ pour éviter la création programmée.

Je ne vais pas couvrir comment vous mettez en place un DataSource au printemps car il est couvert dans une myriade d'autres/meilleurs endroits.

7
répondu Adam Gent 2017-05-23 10:29:47

obtenir des transactions de ressort avec jOOQ est beaucoup plus simple (sauf si j'ai oublié quelque chose):

enveloppez simplement votre source de données dans

org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy

optionnel : pour retarder l'ouverture d'une connexion jdbc jusqu'à ce que la première déclaration sql se produise, utiliser

org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy

ainsi comme un échantillon font ceci pour créer une usine de jOOQ avec' transactions 'et' lazyness ' appliqué

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!
7
répondu Peter Ertl 2013-01-09 17:37:20

espérons que cela sera utile pour quelqu'un....

Printemps de contexte de l'application de configuration.

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

il remplira automatiquement l'usine publique avec la connexion donnée (et oui, il peut s'agir d'une connexion groupée, avec fermeture automatique etc., voir la classe DriverManagerDataSource pour une configuration plus détaillée). Et maintenant, le publicFactory. Note: pas besoin de modifier l'usine publique originale générée par 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);
    }
}

À la fin, il suffit d'appeler l'usine.

 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);
                }

fait!

3
répondu Agharta 2012-06-23 00:29:14

en supposant que vous utilisez le ressort pour construire une webapp, vous voulez probablement faire quelque chose comme ceci:

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
}

vous voulez probablement obtenir une source de données via L'injection de dépendances de Spring, parce que votre conteneur web, Tomcat ou whathaveyou, fournit la source de données et fait du pooling de connexion. Dans l'un de vos fichiers de configuration de printemps vous auriez quelque chose comme

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

L'objet que le code ci-dessus (ou sur certains objet qui fournit CE code avec la source de données) pourrait avoir une configuration dans un fichier ressort pour l'instancier avec la source de données, comme

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

la partie de la chaîne de caractères" jdbc/datasource " correspondrait à un nom de ressource configuré dans le conteneur web. Cela varie, mais pour Tomcat il peut s'agir d'un fichier de contexte dans conf/Catalina/localhost sous Tomcat home, par exemple,

<?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>
3
répondu EricS 2013-09-18 11:52:00

la façon la plus facile, (j'ai trouvé) d'utiliser des Transactions de ressort avec jOOQ, est donnée ici: http://blog.liftoffllc.in/2014/06/jooq-and-transactions.html

regardez cette réponse pour une meilleure explication: https://stackoverflow.com/a/24380508/542108

1
répondu CodePredator 2017-05-23 12:02:53

pour la configuration Java (qui est par défaut pour le démarrage à ressort), vous pouvez utiliser le code suivant:

/* 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());
}
1
répondu Przemek Nowak 2015-07-06 16:37:46