31

I am converting Pure SQL to jOOQ now I have this

("SELECT Count(*) Count From Table "); 

I have to write this in jOOQ how can we write it?

selectQueryRecord.addSelect(Here Count Function );
selectQueryRecord.addFrom(Table);
Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
Subodh Joshi
  • 12,717
  • 29
  • 108
  • 202

5 Answers5

86

The most straight-forward way to implement what you're requesting is this, by using selectCount():

int count = 
DSL.using(configuration)
   .selectCount()
   .from(Table)
   .fetchOne(0, int.class);

Alternatively, you can explicitly express the count() function:

int count = 
DSL.using(configuration)
   .select(DSL.count())
   .from(Table)
   .fetchOne(0, int.class);

Or, you can use this, if you don't like mapping the value:

int count =
DSL.using(configuration)
   .fetchValue(selectCount().from(Table));

There's another alternative for fetching a count(*) of any arbitrary select expression, which helps you avoid specifying the result column index and type in the above fetchOne() method. This uses fetchCount():

int count =
DSL.using(configuration)
   .fetchCount(DSL.selectFrom(Table));

Beware, though, that this renders a nested select like this:

SELECT COUNT(*) FROM (SELECT a, b, ... FROM Table)
Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
  • Can i use same transaction variable which i am suing through out in my code – Subodh Joshi Oct 30 '13 at 08:56
  • What's the "transaction" variable? But maybe, you should ask a new question for that... – Lukas Eder Oct 30 '13 at 09:04
  • 'Transaction transfeeTransfer = Transaction.current();' – Subodh Joshi Oct 30 '13 at 09:39
  • 1
    I'm not sure how this relates. From your other question(s) I suspect that this is somehow related to a jOOQ `DSLContext` type. But please ask a new Stack Overflow question (and/or write to the [jOOQ User Group](https://groups.google.com/forum/#!forum/jooq-user)) for questions related to transaction handling – Lukas Eder Oct 30 '13 at 09:49
  • @LukasEder, why isn't a `long` used here? – Garret Wilson Oct 26 '14 at 20:52
  • @GarretWilson: It probably would've been a better choice, or even `BigInteger`. For historic reasons, a couple of these types are `int` or `Integer` to match pre-JDBC-4.2's usage of `int` for counts. In any case, in 98% of the cases, you won't need to count more than 2G records, so that might be a minor annoyance... – Lukas Eder Oct 26 '14 at 23:19
  • 1
    @LukasEder: Sitting here finishing a glass of wine, the API designer part of me responds: 1) It probably should have always been `long`, even if JDBC used an int (there is no need to "match" JDBC if a `long` is more appropriate and accommodates an int), and 2) I hope "we" can change it eventually, even though this does not affect me in any way right now---maybe someday it might! :) Anyway, I was just curious and thanks for the answer---and for the great library. – Garret Wilson Oct 27 '14 at 05:40
  • 1
    @GarretWilson: It may be the wine talking out of you... but you're right :) and yes, there have been a couple of silly design decisions. Yet, they're there and we're doing semantic versioning so we cannot get rid of them very soon. But I realised that we don't have an issue yet to fix this particular case, so here it is, planned for jOOQ 4.0: https://github.com/jOOQ/jOOQ/issues/3714 – Lukas Eder Oct 27 '14 at 06:33
  • @LukasEder: Not "silly", just a tiny oversight. Cheers, and thanks for the bug. – Garret Wilson Oct 27 '14 at 13:39
  • @JeanValjean: Thanks for your edit, but the code was correct – Lukas Eder Mar 06 '16 at 20:35
  • @LukasEder that's true, I was drunk I guess! – JeanValjean Mar 06 '16 at 20:37
  • @LukasEder I see that you have used primitive *int* in your query above. Any side effect or performance issue with using wrapper Integer in Java? – realPK Feb 04 '18 at 21:19
  • @realPK: For a single count operation? I don't think so... But perhaps you have a much more specific question? In that case, why not ask a new question? :) – Lukas Eder Feb 05 '18 at 09:20
  • fectchOne method will return null,is that not throw error when use fetchOne(0,int.class)? – Q10Viking Mar 19 '20 at 03:58
  • 1
    @Q10Viking When mapping a column value to `int.class`, jOOQ will never throw a NPE, but use the `int` type's default value instead, which is `0`. So, while `fetchOne()` might return `null` (if there are no results), and `fetchOne(0)` might return `null` (if there are no results, or the value at position `0` is `null`), `fetchOne(0, int.class)` will return `0` in those cases. – Lukas Eder Mar 19 '20 at 08:11
  • @LukasEder with jooq 3.14 and nullable annotations intellij yields a warning that unboxing might throw NPE while this is actually not possible in this case. – oshai Oct 29 '20 at 13:14
  • @oshai: Can you please create an issue: https://github.com/jOOQ/jOOQ/issues/new/choose – Lukas Eder Oct 29 '20 at 14:14
  • @LukasEder submitted here: https://github.com/jOOQ/jOOQ/issues/10831 – oshai Nov 02 '20 at 05:56
4

I use the following syntax for this:

import org.jooq.impl.DSL.count

... 

int count = 
DSL.using(configuration)
   .selectCount()
   .from(Table)
   .fetchOne(count());

This is less verbose and simpler.

Lukas's answer dates from 2013, maybe this solution did not exist at the time.

Kevin Davin
  • 511
  • 1
  • 4
  • 12
0

Here is the solution We have to use like this

  selectQueryRecord.fetchCount();
Subodh Joshi
  • 12,717
  • 29
  • 108
  • 202
0

I used this:

Integer count = DSL.selectCount().from(Table).where(Table.FIELD.eq(value)).fetchOneInto(Integer.class);

Jesús Sánchez
  • 705
  • 11
  • 16
-2

NOTE:

Deprecated. - 3.5.0 - [#3356] - This method is being removed as it is confusingly different from all the other types of ResultQuery.fetch() methods, in that it modifies the original Select statement by wrapping it. In particular, this method can be easily confused with ResultQuery.fetch(Field), or more concretely fetch(count()), which has an entirely different semantics. Use DSLContext.fetchCount(Select) instead. Execute this query in the context of its attached executor and return a COUNT(*) value.

I think the proper way to write get the count would be like this:

 SelectQuery<Record> selectQueryCount = transaction.selectQuery();
 selectQueryCount.addFrom(Table);
 
 Result<Record> resultObject = selectQueryRecord.fetchCount();
Community
  • 1
  • 1
psisodia
  • 1,117
  • 5
  • 17
  • 36
  • `.fetchCount()` **is deprecated now** @Lukas Elder's answer is the correct one now. Not this one. –  Feb 06 '16 at 17:36