Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 209 Vote(s) - 3.67 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Using prepared statements with JDBCTemplate

#1
I'm using the JDBC template and want to read from a database using prepared statements. I iterate over many lines in a .csv file, and on every line I execute some SQL select queries with corresponding values.

I want to speed up my reading from the database but I don't know how to get the JDBC template to work with prepared statements.

There is the [PreparedStatementCreator][1] and the [PreparedStatementSetter][2]. As in [this example][3] both of them are created with anonymous inner classes.
But inside the PreparedStatementSetter class I don't have access to the values I want to set in the prepared statement.

Since I'm iterating through a .csv file, I can't hard code them as a String because I don't know them.
I also can't pass them to the PreparedStatementSetter because there are no arguments for the constructor. And setting my values to final would be dumb too.

I was used to the creation of prepared statements being fairly simple. Something like

PreparedStatement updateSales = con.prepareStatement(
"UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? ");
updateSales.setInt(1, 75);
updateSales.setString(2, "Colombian");
updateSales.executeUpdate():

as in this [Java tutorial][4].


[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]

[4]:

[To see links please register here]

Reply

#2
Try the following:

PreparedStatementCreator creator = new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement updateSales = con.prepareStatement(
"UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? ");
updateSales.setInt(1, 75);
updateSales.setString(2, "Colombian");
return updateSales;
}
};
Reply

#3
I'd factor out the prepared statement handling to at least a method. In this case, because there are no results it is fairly simple (and assuming that the connection is an instance variable that doesn't change):

private PreparedStatement updateSales;
public void updateSales(int sales, String cof_name) throws SQLException {
if (updateSales == null) {
updateSales = con.prepareStatement(
"UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ?");
}
updateSales.setInt(1, sales);
updateSales.setString(2, cof_name);
updateSales.executeUpdate();
}

At that point, it is then just a matter of calling:

updateSales(75, "Colombian");

Which is pretty simple to integrate with other things, yes? And if you call the method many times, the update will only be constructed once and that will make things much faster. Well, assuming you don't do crazy things like doing each update in its own transaction...

Note that the types are fixed. This is because for any particular query/update, they *should* be fixed so as to allow the database to do its job efficiently. If you're just pulling arbitrary strings from a CSV file, pass them in as strings. There's also no locking; far better to keep individual connections to being used from a single thread instead.
Reply

#4
class Main {
public static void main(String args[]) throws Exception {
ApplicationContext ac = new
ClassPathXmlApplicationContext("context.xml", Main.class);
DataSource dataSource = (DataSource) ac.getBean("dataSource");
// DataSource mysqlDataSource = (DataSource) ac.getBean("mysqlDataSource");

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

String prasobhName =
jdbcTemplate.query(
"select first_name from customer where last_name like ?",
new PreparedStatementSetter() {
public void setValues(PreparedStatement preparedStatement) throws
SQLException {
preparedStatement.setString(1, "nair%");
}
},
new ResultSetExtractor<Long>() {
public Long extractData(ResultSet resultSet) throws SQLException,
DataAccessException {
if (resultSet.next()) {
return resultSet.getLong(1);
}
return null;
}
}
);
System.out.println(machaceksName);
}
}
Reply

#5
By default, the `JDBCTemplate` does its own `PreparedStatement` internally, if you just use the `.update(String sql, Object ... args)` form. Spring, and your database, will manage the compiled query for you, so you don't have to worry about opening, closing, resource protection, etc. One of the saving graces of Spring. [A link to Spring 2.5's documentation on this.][1] Hope it makes things clearer. Also, statement caching can be done at the JDBC level, as in the case of [at least some of Oracle's JDBC drivers.][2]
That will go into a lot more detail than I can competently.


[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#6
I've tried a select statement now with a [`PreparedStatement`][1], but it turned out that it was not faster than the Jdbc template. Maybe, as mezmo suggested, it automatically creates prepared statements.

Anyway, the reason for my sql `SELECT`s being so slow was another one. In the `WHERE` clause I always used the operator `LIKE`, when all I wanted to do was finding an exact match. As I've found out `LIKE` searches for a pattern and therefore is pretty slow.

I'm using the operator `=` now and it's much faster.

[1]:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through