Does updateCount() and executeUpdate() return samething - java

String query="UPDATE table_name SET tab_attr1= ? WHERE tab_attr2= ?";
PreparedStatement preparedStatement=connection.prepareStatement(query);
preparedStatement.setString(1,"test1");
preparedStatement.setString(2,"test2");
//case_1
int count=preparedStatement.executeUpdate();
/*
case_2
preparedStatement.execute();
int count=preparedStatement.getUpdateCount();
*/
Im new to the field and working as a Java Developer
In my testcases both returns the same thing
So my question is whether there is any difference between the two
and if no differences then what is the need for both functions.
What is the difference between 2 cases..?

From the docs:
PreparedStatement.html#executeUpdate()
Executes the SQL statement in this PreparedStatement object, which
must be an SQL Data Manipulation Language (DML) statement, such as
INSERT, UPDATE or DELETE; or an SQL statement that returns nothing,
such as a DDL statement.
Returns: either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0 for SQL statements that return nothing
So basically:
executeUpdate() is used for SQL INSERT, UPDATE, DELETE or a DLL statement.
execute() could be used for any SQL statement after which you would call getUpdateCount().
Since you're using an UPDATE it doesn't matter in your case. There should be no difference.

executeUpdate(String sql):This method is used for SQL statements which update the database in some way ,returns an int value which represents the number of rows affected by the query
execute(String sql) :This method can be used for all types of SQL statements. If you don’t know which method to use for you SQL statements, then this method can be the best option.
there is also executeQuery(String sql) :This method is used for SQL statements which retrieve some data from the database,This method is meant to be used for select queries which fetch some data from the database

Related

How to use org.springframework.jdbc.object to implement reusable ddl statements?

I would like to use entities from org.springframework.jdbc.object package for modeling access to database.
It is clear how to create objects for select, update, insert and delete queries. We can just extend MappingSqlQuery<?> or SqlUpdate then declare all the parameters, collect named parameters in some map and execute statement stmt.executeByNamedParam(Map<String, ?> paramMap);.
It is not clear how we can use org.springframework.jdbc.object package to implement ddl statements like schema/table creation, or altering table.
For example I would like to create schema dynamically, the query look like this: create schema if not exists schema_name.
I create statement in next way:
public final class CreateSchemaStmt extends SqlUpdate {
private static final String CREATE_SCHEMA_SQL_TEMPLATE =
"create schema if not exists ?";
public CreateSchemaStmt(DataSource ds) {
setDataSource(ds);
setSql(CREATE_SCHEMA_SQL_TEMPLATE);
declareParameter(new SqlParameter("schema", Types.VARCHAR));
compile();
}
}
But it is not possible to declare parameter in such a way and pass it to statement execution.
Of course I can always create a new statement when I need to create new schema/table or alter table (with sql query without placeholders), but in this case this statement will not be reusable.
Could such kind of query be created and executed with named parameters?
No, a DDL statement cannot be reused. Any change of table name, column name, column data type, etc. will be a different statement.
All the classes in the org.springframework.jdbc.object package are helpers for using a PreparedStatement, and DDL statements will gain no benefit from being prepared.
For DDL, use JdbcTemplate and the execute(String sql) method. As the javadoc of that method says:
Issue a single SQL execute, typically a DDL statement.
Don't focus on the tool. When you say "I would like to use entities from org.springframework.jdbc.object package", you're focusing too much on the tool. You should focus on the job that needs done, then pick the right tool for the job. For DDL statements, JdbcTemplate.execute(sql) is the right tool.
Use batchUpdate(String... sql) and ignore the return value, if you have a lot of DDL statements to execute and performance is critical. For DDL statements though, that is unlikely to be the case.

getting result of select 1 query in PreparedStatement in JAVA [duplicate]

