How to reuse connect function database java mysqlite? - java

I'm writing an application with java form and sqlite and I have a function to connect to database and get data like this:
public ResultSet getResultSet(String query) {
Connection conn = null;
ResultSet rs = null;
try {
// create a database conn
conn = DriverManager.getConnection("jdbc:sqlite:C:\\Users\\nguye_000\\Desktop\\qlct.db");
Statement statement = conn.createStatement();
statement.setQueryTimeout(30);
rs = statement.executeQuery(query);
return rs;
}
catch(SQLException e) {
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
}
finally {
try {
if(conn != null)
conn.close();
}
catch(SQLException e) {
// conn close failed.
System.err.println(e);
}
}
return rs;
}
Why when I call it in main function I get an error?
Database db = new Database();
ResultSet rs = db.getResultSet("SELECT * FROM qlct_options");
while(rs.next()) {
// read the result set
System.out.println("id = " + rs.getInt("option_id"));
System.out.println("name = " + rs.getString("option_key"));
System.out.println("value = " + rs.getString("option_value"));
}
id = 0
name = null
value = null
Exception in thread "main" java.sql.SQLException: [SQLITE_MISUSE] Library used incorrectly (out of memory)
at org.sqlite.core.DB.newSQLException(DB.java:890)
at org.sqlite.core.DB.newSQLException(DB.java:901)
at org.sqlite.core.DB.throwex(DB.java:868)
at org.sqlite.jdbc3.JDBC3ResultSet.next(JDBC3ResultSet.java:83)
at qlct.Qlct.main(Qlct.java:18)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
I want to everytime run a any query I can use getResultSet() function and pass query into it. I can't write a code like this http://chuoidichvu.com/downloads/Database.java, each time I need to write a query I do try{} catch{}, final{}. It's hard!

You return a ResultSet from your function after having close the connection (in the finally part of the outer try).
This causes an error, since you can scan the ResultSet only while the Statement and the Connection are still open.
To obtain your objective (“reuse connect function database java mysqlite”) you have to “rearrange” the abstraction that you are trying to define. For instance you could pass to your method a lambda expression (if you are using Java 8) that processes the result inside it.

Related

How to ignore query error and continue to execute second query?

I am developing an app that retrieve data from SQL Server.
I have to execute 2 queries together to come out with result. The problem is the first query is a Stored Procedure that contain (INSERT INTO... EXEC sp_....), this query is shows error in server side but it is executed well, then the second query will read from the inserted result into it sue the first query.
The problem is, when the fist query execute, it make the App goes to Exception part which do not allow the second query to be executed.
Is there any way to make Android Studio ignore the error and execute the second query?
protected String doInBackground(String... params) {
try {
Connection con = connectionClass.CONN();
if (con == null) {
message = "Error in connection with SQL server";
} else {
String query = "EXEC [dbo].[sp_ReminderTimeToArriveTheBus]" +
" '"+str_wilayat+"','"+str_city+"', '"+str_station+"', '"+str_distnation+"', '"+currentTime+"'";
PreparedStatement stmt = con.prepareStatement(query);
ResultSet rs = stmt.executeQuery();
rs.next();
String query2 = "SELECT OutputValue FROM [dbo].[FinalResultTable]";
PreparedStatement stmt2 = con.prepareStatement(query2);
ResultSet rs2 = stmt2.executeQuery();
str_min = rs2.getString("OutputValue");
if(rs2.next())
{
message = "O.K.";
str_min = rs2.getString("OutputValue");
isSuccess=true;
}
else{
isSuccess=false;
}
stmt.close();
rs.close();
stmt2.close();
rs2.close();
}
}
catch (Exception ex)
{
message = "Error";
}
return message;
}
If i am understanding the question correctly is query2 should be executed in every situation. You can try running this query in place of "Return message"after catch clause.
I solve the issue through re-write the first query (the stored procedure) and it is executing without errors now.
:)

How to save the results of a query on variables for each field on Java?

