my code show this next warning:
QSqlDatabasePrivate::removeDatabase: connection ‘qt_sql_default_connection’
is still in use, all queries will cease to work
This is my code the connection with data base is fine:
QSqlDatabase database::db()
{
return m_db;
}
bool database::connect()
{
m_db = QSqlDatabase::addDatabase("QMYSQL");
m_db.setDatabaseName("aaaa");
m_db.setHostName("192.168.xxx.xxx");
m_db.setUserName("xx");
m_db.setPassword("xxxx");
m_db.setPort(1234);
return m_db.open();
}
void database::close()
{
QString connection;
connection = m_db.connectionName();
m_db.close();
m_db.removeDatabase(connection);
}
m_db is define as:
QSqlDatabase m_db;
and my test is:
database db;
qDebug() << "CONNECT: " << db.connect();
db.close();
How can I fix it?
Thanks you very much.
After you closed it, m_db still holds a reference to the database you configured in connect().
You can reset m_db by assigning a default constructed QSqlDatabase:
void database::close()
{
QString connection;
connection = m_db.connectionName();
m_db.close();
m_db = QSqlDatabase();
m_db.removeDatabase(connection);
}
void database::close()
{
QString connection;
connection = m_db.connectionName();
m_db = QSQlDatabase();
//m_db.close();
m_db.removeDatabase(connection);
}
try this it will work..
Adding an additional scope does the same trick:
QString connectionName;
bool ok = false;
{
QSqlDatabase db = QSqlDatabase::addDatabase(databaseType);
connectionName = db.connectionName();
db.setHostName(hostname);
db.setDatabaseName(databaseName);
db.setUserName(userName);
db.setPassword(password);
ok = db.open();
db.close();
}
QSqlDatabase::removeDatabase(connectionName);
return ok;
Related
I'm trying to connect to a remote MySQL database directly from my arduino to do some telemetry on some hardware. However the code gets stuck while connecting to the db, and gives always the answer "no db found". Where am I wrong?
I'm sure that I'm correct with the user/pass thing, however I really can't figure out why it won't connect to the db to execute the query.
#include <ESP8266WiFi.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
char ssid[] = "mywifissid";
char pass[] = "mywifipass";
char mysqlUser[] = "mysqluser";
char mysqlPass[] = "mysqlpassword";
char id[] = "someidforthearduino";
WiFiClient wifiClient;
MySQL_Connection mysqlConnection ((Client *)&wifiClient);
IPAddress mysqlServer (/*some kind of address for the mySQL server*/);
bool is_Sending = false;
char queryToExecute[128];
char queryUpdate[] = "somequery";
int nPresses = 0;
void setup() {
Serial.begin(115200);
Serial.println("Inizializzazione pin in corso...");
pinMode(D4, INPUT_PULLUP);
Serial.println("Connessione alla rete in corso...");
WiFi.disconnect();
WiFi.begin(ssid,pass);
while(WiFi.status() != WL_CONNECTED) {
delay(200);
Serial.print(".");
}
Serial.println("");
Serial.print("Connesso con ip ");
Serial.println(WiFi.localIP());
Serial.println("Inizializzazione completata");
}
void loop() {
if (!digitalRead(D4) && !is_Sending) {
is_Sending = true;
nPresses++;
Serial.println("Rilevata pressione tasto. Connessione in corso...");
if (mysqlConnection.connect(mysqlServer,3306,mysqlUser,mysqlPass)) {
Serial.println("");
Serial.println("Connesso. Inserimento dato...");
sprintf(queryToExecute, queryUpdate, nPresses, id);
MySQL_Cursor *c = new MySQL_Cursor(&mysqlConnection);
c->execute(queryToExecute);
delete c;
Serial.println("Aggiornamento effettuato!");
} else {
Serial.println("No db found.");
}
mysqlConnection.close();
is_Sending = false;
}
}
I figured it out. The code is correct, I just typed the wrong IP for the MySQL server! I discovered it by opening the command prompt and pinging the host name;
String url = "jdbc:mysql://localhost:3306/mysql";
String user = "root";
String pass = "root1";
try {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection(url, user, pass);
System.out.println("Connected to database");
} catch (Exception e) {
System.out.println(e);
System.out.println("Could not connect to database");
}
Password should be "root". The program does not display the message in the catch block and stops working. Can anyone tell me what happens?
[UPDATE]
I apologise I asked a bad question. The problem is already solved, Thanks. This helps to properly check whether the connection exists.
if (conn1 != null) {
System.out.println("Connected to the database test1");
}
There are three different ways to connect to SQL data base as shown in below code
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class MySQLConnectExample {
public static void main(String[] args) {
// creates three different Connection objects
Connection conn1 = null;
Connection conn2 = null;
Connection conn3 = null;
try {
// connect way #1
String url1 = "jdbc:mysql://localhost:3306/test1";
String user = "root";
String password = "secret";
conn1 = DriverManager.getConnection(url1, user, password);
if (conn1 != null) {
System.out.println("Connected to the database test1");
}
// connect way #2
String url2 = "jdbc:mysql://localhost:3306/test2?user=root&password=secret";
conn2 = DriverManager.getConnection(url2);
if (conn2 != null) {
System.out.println("Connected to the database test2");
}
// connect way #3
String url3 = "jdbc:mysql://localhost:3306/test3";
Properties info = new Properties();
info.put("user", "root");
info.put("password", "secret");
conn3 = DriverManager.getConnection(url3, info);
if (conn3 != null) {
System.out.println("Connected to the database test3");
}
} catch (SQLException ex) {
System.out.println("An error occurred. Maybe user/password is invalid");
ex.printStackTrace();
}
}
}
From groovy script in SoapUI I need to connect to a mysql database to perform some queries. The problem is that due to security reasons no external access is possible.
Therefore it is required to get an ssh access (like a tunnel) and invoke mysql locally.
Initially I was reading the below project properties and then connect to mysql:
ServerUrl=jdbc:mysql://10.255.255.122:3306/db
ServerDbUser=user
ServerDbPwd=password
ServerDriver=com.mysql.jdbc.Driver
def url=testRunner.testCase.testSuite.project.getPropertyValue("ServerUrl")
def usr=testRunner.testCase.testSuite.project.getPropertyValue("ServerDbUser")
def pwd=testRunner.testCase.testSuite.project.getPropertyValue("ServerDbPwd")
def driver=testRunner.testCase.testSuite.project.getPropertyValue("ServerDriver")
com.eviware.soapui.support.GroovyUtils.registerJdbcDriver(driver)
sqlServer = Sql.newInstance(url, usr, pwd, driver)`
But this didn't work so now it is required to establish first a ssh connection to the server with the IP 10.255.255.122 and then open the mysql connection locally. So I guess the Server Url will change to:
ServerUrl=jdbc:mysql://127.0.0.1:3306/db
But I don't know how to set first the ssh connection to the server.
Can someone help me with this?
Thanks.
Have a look at http://forum.soapui.org/viewtopic.php?t=15400 and connect to remote mysql database through ssh using java
It will give you an idea about implementing it in soapUI.
Below is the code by Ripon Al Wasim which is available as an answer at the stackoverflow link mentioned above
package mypackage;
import java.sql.*;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class UpdateMySqlDatabase {
static int lport;
static String rhost;
static int rport;
public static void go(){
String user = "ripon";
String password = "wasim";
String host = "myhost.ripon.wasim";
int port=22;
try
{
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, port);
lport = 4321;
rhost = "localhost";
rport = 3306;
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
System.out.println("Establishing Connection...");
session.connect();
int assinged_port=session.setPortForwardingL(lport, rhost, rport);
System.out.println("localhost:"+assinged_port+" -> "+rhost+":"+rport);
}
catch(Exception e){System.err.print(e);}
}
public static void main(String[] args) {
try{
go();
} catch(Exception ex){
ex.printStackTrace();
}
System.out.println("An example for updating a Row from Mysql Database!");
Connection con = null;
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://" + rhost +":" + lport + "/";
String db = "testDB";
String dbUser = "wasim";
String dbPasswd = "riponalwasim123";
try{
Class.forName(driver);
con = DriverManager.getConnection(url+db, dbUser, dbPasswd);
try{
Statement st = con.createStatement();
String sql = "UPDATE MyTableName " +
"SET email = 'ripon.wasim#smile.com' WHERE email='peace#happy.com'";
int update = st.executeUpdate(sql);
if(update >= 1){
System.out.println("Row is updated.");
}
else{
System.out.println("Row is not updated.");
}
}
catch (SQLException s){
System.out.println("SQL statement is not executed!");
}
}
catch (Exception e){
e.printStackTrace();
}
}
}
hi i am doing an jsp project. and i deploy my project on apache tomcat. i use mysql as databese.
when i deploy project on remote server it is run good. but after some hours it gives me sql error. then i go back my apache server and start projecet again it run and after some hours it gives me same sql error again. i dont know the problem. is that caused from my java connection code or it is about mysql server. can some one tell me why it gives me sql error.?
public class ConnectionManager {
private String className = "com.mysql.jdbc.Driver";
private String userName ="username";
private String password = "password";
private String url = "jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf-8";
/**
* #uml.property name="connectionInstance"
* #uml.associationEnd
*/
private static ConnectionManager connectionInstance = null;
public ConnectionManager(){
}
public static synchronized ConnectionManager getInstance() {
if(connectionInstance == null) {
connectionInstance = new ConnectionManager();
}
return connectionInstance;
}
public Connection getConnection(){
Connection conn = null;
try {
Class.forName(className);
conn = DriverManager.getConnection (url, userName, password);
System.out.println("Connection Established");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
MySQL has a default connection timeout of 8 hours. So this means that you've kept a SQL connection open for too long. Your code suggests that you're creating only one connection on application's startup and reusing it application wide. This is very bad. This is not threadsafe.
You need to change your code so that you're not declaring and storing the SQL Connection as a static or instance variable anywhere in your code. Instead, it should be declared, created and closed within the shortest possible scope. Preferably within the very same method block as where you're executing the SQL query.
Here's a minor rewrite of your ConnectionManager which does the job properly:
public class ConnectionManager {
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String USERNAME ="username";
private static final String PASSWORD = "password";
private static final String URL = "jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf-8";
static {
try {
Class.forName(DRIVER);
}
catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(DRIVER + " missing in classpath!", e);
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USERNAME, PASSWORD);
}
}
Use it as follows:
public class SomeDAO {
public SomeEntity find(Long id) throws SQLException {
Connection connection = null;
// ...
try {
connection = ConnectionManager.getConnection();
// ...
}
finally {
// ...
if (connection != null) try { connection.close(); } catch(SQLException ignore) {}
}
return someEntity;
}
To improve connecting performance, use a connection pool instead of DriverManager.
See also:
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
Are you closing connections properly after using them.
I am trying to determine if I am actually using JDBC connection pooling. After doing some research, the implementation almost seems too easy. Easier than a regular connection in fact so i'd like to verify.
Here is my connection class:
public class DatabaseConnection {
Connection conn = null;
public Connection getConnection() {
BasicDataSource bds = new BasicDataSource();
bds.setDriverClassName("com.mysql.jdbc.Driver");
bds.setUrl("jdbc:mysql://localhost:3306/data");
bds.setUsername("USERNAME");
bds.setPassword("PASSWORD");
try{
System.out.println("Attempting Database Connection");
conn = bds.getConnection();
System.out.println("Connected Successfully");
}catch(SQLException e){
System.out.println("Caught SQL Exception: " + e);
}
return conn;
}
public void closeConnection() throws SQLException {
conn.close();
}
}
Is this true connection pooling? I am using the connection in another class as so:
//Check data against database.
DatabaseConnection dbConn = new DatabaseConnection();
Connection conn;
ResultSet rs;
PreparedStatement prepStmt;
//Query database and check username/pass against table.
try{
conn = dbConn.getConnection();
String sql = "SELECT * FROM users WHERE username=? AND password=?";
prepStmt = conn.prepareStatement(sql);
prepStmt.setString(1, user.getUsername());
prepStmt.setString(2, user.getPassword());
rs = prepStmt.executeQuery();
if(rs.next()){ //Found Match.
do{
out.println("UserName = " + rs.getObject("username") + " Password = " + rs.getObject("password"));
out.println("<br>");
} while(rs.next());
} else {
out.println("Sorry, you are not in my database."); //No Match.
}
dbConn.closeConnection(); //Close db connection.
}catch(SQLException e){
System.out.println("Caught SQL Exception: " + e);
}
Assuming that it's the BasicDataSource is from DBCP, then yes, you are using a connection pool. However, you're recreating another connection pool on every connection acquirement. You are not really pooling connections from the same pool. You need to create the connection pool only once on application's startup and get every connection from it. You should also not hold the connection as an instance variable. You should also close the connection, statement and resultset to ensure that the resources are properly closed, also in case of exceptions. Java 7's try-with-resources statement is helpful in this, it will auto-close the resources when the try block is finished.
Here's a minor rewrite:
public final class Database {
private static final BasicDataSource dataSource = new BasicDataSource();
static {
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/data");
dataSource.setUsername("USERNAME");
dataSource.setPassword("PASSWORD");
}
private Database() {
//
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
(this can if necessary be refactored as an abstract factory to improve pluggability)
and
private static final String SQL_EXIST = "SELECT * FROM users WHERE username=? AND password=?";
public boolean exist(User user) throws SQLException {
boolean exist = false;
try (
Connection connection = Database.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL_EXIST);
) {
statement.setString(1, user.getUsername());
statement.setString(2, user.getPassword());
try (ResultSet resultSet = preparedStatement.executeQuery()) {
exist = resultSet.next();
}
}
return exist;
}
which is to be used as follows:
try {
if (!userDAO.exist(username, password)) {
request.setAttribute("message", "Unknown login. Try again.");
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
} else {
request.getSession().setAttribute("user", username);
response.sendRedirect("userhome");
}
} catch (SQLException e) {
throw new ServletException("DB error", e);
}
In a real Java EE environement you should however delegate the creation of the DataSource to the container / application server and obtain it from JNDI. In case of Tomcat, see also for example this document: http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html
Doesn't seem like it's pooled. You should store the DataSource in DatabaseConnection instead of creating a new one with each getConnection() call. getConnection() should return datasource.getConnection().
Looks like a DBCP usage. If so, then yes. It's already pooled. And here is the default pool property value of the DBCP.
/**
* The default cap on the number of "sleeping" instances in the pool.
* #see #getMaxIdle
* #see #setMaxIdle
*/
public static final int DEFAULT_MAX_IDLE = 8;
/**
* The default minimum number of "sleeping" instances in the pool
* before before the evictor thread (if active) spawns new objects.
* #see #getMinIdle
* #see #setMinIdle
*/
public static final int DEFAULT_MIN_IDLE = 0;
/**
* The default cap on the total number of active instances from the pool.
* #see #getMaxActive
*/
public static final int DEFAULT_MAX_ACTIVE = 8;
As a follow up to BalusC's solution, below is an implementation that I can be used within an application that requires more than one connection, or in a common library that would not know the connection properties in advance...
import org.apache.commons.dbcp.BasicDataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.ConcurrentHashMap;
public final class Database {
private static final ConcurrentHashMap<String, BasicDataSource> dataSources = new ConcurrentHashMap();
private Database() {
//
}
public static Connection getConnection(String connectionString, String username, String password) throws SQLException {
BasicDataSource dataSource;
if (dataSources.containsKey(connectionString)) {
dataSource = dataSources.get(connectionString);
} else {
dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl(connectionString);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSources.put(connectionString, dataSource);
}
return dataSource.getConnection();
}
}