The Prepared Statement is a slightly more powerful version of a Statement, and should always be at least as quick and easy to handle as a Statement.
The Prepared Statement may be parametrized
Most relational databases handles a JDBC / SQL query in four steps:
Parse the incoming SQL query
Compile the SQL query
Plan/optimize the data acquisition path
Execute the optimized query / acquire and return data
A Statement will always proceed through the four steps above for each SQL query sent to the database. A Prepared Statement pre-executes steps (1) - (3) in the execution process above. Thus, when creating a Prepared Statement some pre-optimization is performed immediately. The effect is to lessen the load on the database engine at execution time.
Now my question is this:
"Is there any other advantage of using Prepared Statement?"
Advantages of a PreparedStatement:
Precompilation and DB-side caching of the SQL statement leads to overall faster execution and the ability to reuse the same SQL statement in batches.
Automatic prevention of SQL injection attacks by builtin escaping of quotes and other special characters. Note that this requires that you use any of the PreparedStatement setXxx() methods to set the values
preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email, birthdate, photo) VALUES (?, ?, ?, ?)");
preparedStatement.setString(1, person.getName());
preparedStatement.setString(2, person.getEmail());
preparedStatement.setTimestamp(3, new Timestamp(person.getBirthdate().getTime()));
preparedStatement.setBinaryStream(4, person.getPhoto());
preparedStatement.executeUpdate();
and thus don't inline the values in the SQL string by string-concatenating.
preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email) VALUES ('" + person.getName() + "', '" + person.getEmail() + "'");
preparedStatement.executeUpdate();
Eases setting of non-standard Java objects in a SQL string, e.g. Date, Time, Timestamp, BigDecimal, InputStream (Blob) and Reader (Clob). On most of those types you can't "just" do a toString() as you would do in a simple Statement. You could even refactor it all to using PreparedStatement#setObject() inside a loop as demonstrated in the utility method below:
public static void setValues(PreparedStatement preparedStatement, Object... values) throws SQLException {
for (int i = 0; i < values.length; i++) {
preparedStatement.setObject(i + 1, values[i]);
}
}
Which can be used as below:
preparedStatement = connection.prepareStatement("INSERT INTO Person (name, email, birthdate, photo) VALUES (?, ?, ?, ?)");
setValues(preparedStatement, person.getName(), person.getEmail(), new Timestamp(person.getBirthdate().getTime()), person.getPhoto());
preparedStatement.executeUpdate();
They are pre-compiled (once), so faster for repeated execution of dynamic SQL (where parameters change)
Database statement caching boosts DB execution performance
Databases store caches of execution plans for previously executed statements. This allows the database engine to reuse the plans for statements that have been executed previously. Because PreparedStatement uses parameters, each time it is executed it appears as the same SQL, the database can reuse the previous access plan, reducing processing. Statements "inline" the parameters into the SQL string and so do not appear as the same SQL to the DB, preventing cache usage.
Binary communications protocol means less bandwidth and faster comms calls to DB server
Prepared statements are normally executed through a non-SQL binary protocol. This means that there is less data in the packets, so communications to the server is faster. As a rule of thumb network operations are an order of magnitude slower than disk operations which are an order of magnitude slower than in-memory CPU operations. Hence, any reduction in amount of data sent over the network will have a good effect on overall performance.
They protect against SQL injection, by escaping text for all the parameter values provided.
They provide stronger separation between the query code and the parameter values (compared to concatenated SQL strings), boosting readability and helping code maintainers quickly understand inputs and outputs of the query.
In java, can call getMetadata() and getParameterMetadata() to reflect on the result set fields and the parameter fields, respectively
In java, intelligently accepts java objects as parameter types via setObject, setBoolean, setByte, setDate, setDouble, setDouble, setFloat, setInt, setLong, setShort, setTime, setTimestamp - it converts into JDBC type format that is comprehendible to DB (not just toString() format).
In java, accepts SQL ARRAYs, as parameter type via setArray method
In java, accepts CLOBs, BLOBs, OutputStreams and Readers as parameter "feeds" via setClob/setNClob, setBlob, setBinaryStream, setCharacterStream/setAsciiStream/setNCharacterStream methods, respectively
In java, allows DB-specific values to be set for SQL DATALINK, SQL ROWID, SQL XML, and NULL via setURL, setRowId, setSQLXML ans setNull methods
In java, inherits all methods from Statement. It inherits the addBatch method, and additionally allows a set of parameter values to be added to match the set of batched SQL commands via addBatch method.
In java, a special type of PreparedStatement (the subclass CallableStatement) allows stored procedures to be executed - supporting high performance, encapsulation, procedural programming and SQL, DB administration/maintenance/tweaking of logic, and use of proprietary DB logic & features
PreparedStatement is a very good defense (but not foolproof) in preventing SQL injection attacks. Binding parameter values is a good way to guarding against "little Bobby Tables" making an unwanted visit.
Some of the benefits of PreparedStatement over Statement are:
PreparedStatement helps us in preventing SQL injection attacks because it automatically escapes the special characters.
PreparedStatement allows us to execute dynamic queries with parameter inputs.
PreparedStatement provides different types of setter methods to set the input parameters for the query.
PreparedStatement is faster than Statement. It becomes more visible when we reuse the PreparedStatement or use it’s batch processing methods for executing multiple queries.
PreparedStatement helps us in writing object Oriented code with setter methods whereas with Statement we have to use String Concatenation to create the query. If there are multiple parameters to set, writing Query using String concatenation looks very ugly and error prone.
Read more about SQL injection issue at http://www.journaldev.com/2489/jdbc-statement-vs-preparedstatement-sql-injection-example
nothing much to add,
1 - if you want to execute a query in a loop (more than 1 time), prepared statement can be faster, because of optimization that you mentioned.
2 - parameterized query is a good way to avoid SQL Injection. Parameterized querys are only available in PreparedStatement.
Statement is static and prepared statement is dynamic.
Statement is suitable for DDL and prepared statment for DML.
Statement is slower while prepared statement is faster.
more differences (archived)
Can't do CLOBs in a Statement.
And: (OraclePreparedStatement) ps
As Quoted by mattjames
The use of a Statement in JDBC should be 100% localized to being used
for DDL (ALTER, CREATE, GRANT, etc) as these are the only statement
types that cannot accept BIND VARIABLES. PreparedStatements or
CallableStatements should be used for EVERY OTHER type of statement
(DML, Queries). As these are the statement types that accept bind
variables.
This is a fact, a rule, a law -- use prepared statements EVERYWHERE.
Use STATEMENTS almost no where.
Statement will be used for executing static SQL statements and it can't accept input parameters.
PreparedStatement will be used for executing SQL statements many times dynamically. It will accept input parameters.
sql injection is ignored by prepared statement so security is increase in prepared statement
It's easier to read
You can easily make the query string a constant
Statement interface executes static SQL statements without parameters
PreparedStatement interface (extending Statement) executes a precompiled SQL statement with/without parameters
Efficient for repeated executions
It is precompiled so it's faster
Another characteristic of Prepared or Parameterized Query: Reference taken from this article.
This statement is one of features of the database system in which same SQL statement executes repeatedly with high efficiency. The prepared statements are one kind of the Template and used by application with different parameters.
The statement template is prepared and sent to the database system and database system perform parsing, compiling and optimization on this template and store without executing it.
Some of parameter like, where clause is not passed during template creation later application, send these parameters to the database system and database system use template of SQL Statement and executes as per request.
Prepared statements are very useful against SQL Injection because the application can prepare parameter using different techniques and protocols.
When the number of data is increasing and indexes are changing frequently at that time Prepared Statements might be fail because in this situation require a new query plan.
Dont get confusion : simply remember
Statement is used for static queries like DDLs i.e. create,drop,alter and prepareStatement is used for dynamic queries i.e. DML query.
In Statement, the query is not precompiled while in prepareStatement query is precompiled, because of this prepareStatement is time efficient.
prepareStatement takes argument at the time of creation while Statement does not take arguments.
For Example if you want to create table and insert element then ::
Create table (static) by using Statement and Insert element (dynamic)by using prepareStatement.
I followed all the answers of this question to change a working legacy code using - Statement ( but having SQL Injections ) to a solution using PreparedStatement with a much slower code because of poor understanding of semantics around Statement.addBatch(String sql) & PreparedStatement.addBatch().
So I am listing my scenario here so others don't make same mistake.
My scenario was
Statement statement = connection.createStatement();
for (Object object : objectList) {
//Create a query which would be different for each object
// Add this query to statement for batch using - statement.addBatch(query);
}
statement.executeBatch();
So in above code , I had thousands of different queries, all added to same statement and this code worked faster because statements not being cached was good & this code executed rarely in the app.
Now to fix SQL Injections, I changed this code to ,
List<PreparedStatement> pStatements = new ArrayList<>();
for (Object object : objectList) {
//Create a query which would be different for each object
PreparedStatement pStatement =connection.prepareStatement(query);
// This query can't be added to batch because its a different query so I used list.
//Set parameter to pStatement using object
pStatements.add(pStatement);
}// Object loop
// In place of statement.executeBatch(); , I had to loop around the list & execute each update separately
for (PreparedStatement ps : pStatements) {
ps.executeUpdate();
}
So you see, I started creating thousands of PreparedStatement objects & then eventually not able to utilize batching because my scenario demanded that - there are thousands of UPDATE or INSERT queries & all of these queries happen to be different.
Fixing SQL injection was mandatory at no cost of performance degradation and I don't think that it is possible with PreparedStatement in this scenario.
Also, when you use inbuilt batching facility, you have to worry about closing only one Statement but with this List approach, you need to close statement before reuse , Reusing a PreparedStatement

Is there a method (java) for use both the methods executeupdate and executequery?

On my program (client - server), sometimes the client send to server a query for example : "select from ....", so on server there is executeQuery, and sometimes the client send to client a query for example : "insert into.... ", so on server there is executeUpdate.
I want a method that i can use for executeQuery and executeUpdate.
If you are passing Query String than at Server\Client when you receive the query decide your path.
Create Different Methods for Execution of different queries and pass parameter as String(Query) or you can use conditional statements to provide proper execution according to String.
By the use of String Methods like queryString.startsWith("insert") to find appropriate method for execution and decide whether go for insert/update/select or anything else.
And yes as user432 has suggested it would be better to go for execute() which can execute any kind of SQL Statement.
But for Queries which returns data you need to use Methods on statement Object Like.
getResultSet()
getUpdateCount()
At an API level, this would be a non-sense to have the same method for both, as they do return different objects. The executeUpdate() method returns the number of rows that were affected by your update, whereas the executeQuery() method returns a ResultSet containing all your results, which is very handy.

Statement and PreparedStatement in JDBC [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between Statement and PreparedStatement
I have confused with Statement and PreparedStatement in JDBC.Is PreparedStatement is version of Statement? or any other difference in that ? Can any body clear that question. thanks.
From Using Prepared Statements of the Java official tutorials
Sometimes it is more convenient to use a PreparedStatement object for
sending SQL statements to the database. This special type of statement
is derived from the more general class, Statement, that you already
know.
If you want to execute a Statement object many times, it usually
reduces execution time to use a PreparedStatement object instead.
The main feature of a PreparedStatement object is that, unlike a
Statement object, it is given a SQL statement when it is created. The
advantage to this is that in most cases, this SQL statement is sent to
the DBMS right away, where it is compiled. As a result, the
PreparedStatement object contains not just a SQL statement, but a SQL
statement that has been precompiled. This means that when the
PreparedStatement is executed, the DBMS can just run the
PreparedStatement SQL statement without having to compile it first.
Although PreparedStatement objects can be used for SQL statements with
no parameters, you probably use them most often for SQL statements
that take parameters. The advantage of using SQL statements that take
parameters is that you can use the same statement and supply it with
different values each time you execute it. Examples of this are in the
following sections.

Can we execute some queries while traversing resultset in java

I am trying to implement a task in java using JDBC like Stored Procedure in SQL.
In SQL, when we write cursor, first we execute select query and then fetching the records we perform some actions.
Likely I have fired a select query in Hive.
sql="SELECT a,c,b FROM tbl_name";
res=stmt.executeQuery(); -----------> CONTAINS 30 RECORDS
while(res.next())
{
sql="INSERT INTO table .....";
rs1=stmt.executeQuery();
sql="SELECT d,e,f FROM table .....";
rs1=stmt.executeQuery();
like wise many queries are there.....
.
.
.
..
}
As my select query contains 30 records but when I execute it my while(res.next()) execute only once.
But instead of queries I just try to display field to check whether it is fetching or not
then it is working fine..
(while loop contains only System.out.println statements)
sql="SELECT * FROM tbl_name";
res=stmt.executeQuery(sql);
while(res.next())
{
S.O.P.("fields : "+res.getString(0));
}
(I think that when the resultset is getting traversed and if in between queries are there then queries get the executed but at the same time loop also get executes and after some time when queries execution get finishes by that while loop of resultset also get finishes and hence it get executes for once. I am not sure about it.)
Why it is happening I am not getting. Is anything I am doing wrong?
Each Statement can only have one open ResultSet at a time. From the documentation:
By default, only one ResultSet object per Statement object can be open
at the same time. Therefore, if the reading of one ResultSet object is
interleaved with the reading of another, each must have been generated
by different Statement objects. All execution methods in the Statement
interface implicitly close a statment's current ResultSet object if an
open one exists.
The calls to executeQuery inside your loop will implicitly close the outer ResultSet, so that's why you only see one row.
I would restructure your flow. Primarily, don't try and reuse the same Statement object to execute a new query. When I try that using the PostgreSQL driver, for example, I readily get an exception, "This ResultSet is closed."
Instead, rewrite it to something like this:
Connection conn = DriverManager.getConnection(...);
Statement outerStatement = conn.createStatement();
ResultSet outerResultSet = outerStatement.executeQuery("...");
while (outerResultSet.next()) {
Statement innerStatement = conn.createStatement();
ResultSet innerResultSet = innerStatement.executeQuery("...");
while (innerResultSet.next()) {
// ...
}
innerResultSet.close();
innerStatement.close();
}
outerResultSet.close();
outerStatement.close();
conn.close();
Of course, surround with try-catch-finally as needed.
It doesn't happen like that, You can try until your query gets executed loop will wait.
ideally you can only have one statement executing at one moment in time against one database connection so you can either create and execute the second statement, or iterate through the resultset from first statement and store the data in collection (e.g. in an arraylist of hashmap) then close that statement and run the second one, this time retrieving the id's from the collection you saved them in.

Categories

Resources