I need to accomplish the following:
1.- Save on different variables each field of a query result (Oracle DB).
The query result could be 1 o more rows (5 average).
2.- Invoke a WebService for each row.
4.- Wait for the WebService answer and then repeat the process.
I think that saving the result of 1 row and then invoke the WebService it easy but the problem is when the query result throws more than 1 row.
How can I do this? Is Arraylist the answer?
EDIT: I am using the following code. How can I print the arraylist to see if the connection is working?
If I run this i get:
com.packagename.SomeBean#1d251891
com.packagename.SomeBean#48140564
com.packagename.SomeBean#58ceff1
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
List<SomeBean> v = new ArrayList<SomeBean>();
String query = "select * from table where ROWNUM BETWEEN 1 and 3";
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection("jdbc:oracle:thin:user/pass#localhost:port:SID");
stmt = con.createStatement();
rs = stmt.executeQuery(query);
while( rs.next() ){
SomeBean n = new SomeBean();
n.setColumn1(rs.getInt("column1"));
n.setColumn2(rs.getString("column2"));
n.setColumn3(rs.getString("column3"));
n.setColumn4(rs.getInt("column4"));
n.setColumn5(rs.getString("column5"));
n.setColumn6(rs.getString("column6"));
n.setColumn7(rs.getString("column7"));
...
v.add(n);
}
for(SomeBean s : v){
System.out.println(s);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
stmt.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
Answering to your question is quite difficoult.
But I can give you some hints.
Your startpoint is JDBC.
The Java Database Connectivity (JDBC)
The Java Database Connectivity (JDBC) API is the industry standard for database-independent connectivity between the Java programming language and a wide range of databases SQL databases and other tabular data sources, such as spreadsheets or flat files. The JDBC API provides a call-level API for SQL-based database access.
The Java Database Connectivity (JDBC)
Once you are able to establish a connection to the DB, this snippet can help you answering to your question.
// start connection
List<SomeBean> v = new ArrayList<SomeBean>();
Statement st;
try
{
st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
while( rs.next() ){
SomeBean n = new SomeBean();
n.setFirstField(rs.getInt("firstfield"));
n.setSecondField(rs.getString("secondfield"));
...
...
v.add(n);
}
}
catch (SQLException e)
{
e.printStackTrace();
}
// close connection
Once you have your collection of beans, just write a for loop that calls the webservice one time for each bean.
for(SomeBean s : v){
callToYouWS(s);
}

tomcat jdbc pool timeout not working

I am developing high-load application using tomcat jdbc connection pool and Oracle database. It is very important to ensure my app to have very small DB query timeouts (no longer than 3 seconds) to prevent long-running queries or database slowness from blocking all my application. To simulate long-running queries I have put the DB in QUIESCE state using ALTER SYSTEM QUIESCE RESTRICTED statement.
But it looks like the timeout values have no impact - when i begin to test my application, it hangs...
Here is my jdbc pool configuration:
String connprops = "oracle.net.CONNECT_TIMEOUT=3000;oracle.jdbc.ReadTimeout=3000;"
+ "oracle.net.READ_TIMEOUT=3000";
pp.setConnectionProperties(connprops);
pp.setDriverClassName("oracle.jdbc.OracleDriver");
pp.setTestOnBorrow(true);
pp.setTestOnConnect(true);
pp.setTestOnReturn(true);
pp.setTestWhileIdle(true);
pp.setMaxWait(2000);
pp.setMinEvictableIdleTimeMillis(20000);
pp.setTimeBetweenEvictionRunsMillis(20000);
pp.setValidationInterval(3000);
pp.setValidationQuery("SELECT 1 FROM DUAL");
pp.setMaxAge(3000);
pp.setRemoveAbandoned(true);
pp.setRemoveAbandonedTimeout(3);
pp.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.QueryTimeoutInterceptor(queryTimeout=3)");
dataSource = new DataSource();
dataSource.setPoolProperties(pp);
That's how i work with connections (pretty simple):
Connection conn = dataSource.getConnection();
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery(/*some select query*/);
if (rs.next()) {
result = rs.getInt(1);
/*process the result*/
}
rs.close();
stmt.close();
conn.close();
}
catch(Exception e) {
logger.error("Exception: " + e.getMessage(), e);
}finally {
if (conn != null) {
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
conn.close();
}
}
Any ideas? Thanks in advance!
Try to use this config:
String connprops = "oracle.net.CONNECT_TIMEOUT=\"3000\";oracle.jdbc.ReadTimeout=\"3000\";"
+ "oracle.net.READ_TIMEOUT=\"3000\"";
All non-string values are ignored by java.util.Properties.java:
public String getProperty(String key) {
Object oval = super.get(key);
String sval = (oval instanceof String) ? (String)oval : null; // <- !!!!
return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;
}
You should probably also use java.sql.Statement's query timeout:
stmt.setQueryTimeout(3); // int seconds

How to check if a particular database in MySQL already exists using Java

