30

Can't seem to find a way to get one string from table using JdbcTemplate query. This is the table my sql returns:

ID | STREET_NAME
------------------------
1  | Elm street

Now how am I supposed to get the value of STREET_NAME. SQL always returns one row, so no need to worry about returning more than one row.

For some background info: INNER JOIN and COUNT in the same query

Using Tony Stark answer to get my table.

But how can I extract "Elm street" from it using JdbcTemplate?

Community
  • 1
  • 1
lkallas
  • 1,310
  • 5
  • 22
  • 36

5 Answers5

58

It would help a lot to know what your SQL query looks like, but assuming it's something like SELECT STREET_NAME FROM table WHERE ID=1;

CODE:

public String getStreetNameById(int id) {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    String sql = "SELECT STREET_NAME FROM table WHERE ID=?";

    String streetName = (String) jdbcTemplate.queryForObject(
            sql, new Object[] { id }, String.class);

    return streetName;
}
SGT Grumpy Pants
  • 4,118
  • 4
  • 42
  • 64
jlewkovich
  • 2,725
  • 2
  • 35
  • 49
  • 2
    I tried your code for sure. How does it know what column do you need to get back? It said: "Incorrect column count: expected 1, actual 2" – Laszlo Lugosi Apr 05 '18 at 15:17
  • this is deprecated I am reading, what is the updated solution? queryForObject(java.lang.String, java.lang.Object[], java.lang.Class)' is deprecated – mattsmith5 Aug 23 '21 at 16:19
  • 2
    you can use now: ```queryForObject(sql, String.class, id)``` – Jiyan Akgül Mar 14 '23 at 12:09
13

The class JdbcTemplate implements JdbcOperations.

If you look at the queryForObject javadocs in JdbcOperations it states:

Deprecated. as of 5.3, in favor of queryForObject(String, Class, Object...)

Basically, they have changed the method signature to get rid of Object[] arguments in the method signatures in favor of varargs. Please, see the relevant Github issue.

You can rewrite answer of @jlewkovich with the new method signature like this:

public String getStreetNameById(int id) {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    String sql = "SELECT STREET_NAME FROM table WHERE ID=?";

    String streetName = (String) jdbcTemplate.queryForObject(
            sql, String.class, id);

    return streetName;
}
jccampanero
  • 50,989
  • 3
  • 20
  • 49
  • How to get multiple column in select statement. – Onic Team Jan 07 '22 at 14:57
  • 1
    @VedPrakash It is the same as explained, but you need to use some kind of row mapping mechanism to build your object. Please, see for instance [this related article](https://mkyong.com/spring/spring-jdbctemplate-querying-examples/) for a great couple of examples. I hope it helps. – jccampanero Jan 07 '22 at 16:39
  • String checkDuplicateFileQry = "select job_id, site_level_batch_id from toplevel_bulk_status where file_checksum ='" + checksum + "'"; logger.log(INFO, "checkDuplicateFileQry :: " + checkDuplicateFileQry); List fileIdList = new ArrayList<>(); try { List> uploadedFileId = ((ConnectionFactoryPostgresReaderImpl) cfPostgresReaderImpl).getConnection() .queryForList(checkDuplicateFileQry, new Object[] {checksum}); – Onic Team Jan 07 '22 at 17:26
  • I don't want to use row mapper, I'm using above code but getting error message : The column index is out of range: 1, number of columns: 0. but when i ran this query in my db console it's return row – Onic Team Jan 07 '22 at 17:29
  • issue in my query, missing ? mark in where condition. – Onic Team Jan 07 '22 at 18:11
  • Hi @VedPrakash. Yes, certainly it can be the cause of the error. Sorry, but I think there is something missing on your code. I assume you are using `jdbcTemplate.queryForList`. Please, if that assumption is correct, you could use for instance the example 2.4 in the link I mentioned previously, and build your list as you need to. Does it make sense to you? – jccampanero Jan 07 '22 at 18:18
  • Yes, I'm using jdbcTemplate, Issue resolved, Thank you for your time. – Onic Team Jan 09 '22 at 04:59
  • I didn't do this. – Onic Team Sep 15 '22 at 14:24
  • @OnicTeam Sorry, I wasn't aware that you were mentioned by my comment; it was not my intention to mention you, I was just trying to ask the person who downvoted the answer yesterday if he/she could provide any reason of the downvote. Sorry again, and thank you for the feedback. – jccampanero Sep 15 '22 at 21:36
7

If you want to get only one column "string" from your table (or any query with joins), you have to say the name of the column.

Using SELECT * FROM TABLE is a very-very bad practice by the way. I bet you did this.

@JLewkovich modified code:

public String getStreetNameById(int id) {
  JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
  String sql = "SELECT STREET_NAME FROM table WHERE ID=?";

  String streetName = (String) jdbcTemplate.queryForObject(
        sql, new Object[] { id }, String.class);

  return streetName;
}

But what if there is 0 or more than one result? Think about it!

But to getting a sequence value (in Oracle), this should work.

public Long getSequence() {
  Long seq;
  String sql = "select SEQ_XY.NEXTVAL from dual";
  seq = jdbcTemplateObject.queryForObject(sql, new Object[] {}, Long.class);
  return seq;
}
Laszlo Lugosi
  • 3,669
  • 1
  • 21
  • 17
  • 2
    If you use queryforobject and you get back zero row. It will throw a EmptyResultDataAccessException. It is recommended to use the query method instead so that you can handle it properly. – Dot Batch May 11 '18 at 16:26
  • this is deprecated I am reading, what is the updated solution? queryForObject(java.lang.String, java.lang.Object[], java.lang.Class)' is deprecated – mattsmith5 Aug 23 '21 at 16:24
3

As per latest specification queryForObject with below syntax is now deprecated

<T> T   queryForObject(String sql, Object[] args, Class<T> requiredType)

New method uses varargs.

<T> T   queryForObject(String sql, Class<T> requiredType, Object... args) 

Updated Solution: We have to replace the class type with Object args and vice-versa.

Sql Query: SELECT STREET_NAME FROM table WHERE ID=1;

public String getStreetNameById(int id) {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    String sql = "SELECT STREET_NAME FROM table WHERE ID=?";

    String streetName = (String) jdbcTemplate.queryForObject(
            sql, String.class, new Object[] { id });

    return streetName;
}
TriS
  • 3,668
  • 3
  • 11
  • 25
0

I usually do this way:

String result = DataAccessUtils.singleResult(
    jdbcTemplate.queryForList(
        "SELECT street_name FROM table WHERE id = :id",
        Collections.singletonMap("id", id),
        String.class
    )
)

queryForList is used instead of queryForObject for handling empty results. queryForObject throws EmptyResultDataAccessException for empty results. Often it is not desired behavior.

DataAccessUtils.singleResult + queryForList:

  • returns null for empty result
  • returns single result if exactly 1 row found
  • throws exception if more then 1 rows found. Should not happen for primary key / unique index search

DataAccessUtils.singleResult

Anton Yuriev
  • 580
  • 8
  • 10