Before I explain my problem I would like to say that I know the basics of JDBC but not really used to it.
I am using an updatable result set to hold data from 2 different tables, as in the following sample code:
searchQry = "SELECT ct.CustomerName, ct.Email, ct.PhoneNo, ot.ItemName
FROM CUSTOMER_TABLE ct JOIN ORDER_Table ot
ON ct.OrderID = ot.OrderID";
prestmt = dbcon.prepareStatement(searchQry, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
uprs = prestmt.executeQuery();
uprs.updateLong("ut.PhoneNo", 7240987456L);
uprs.updateString("otItemName", "GTA5");
uprs.updateRow();
I would like to know if I will update the database from somewhere else (not using the same result set object) while the result set, upsr, connected to the database, whether uprs will get updated with it or it will throw an error or it will go with the old data itself. Sorry if it a newbie question but I can't really test that on my DB without knowing the outcomes and safe measures.
Please, suggest me if there is any better way to update the underlining db along with the data in the ResultSet without having any transaction issues when changing from different places.
Using:
Oracle Database for JDBC connection.
Related
I'm trying to write a small code snippet where I need to get some data from a database and then process the result in some other java file. I tried writing a program and the execution for the same was failing with error "Cannot access resultset as the connection was already closed".
Is there any way can we store the result fetched from database some where (Ex.some arraylist) and use it for computation after closing the connection? If yes, can someone please explain it with example?
Slightly handicapped since I'm new to it.
Class A {
public Map<String, Object> loadDat(int acc,Map<String,Object> result)
throws Exception {
Class.forName("com.teradata.jdbc.TeraDriver");
Connection conn = DriverManager.getConnection(connectionString, user, password);
query = "select * from mytable where id="+acc;
PreparedStatement stmt = conn.prepareStatement(query);
ResultSet rs=stmt.executeQuery();
result.put(" Result", rs) ;
return result;
}
}
In general,
don't code JDBC database access by hand.
Libraries already exist that do all the low level JDBC handling now and
they do it correctly.
You will never do it better than an one of the mature,
open source projects already do it.
Instead,
learn and use something like MyBatis.
If you use Spring,
here is a link to the Mybatis-Spring project.
MyBatis conceals all of the data conversion and JDBC junk.
Instead, you define your query in a simple XML file and receive a List
as the result of a query.
Just to add to #DwB's answer that is correct.
You can 1) retrieve all rows from your query into a Java List, 2) then close the connection, and 3) then use the Java List in another class (for further processing).
If you close the connection after retrieving only part of the result set, you'll lose the rest of it and will receive the error you mention. Don't do it this way.
The code that I am working with primarily uses Spring and jdbcTemplate as a way to query the database.
As a non-working example, but just to get the idea across of how I get data and display it on my website...
There will be some object called Bike.
List<bikeObject> bikes = new ArrayList<>();
List<Map<String, Object>> rows = jdbcTemplate.queryForList(bikeQuery));
for (Map<String<Object> row : rows){
bikeObject b = new bikeObject();
b.setProperty((String row.get(-property-));
....
bikes.push(bikeObject)
}
However, sometimes the query can be too large and my computer can run out of memory or the database query can timeout.
A solution that was brought to my attention was to just query it into a ResultSet and then iterate through and stream it directly to a file. I can scrap the display on the website and just let the user download an excel table on a click of a button.
I see that I can use something like (copied from the oracle site)
OracleDataSource ods = new OracleDataSource();
ods.setURL(url);
ods.setUser(user);
ods.setPassword(password);
String URL = "jdbc:oracle:thin:scott/tiger#//myhost:1521/orcl");
ods.setURL(URL);
Connection conn = ods.getConnection();
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery(query);
from here I think I can just iterate through rset and write to a file using BufferedWriter.
The issue I have with this is that my code is pretty consistent so how would I set the URL/User/Password from the Spring properties file that I have? I don't want to type it in the file on a one time occasion.
Also, is this the best way to approach this problem? Can I write to file using jdbcTemplate + ResultSet? I'm stuck on finding a way how.
Slight update:
I assume that the query (passed off from someone else) is optimal and that all the data is necessary. This leaves me with the conclusion of streaming the query results straight to file. Is there a way I can do this with jdbcTemplate or do I have to do it via
Connection conn = ods.getConnection();
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery(swSb);
And iterating through it on a next() basis?
You don't describe well the problem: Do you really need all data? is database setup with indexes and is the query optimal?
You can use oracle pagination support http://www.oracle.com/technetwork/issue-archive/2007/07-jan/o17asktom-093877.html so the user get first X elements.
If you really need all data and it is a lot I would avoid mapping to an object specially object instantiation inside a loop.
It would help if you could tell how many rows are you expecting
I have a wierd behavior in a Java application.
It issues simple queries and modifications to a remote MySQL database. I found that queries, run by executeQuery() work just fine, but inserts or delete to the database run through executeUpdate() will fail.
Ruling out the first thing that comes to mind: the user the app connects with has correct privilledges set up, as the same INSERT run from the same machine, but in DBeaver, will produce the desired modification.
Some code:
Connection creation
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(url, user, pass);
Problematic part:
Statement parentIdStatement = connection.createStatement();
String parentQuery = String.format(ProcessDAO.GET_PARENT_ID, parentName);
if (DEBUG_SQL) {
plugin.getLogger().log(Level.INFO, parentQuery);
}
ResultSet result = parentIdStatement.executeQuery(parentQuery);
result.first();
parentId = result.getInt(1);
if (DEBUG_SQL) {
plugin.getLogger().log(Level.INFO, parentId.toString()); // works, expected value
}
Statement createContainerStatement = connection.createStatement();
String containerQuery = String.format(ContainerDAO.CREATE_CONTAINER, parentId, myName);
if (DEBUG_SQL) {
plugin.getLogger().log(Level.INFO, containerQuery); // works when issued through DBeaver
}
createContainerStatement.executeUpdate(containerQuery); // does nothing
"DAOs":
ProcessDAO.GET_PARENT_ID = "SELECT id FROM mon_process WHERE proc_name = '%1$s'";
ContainerDAO.CREATE_CONTAINER = "INSERT INTO mon_container (cont_name, proc_id, cont_expiry, cont_size) VALUES ('%2$s', %1$d, CURRENT_TIMESTAMP(), NULL)";
I suspect this might have to do with my usage of Statement and Connection.
This being a lightweight lightly-used app, I went to simplicity, so no framework, and no specific isntructions regarding transactions or commits.
So, in the end, this code was just fine. It worked today.
To answer the question: where to look first in a similar case (SELECT works but UPDATE / INSERT / DELETE does not)
If rights are not the problem, then there is probably a lock on the table you try to modify. In my case, someone left with an uncommited transaction open.
Proper SQL exceptions logging (which was suboptimal in my case) will help you figure it out.
I want to display the data of a postgresql database using the CRUD in the play framework; I looked for any examples to get idea which I didn't find after a long time of searching in google. Someone help me with this if you can or post a valid link regarding this. Thanks in advance!
I use, Play 1.2.5, java and postgresql.
I assume you want to do this in your application code in runtime.
You can execute query using DB plugin to search DB metadata using native PostgreSQL queries.
Here's an example how to get column names of my system DOCUMENT table:
List<String> columns = new ArrayList<>();
ResultSet result = DB.executeQuery("select column_name from INFORMATION_SCHEMA.COLUMNS where table_name = 'DOCUMENT';");
while(result.next()) {
String column = result.getString(1);
columns.add(column);
}
This note that code is somewhat simplified and you should use prepared statements if anything in this query will be inserted from data that user or any other system entered.
Use DB.getConnection().prepareStatement() to get PreparedStatement instance.
String link = "http://hosted.ap.org";
I want to find whether the given url is already existing in the SQL DB under the table name "urls". If the given url is not found in that table i need to insert it in to that table.
As I am a beginner in Java, I cannot really reach the exact code.
Please advise on this regard on how to search the url in the table.
I am done with the SQL Connection using the java code. Please advise me on the searching and inserting part alone as explained above.
PreparedStatement insert = connectin.preparedStateme("insert into urls(url) vlaues(?)");
PreparedStatement search = connectin.preparedStateme("select * from urls where url = ?");
search.setString(1, <your url value to search>);
ResultSet rs = search.executeQuery();
if (!rs.hasNext()) {
insert.setString(1, <your url value to insert>);
insert.executeUpdate();
}
//finally close your statements and connection
...
i assumed that you only have one field your table and field name is url. if you have more fields you need to add them in insert query.
You need to distinguish between two completely separate things: SQL (Structured Query Language) is the language which you use to communicate with the DB. JDBC (Java DataBase Connectivity) is a Java API which enables you to execute SQL language using Java code.
To get data from DB, you usually use the SQL SELECT statement. To insert data in a DB, you usually use the SQL INSERT INTO statement
To prepare a SQL statement in Java, you usually use Connection#prepareStatement(). To execute a SQL SELECT statement in Java, you should use PreparedStatement#executeQuery(). It returns a ResultSet with the query results. To execute a SQL INSERT statement in Java, you should use PreparedStatement#executeUpdate().
See also:
SQL tutorial
JDBC tutorial