I am new to JDBC, and I wanted to find out if there is a way to check if a particular database already exists in MySQL.
Let's say I wanted to create a database named students. If the students database is already created in MySQL an error message in Eclipse would state that this students database already exists. However, I wanted to create a Boolean method to check if students database already exists. If it exists then the Boolean method would return false, otherwise if it’s true, then I can create the students database.
How do I do these in Java? Are there any methods in JDBC that does this or do I need to code it from scratch?
I followed mguymons suggestion and this is what I came up:
public boolean checkDBExists(String dbName) {
try {
Class.forName(JDBCDriver); // Register JDBC driver
System.out.println("Creating a connection...");
conn = DriverManager.getConnection(DBURL, USER, PASS); // Open a connection
ResultSet resultSet = conn.getMetaData().getCatalogs();
while (resultSet.next()) {
String databaseName = resultSet.getString(1);
if(databaseName.equals(dbName)) {
return true;
}
}
resultSet.close();
}
catch(Exception e) {
e.printStackTrace();
}
return false;
}
You can get that information from a JDBC Connection using getCatalogs. Here is an example of getting the Catalogs, aka Database names
// Connection connection = <your java.sql.Connection>
ResultSet resultSet = connection.getMetaData().getCatalogs();
// Iterate each catalog in the ResultSet
while (resultSet.next()) {
// Get the database name, which is at position 1
String databaseName = resultSet.getString(1);
}
resultSet.close();
show databases like 'students'
If you get a row back, it exists.
In newer versions of MySQL (5 and above) run this query:
SELECT COUNT(*)
FROM information_schema.tables
WHERE table_schema = '[database name]'
AND table_name = '[table name]';
If the result is 1 it exists.
In Java JDBC that would look something like this:
// Create connection and statement
String query = "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema'[database name]' AND table_name = '[table name]'";
ResultSet rs = stmt.executeQuery(query);
rs.next();
boolean exists = rs.getInt("COUNT(*)") > 0;
// Close connection, statement, and result set.
return exists;
You're doing it back to front. The correct technique is to try to create it and catch the exception. The way you want to do it is subject to timing-window problems: it wasn't there when you tested, but it was there when you tried to create it. And you still have to catch the exception anyway.
You should break out of the loop once the target database is found. Otherwise, it's only sensible if your target search is the last in the result set.
public boolean checkDBExists(String dbName) {
try {
Class.forName(JDBCDriver); // Register JDBC Driver
System.out.println("Creating a connection...");
conn = DriverManager.getConnection(DBURL, USER, PASS); // Open a connection
ResultSet resultSet = conn.getMetaData().getCatalogs();
while (resultSet.next()) {
String databaseName = resultSet.getString(1);
if(databaseName.equals(dbName)) {
return true;
break;
}
}
resultSet.close();
}
catch(Exception e) {
e.printStackTrace();
}
return false;
}

Operation not allowed after ResultSet closed

Allright been trying to figure this out the last 2 days.
Statement statement = con.createStatement();
String query = "SELECT * FROM sell";
ResultSet rs = query(query);
while (rs.next()){//<--- I get there operation error here
This is the query method.
public static ResultSet query(String s) throws SQLException {
try {
if (s.toLowerCase().startsWith("select")) {
if(stm == null) {
createConnection();
}
ResultSet rs = stm.executeQuery(s);
return rs;
} else {
if(stm == null) {
createConnection();
}
stm.executeUpdate(s);
}
return null;
} catch (Exception e) {
e.printStackTrace();
con = null;
stm = null;
}
return null;
}
How can I fix this error?
It's hard to be sure just from the code you've posted, but I suspect that the ResultSet is inadvertently getting closed (or stm is getting reused) inside the body of the while loop. This would trigger the exception at the start of the following iteration.
Additionally, you need to make sure there are no other threads in your application that could potentially be using the same DB connection or stm object.
IMHO, you should do everything you need with your ResultSet before you close your connection.
there are few things you need to fix. Opening a connection, running a query to get the rs, closing it, and closing the connection all should be done in the same function scope as far as possible. from your code, you seem to use the "con" variable as a global variable, which could potentially cause a problem. you are not closing the stm object. or the rs object. this code does not run for too long, even if it has no errors. Your code should be like this:
if (stringUtils.isBlank(sql)){
throw new IllegalArgumentsException ("SQL statement is required");
}
Connection con = null;
PreparedStatement ps =null;
Resultset rs = null;
try{
con = getConnection();
ps = con.preparestatement(sql);
rs = ps.executeQuery();
processResults(rs);
close(rs);
close(ps);
close(con);
}catch (Execption e){
log.Exception ("Error in: {}", sql, e);
throw new RuntimeException (e);
}finally{
close(rs);
close(ps);
close(con);
}
use another Statement object in inner loop
Like
Statement st,st1;
st=con.createStatement();
st1=con.createStatement();
//in Inner loop
while(<<your code>>)
{
st1.executeQuery(<<your query>>);
}
I know this is a few years late, but I've found that synchronizing the db methods usually get rid of this problem.

Categories

Resources