So basically, I would like to avoid stored procedures, but at the same time I would'nt want multiple round-trips to database to execute sequential statements.
Apparently this blog says Facebook uses mysql's multiple-statement-queries. Unfortunately, its a C API, is there a java equivalent of it?
So in brief, the question "is in java+mysql how can a second jdbc statement use the output of the first statement as input to execute, without a round-trip to database and without a storedproc" ?
If not how do other people approach this problem?
Yes, the JDBC driver for MySQL support the multi-statement queries. It is however disabled by default for security reasons, as multi-statement queries significantly increase the risks associated with eventual SQL injections.
To turn on multi-statement queries support, simply add the allowMultiQueries=true option to your connection string (or pass the equivalent option in map format). You can get more information on that option here: https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration-properties.html.
Once this option enabled, you can simply execute a call similar to: statement.execute("select ... ; select ... ; select ..."). Returned ResultSets can be iterated from the Statement object: each call to statement.getResultSet() return the next one. Use statement.getMoreResults() to determine if there are indeed more ResultSet available.
It sounds like you want to do batch processing.
here is a duplicate question with an good answer:
How to execute multiple SQL statements from java
Related
Is there a way to make jOOQ perform a SQL statement (in my case a CHECKPOINT) after each DELETE?
Ideally there would also be a way to specify the tables that this happens for.
The RDBMS I'm using (HSQLDB) doesn't allow this statement inside a trigger, otherwise I would have done it this way.
Is there a way to make jOOQ perform a SQL statement (in my case a CHECKPOINT) after each DELETE?
The easiest way forward would be to use an ExecuteListener which checks whether the current statement is a DELETE statement. You can do this:
Either using a regex on the generated SQL, if you also have plain SQL statements that are not generated using the jOOQ DSL
Or using an instanceof Delete check on ExecuteContext.query() if you're sure that you're only running jOOQ DSL statements.
This is to detect the execution of such a statement. Your follow up statement can be run in different ways, of course.
Ideally there would also be a way to specify the tables that this happens for.
This is a bit more tricky. You could implement your own VisitListener that finds all the delete statements on specific tables.
This only works if you use the DSL API, unless you're willing to run a VisitListener on a jOOQ query that you parse based on your plain SQL statements, in case of which you could also do this for arbitrary other statements. Assuming that the parser can parse your SQL.
You should be able to execute "checkpoint" from within jOOQ using the Execute statement, something like:
//create connection
String sql = "use [MyDatabase] checkpoint ";
connection.createStatement().executeQuery(sql);
Having said that, why run a checkpoint after each deleted record? If you're worried about the data being written to disc, just run "checkpoint" you iterate through all your delete operations.
Is it good practice to use Prepared statement for SELECT SQL with connection pooling. (In my case I use Tomcat JDBC connection pool).
Does it add any advantage(speed ups) or it will add overhead for maintaining the Prepared Statements, connections and keep them alive or track whether closed as Pooled connections are maintained internally and they get closed according to different settings as specified here.
I am using DataSource to get connection, Database is MariaDB.
While reading various posts, documentations and examples most of Prepared Statement have been built using INSERT or UPDATE queries. Does it points that for SELECT it will not add any advantage?
MariaDB/MySQL prepared statements do not have any advantages when it comes to query parsing / optimizing, the query plan is not preserved as on some other SQL databases.
They do have a performance advantage when it comes to transferring result sets as column values can be transfered in binary form and get stored into result variables right away. With classic non-prepared statements all result fields are converted to textual form on the server side. This adds processing time on the server side, leads to more bytes having to be transfered over the wire, and depending on your application needs the client side may need to convert values back from textual to binary form (e.g. for integer and float values).
The other reason for using prepared statements, as also noted in the previous comments, is that it is a reliable way to prevent SQL injection, and that applies to SELECT as well as INSERT/UPDATE/DELETE
It's good to use PreparedStatement if you can:
Prevent SQLInjection
Abstract Date/Time representation
Deal with Charset conversions
Readability (you see one string with full SQL)
As the SQL stays constant (with ?) the database might cache the plan and doesn't have to reparse
In case of SELECT the main focus of cause lies with the parameters passed into the WHERE condition.
As for performance: This may depend - but I've never experienced PreparedStatements to be significantly worse than simple Statements - if coded correct of cause.
The fact that you're pooling connections doesn't add much to this. The concept of somehow "preparing all the statements you're going to need on that connection for later" is not how PreparedStatments are meant to be used. It's perfectly fine to prepare the same tiny Statement over and over and over - altough if faced with a loop of INSERTs or UPDATEs it would be wise to reuse PreparedStatement and/or batch the INSERTs
I have to confirm that can we execute multiple select statement in one shot and get multiple resultsets. Please give me some idea for doing this.
I have to execute two select query in one statement:-
String sql="select * form test;
select * from test where empid=1;"
I am expecting to run like this :-
statement.execute(sql);
thanks
I don't believe that standard JDBC supports this. Certainly the ResultSet interface is oriented towards "multiple rows, one row at a time" - but not "multiple sets of results".
That doesn't mean it's not feasible with your specific database, however - it's possible that there's a driver for your database which extends JDBC to allow it. If you specify which database and driver you're using, we could verify that more easily.
In my opinion JDBC does not allow executing multiple statements in one go. The language used in the JDBC specification and API doc indicates that the expectation is that one Statement execution is one statement, not multiple statements (eg it uses 'a SQL statement', which when reading the SQL spec means a single SELECT, INSERT, etc). However it never explicitly states it is not allowed.
Some drivers do support execution of multiple statements in one execution, but this usually has to be explicitly enabled using a connection property. Also some databases support executing a block of stored procedure code without explicitly defining a stored procedure (in that case the block is considered to be the statement).
Create a stored procedure with those set of select statements and use Statement.getMoreResults() to check whether you have more ResultSets and use
Statement.getResultSet() to get the next ResultSet
An example is given Here
In one of my applications I am providing the users the ability to issue direct SQL queries against a database. They type the SQL text into a text box, then I run it exactly as is using JDBC.
Obviously I trust these users very much. But I would like to limit them programatically to issuing only SELECT statements. They should never DELETE/UPDATE/INSERT. I thought maybe JDBC itself could help me here. I found the executeQuery() method in the java.sql.Statement class. But that method allows me to call DELETE (and maybe UPDATE and INSERT too). It does throw an Exception because no ResultSet is returned, but only after deleting the records.
So, I ask here, is there any way in JDBC to make sure that a SQL statement is only performed if it is a query? Or do I have to parse the statement myself and make sure it complies with my wishes?
I suggest you connect to the DBMS with a user that lacks the DELETE / UPDATE and INSERT permissions.
Often, in the network can be found code like this:
private static final String SQL = "SELECT * FROM table_name";
....
and for this SQL query is used PreparedStatement. Why?
As i know, PreparedStatement spend time to precompile SQL statement. It turns out so that the Statement is faster than a PreparedStatement. Or I'm mistaken?
Prepared statements are much faster when you have to run the same statement multiple times, with different data. Thats because SQL will validate the query only once, whereas if you just use a statement it will validate the query each time.
The other benefit of using PreparedStatements is to avoid causing a SQL injection vulnerability - though in your case your query is so simple you haven't encountered that.
For your query, the difference between running a prepared statement vs a statement is probably negligible.
EDIT: In response to your comment below, you will need to look closely at the DAO class to see what it is doing. If for example, each time the method is called it re-creates the prepared statement then you will lose any benefit of using prepared statements.
What you want to achieve, is the encapsulation of your persistence layer so that their is no specific call to MySQL or Postgres or whatever you are using, and at the same time take advantage of the performance and security benefits of things like prepared statements. To do this you need to rely on Java's own objects such as PreparedStatement,.
I personally would build my own DAO class for doing CRUD operations, using Hibernate underneath and the Java Persistence API to encapsulate it all, and that should use prepared statements for the security benefits. If you have a specific use-case for doing repeated operations, then I would be inclined to wrap that within its own object.
Hibernate can be configured to use whatever database vendor you are using via an XML file, and thus it provides really neat encapsulation of your persistence layer. However, it is quite a complicated product to get right!
Most of the time queries are not as simple as your example. If there is any variation to the query, i.e. any parameters that are not known at compile time, you must use PreparedStatement to avoid SQL injection vulnerabilities. This trumps any performance concerns.
If there is any difference between PreparedStatement and Statement, it would be highly dependent on the particular JDBC driver in question and most of the time the penalty will be negligible compare to the cost of going to the database, executing actual query and fetching results back.
As Per the My knowledge PreparedStatement is much faster then statement. Here some reason why preparedstatement is faster then statement please read for more detail.
JDBC API is provide the functionality of connectivity with database. Then we try to execute the query with the use of statement and preparedstatement.
There are four step to execute the query.
Parsing of sql query.
Compile this Query.
optimization of data acquisition path.
execute the query.
Statement interface is suitable when we will not need to execute the query multiple time.
Disadvantages of Statement Interface.
hacker can easily to hack the data. Like suppose we have one query which have the username and password is a parameters you can give the proper parameters is username='abc#example.com' and password ='abc123' actually this is current But hacker can do username='abc#example.com' or '1'=1 and password='' that means you can logged successfully. so that is happening possible in Statement.
And sql validate every time when we fetch the data from database.
So Java has the solution for this above problem that is PreparedStatement.
This interface has many advantages. the main advantages of preparedstatement is sql is not validate the query every time. so you can get the result fast. please read the below more advantages of preparedstatement.
1) We can safely provide the value of query's parameters with setter method.
2) it prevent the SQL injection because it is automatically escapes the special characters.
3) When we use statement above four steps are execute every time But when we use the PreparedStatement only last steps is execute so this is faster then statement.
Faster is not the consideration here. Parsing of the sql will generally be a tiny part of overall execution. See more at When should we use a PreparedStatement instead of a Statement?