I can't open my mysql connection at run method inside timertask class. It throws an exception. When I trying to run this class in my mainclass with a timer.scheduleAtFixedRate(backgroundexecution, 0, 5000); method, It is not working. Anyone have any idea about how I can solve this problem?
#Override
public void run() {//here is my run method
backgroundtask obj = new backgroundtask();
try{
Statement statement = obj.openConnection(); //it throws an exception at this line
String mysqlcommand = "Select *from abc";
ResultSet sonuc = statement.executeQuery(mysqlcommand);
while(sonuc.next()){
if(search.contentEquals(sonuc.getString("ssa"))){
System.out.println(sonuc.getString(2));
}
}
statement.close();
}catch(Exception ex) {
System.out.println("fail");
}
}
You need to add this line before you attempt to carry out a db query (it loads the database drivers class);
Class.forName("com.mysql.jdbc.Driver");
If your using a different db driver the string may be different. Also ensure jdbc is in your classpath.
Related
My original CRUD Method generates a Prepared Statement and sets the strings based on the parameters given.
public class StatementUtility {
...
public static PreparedStatement getFoo(String bar, Connection conn) {
String query = "SELECT Foo FROM BarTable WHERE Bar = ?";
PreparedStatement pstmt = null;
try {
pstmt = conn.prepareStatement(query);
pstmt.setString(1, bar);
}
catch (SQLException e) {
..
}
return pstmt;
}
...
}
In this Statement the Database which I use is set. I created however a TestDB within my MySQL Server where I would like to test a delete Method:
public static String deleteFoo(List<String> input) {
Connection conn = driver.connectCustomerDB(input);
try(PreparedStatement pstmt = StatementUtility.getFoo(String someString, conn)) {
...
}
}
Here is my Test so far
#RunWith(PowerMockRunner.class)
#PrepareForTest(StatementUtility.class)
public class DBConnectionBTBAdminTest {
#Test
public void deleteTest() {
List<String> testInput = new ArrayList<>();
testInput.add("hello");
testInput.add("World");
Driver driver = new Driver();
Connection conn = driver.connectCustomerDB(testInput);
String query = "FooBarFooBarFooBarFooBarFooBarFooBarFooBarFooBar";
try {
//try mocking the Method within
BDDMockito.given(StatementUtility.getFoo(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), any(Connection.class))).willReturn(conn.prepareStatement(stringBuilder.toString()));
//call the method I want to test
SomeClass.deleteCategory(testInput, emptyArray);
...
} catch (SQLException e) {
...
}
}
}
The error that I get is a Nullpointer Exception in the Method where I create the PreparedStatement originally, but that is not the point as I do not want to get into this Method at all, but stub it.
I also tried using Mockito instead of BDDMockito (see here: https://stackoverflow.com/a/21116014/8830232)
and using the real values instead of ArgumentMatchers.*
I also tried some other stuff like mocking the Connection
Currently I am using JUnit#4.12, Mockito#2.13.0, powermock#1.7.1
EDIT:
For #glytching answer to work I had to downgrade mockito from 2.x to 1.x. >Dont forget to adjust powermock dependencies in that case
In addition to #PrepareForTest(StatementUtility.class) (which tells PowerMock to prepare this class for testing) you have to enable static mocking for all methods of StatementUtility. You do this by invoking ...
PowerMockito.mockStatic(StatementUtility.class);
... in your test before you attempt to set any expectations on that mock.
For example:
#RunWith(PowerMockRunner.class)
#PrepareForTest(StatementUtility.class)
public class DBConnectionBTBAdminTest {
#Test
public void deleteTest() {
PowerMockito.mockStatic(StatementUtility.class);
List<String> testInput = new ArrayList<>();
testInput.add("hello");
testInput.add("World");
Driver driver = new Driver();
Connection conn = driver.connectCustomerDB(testInput);
String query = "FooBarFooBarFooBarFooBarFooBarFooBarFooBarFooBar";
try {
BDDMockito.given(StatementUtility.getFoo(...)).willReturn(...);
...
} catch (SQLException e) {
...
}
}
}
i have a java application which connects to mysql database using MYSQL connector. problem is when application started, MYSQL process list shows many connections than i requested in process list (attached image).
i have two threads running which connects to database within 5 seconds and 11 seconds. but, when i refresh mysql process list, it shows server's host ports are changing rapidely than threads are running. normally its changing 3-5 ports per second. can someone please guide me any optimizing issues or any changes to test with this?
thanks
P.S.
I have created a class which connects to DB at initialization and that class's object is in a places where needs DB connectivity. and that class having all methods which using to query from DB.
EDIT
my database connectivity class code is
public class Data{
static Connection con; //create connection
static Statement stmt; //create statement
static ResultSet rs; //create result set
static HostRead hr = new HostRead();
static int db_port = 3306;
static String db_root = "127.0.0.1";
static String db_name = "chsneranew";
static String db_user = "root";
static String db_pass = "";
/**Constructer method*/
public Data(){
this(db_root,db_port,db_name,db_user,db_pass);
if(getConnection()==null){
System.out.println("error in database connection");
}
else{
con = getConnection();
}
}
protected void finalize() throws Throwable {
try {
System.out.println("desctroyed");
con.close();
} finally {
super.finalize();
}
}
public static Connection getConnection(){
try{
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection conn = DriverManager.getConnection("jdbc:mysql://"+db_root+":"+db_port+"/"+db_name, db_user, db_pass);
stmt = conn.createStatement();
return conn;
}
catch(ClassNotFoundException er){
JOptionPane.showMessageDialog(null,"Error found ...\nDataBase Driver error (Invalid Drivers)\nUsers Cant login to system without database\n\nContact System Administrator","Error",JOptionPane.ERROR_MESSAGE);
return null;
}
catch(Exception er){
JOptionPane.showMessageDialog(null,"Error found ...\nDataBase Access error (Invalid Authentication)\nOr\nDataBase not found. Details are not be loaded \n\nUsers Cant login to system without database\n\nContact System Administrator","Error",JOptionPane.ERROR_MESSAGE);
return null;
}
}
public String getUserName(){
try{
Statement stmt2 = getConnection().createStatement();
ResultSet rss2;
String sql = "SELECT name FROM gen";
rss2 = stmt2.executeQuery(sql);
if(rss2.next()){
return rss2.getString("name");
}
}
catch(Exception er){
er.printStackTrace();
}
return null;
}
}
i am calling getUserName()method in my threads. using
Data d = new Data();
d.getUserName();
conn.close();
You need to close the connection, the connection is not closed that is why it is still there in the list. You need to Connection conn above so that it may be visible to rest of the code.
You are calling the getConnection() method three times when you want to read the data via the getUserName() method. Two times in the constructor when your constructor of the Data class is called (one for the if(...) check, one for the con = getConnection() line) and one time when you actually want to read the data at the getConnection().createStatement() line. So you have three connections to the database, and that is just the getUserName method...
Rewrite your code that only one connection is established and this connection is reused for any further execution.
I want to populate a JComboBox with a database column (SQLite).
My database connection is setup through a class called DatabaseConnection setup in anther package.
Here is how it looks like
import java.sql.*;
import javax.swing.JOptionPane;
public class DatabaseConnection {
Connection conn = null;
public static Connection ConnectDB() {
try {
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite:database.db");
JOptionPane.showMessageDialog(null, "Connection Established");
conn.setAutoCommit(false);
return conn;
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
return null;
}
}
}
In my JFrame class I am creating following method, which according to a youtube tutorial should work
public void PopulateJCB()
{
String queryString = "SELECT DISTINCT [Account Name] FROM main ORDER BY [Account Name]";
try
{
Connection statJCBaccountname = DatabaseConnection.ConnectDB();
Statement stmt = statJCBaccountname.createStatement();
ResultSet rsJCBaccountname = stmt.executeQuery(queryString);
while (rsJCBaccountname.next())
{
comboAccountName.addItem(rsJCBaccountname.getString(1));
}
catch (SQLException e)
{
e.printStackTrace();
}
}
But it displays following errors at "comboAccountName.addItem(rsJCBaccountname.getString(1));"
Multiple markers at this line
- Type safety: The method addItem(Object) belongs to the raw type JComboBox. References to generic type JComboBox<E> should be
parameterized
- comboAccountName cannot be resolved
Please help!
I'm not really sure what you're expecting...
statJCBaccountname isn't even in the code example you've provided, but the compiler is saying that the variable is undefined
There is no such method as createStatement in the DatabaseConnection class
You need to resolve these issues before the program will compile. I'd suggest staying away from YouTube tutorials unless you know the author.
Take a look at JDBC Database Access for more details...
I have an aplication which create a number of query (update or insert) and then each query is executed.
The whole code is working fine but I've saw that my server IO latency is too much during this proccess.
The code execute a loop which is taking arround 1 minute.
Then what I wanted to do is write each query in memory instead to execute it, and then, once I have the whole list of query to execute, use "LOAD DATA LOCAL INFILE" from mysql, which will take less time.
My question is: How can I write all my query (String object) in a "File" or "any other container" in java to use it after the loop?.
#user3283548 This is my example code:
Class1:
import java.util.ArrayList;
public class Class1 {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ArrayList<String> Staff=new ArrayList<String>();
Staff.add("tom");
Staff.add("Laura");
Staff.add("Patricia");
for (int x = 0; x < Staff.size(); x++) {
System.out.println(Staff.get(x));
Class2 user = new Class2 (Staff.get(x));
user.checkUser();
}
}
}
Class2:
public class Class2 {
private String user;
public Class2(String user){
this.user=user;
}
public void checkUser() throws Exception{
if (user.equals("tom")){
String queryUser="update UsersT set userStatus='2' where UserName='"+user+"';";
Class3 updateUser = new Class3(queryUser);
updateUser.UpdateQuery();;
}else{
String queryUser="Insert into UsersT (UserName,userStatus)Values('"+user+"','1');";
Class3 updateUser = new Class3(queryUser);
updateUser.InsertQuery();
System.out.println(user+" is not ton doing new insert");
}
}
}
Class3:
public class Class3 {
public String Query;
public Class3(String Query){
this.Query = Query;
}
public void UpdateQuery() throws Exception{
/*// Accessing Driver From Jar File
Class.forName("com.mysql.jdbc.Driver");
//DB Connection
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/default","root","1234567");
String sql =Query;
PreparedStatement pst = con.prepareStatement(sql);*/
System.out.println(Query); //Just to test
//pst.execute();
}
public void InsertQuery() throws Exception{
/*// Accessing Driver From Jar File
Class.forName("com.mysql.jdbc.Driver");
//DB Connection
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/default","root","1234567");
String sql =Query;
PreparedStatement pst = con.prepareStatement(sql);*/
System.out.println(Query); //Just to test
//pst.execute();
}
}
Then, what I wanted to do is create an ArraList in Class1 and use it in Class3 to collect all the queries which has to be executed.
The idea is to execute the list of queries in one time, once the main process is finished, istead to do it for each element within in loop of the Class1. I wanted to do it, because I think it will be take less resource IO from the server HD
Your loop is probably too slow because you're building up Strings using String
I'd hazard a guess you're doing things like
String query = "SELECT * FROM " + variablea + " WHERE + variableb + " = " ...
If you're doing a lot of string concatenation then use StringBuilder as every time you change a string it is actually re-created which is expensive. Simply changing your code to use StringBuilder instead of string will probably cut your loop executed time to a couple of MS. Simply call .toString() method of StringBuilder obj to get the string.
Storing objects
If you want to store anything for later use you should store it in a Collection. If you want a a key-value relationship then use a Map (HashMap would suit you fine). If you just want the values use an List (ArrayList is most popular).
So for example if I wanted to store query strings for later use I would...
Construct the string using StringBuilder.
Put the string (by calling .toString() into a HashMap
Get the query string from the HashMap...
You should never store things on disk if you don't need them to be persistent over application restarts and even then I'd store them in a database not in a file.
Hope this helps.
Thanks
David
EDIT: UPDATE BASED ON YOU POSTING YOUR CODE:
OK this needs some major re-factoring!
I've kept it really simple because I don't have a lot of time to re-write comprehensively.
I've commented where I have made corrections.
Your major issue here is creating objects in loops. You should just create the object once as creating objects is expensive.
I've also corrected other coding issues and replaced the for loop as you shouldn't be writing it like that.I've also renamed the classes to something useful.
I've not tested this so you may need to do some work to get it to work. But this should be a lot faster.
OLD CLASS 1
import java.util.ArrayList;
import java.util.List;
public class StaffChecker {
public static void main(String[] args) throws Exception {
// Creating objects is expensive, you should do this as little as possible
StaffCheckBO staffCheckBO = new StaffCheckBO();
// variables should be Camel Cased and describe what they hold
// Never start with ArrayList start with List you should specific the interface on the left side.
List<String> staffList = new ArrayList<String>();
staffList.add("tom");
staffList.add("Laura");
staffList.add("Patricia");
// use a foreach loop not a (int x = 0 ... ) This is the preffered method.
for (String staffMember : staffList) {
// You now dont need to use .get() you can access the current variable using staffMember
System.out.println(staffMember);
// Do the work
staffCheckBO.checkUser(staffMember);
}
}
}
OLD CLASS 2
/**
* Probably not really any need for this class but I'll assume further business logic may follow.
*/
public class StaffCheckBO {
// Again only create our DAO once...CREATING OBJECTS IS EXPENSIVE.
private StaffDAO staffDAO = new StaffDAO();
public void checkUser(String staffMember) throws Exception{
boolean staffExists = staffDAO.checkStaffExists(staffMember);
if(staffExists) {
System.out.println(staffMember +" is not in database, doing new insert.");
staffDAO.insertStaff(staffMember);
} else {
System.out.println(staffMember +" has been found in the database, updating user.");
staffDAO.updateStaff(staffMember);
}
}
}
OLD CLASS 3
import java.sql.*;
/**
* You will need to do some work to get this class to work fully and this is obviously basic but its to give you an idea.
*/
public class StaffDAO {
public boolean checkStaffExists(String staffName) {
boolean staffExists = false;
try {
String query = "SELECT * FROM STAFF_TABLE WHERE STAFF_NAME = ?";
PreparedStatement preparedStatement = getDBConnection().prepareStatement(query);
// Load your variables into the string in order to be safe against injection attacks.
preparedStatement.setString(1, staffName);
ResultSet resultSet = preparedStatement.executeQuery();
// If a record has been found the staff member is in the database. This obviously doesn't account for multiple staff members
if(resultSet.next()) {
staffExists = true;
}
} catch (SQLException e) {
System.out.println("SQL Exception in getStaff: " + e.getMessage());
}
return staffExists;
}
// Method names should be camel cased
public void updateStaff(String staffName) throws Exception {
try {
String query = "YOUR QUERY";
PreparedStatement preparedStatement = getDBConnection().prepareStatement(query);
// Load your variables into the string in order to be safe against injection attacks.
preparedStatement.setString(1, staffName);
ResultSet resultSet = preparedStatement.executeQuery();
} catch (SQLException e) {
System.out.println("SQL Exception in getStaff: " + e.getMessage());
}
}
public void insertStaff(String staffName) throws Exception {
try {
String query = "YOUR QUERY";
PreparedStatement preparedStatement = getDBConnection().prepareStatement(query);
// Load your variables into the string in order to be safe against injection attacks.
preparedStatement.setString(1, staffName);
ResultSet resultSet = preparedStatement.executeQuery();
} catch (SQLException e) {
System.out.println("SQL Exception in getStaff: " + e.getMessage());
}
}
/**
* You need to abstract the connection logic away so you avoid code reuse.
*
* #return
*/
private Connection getDBConnection() {
Connection connection = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/default", "root", "1234567");
} catch (ClassNotFoundException e) {
System.out.println("Could not find class. DB Connection could not be created: " + e.getMessage());
} catch (SQLException e) {
System.out.println("SQL Exception. " + e.getMessage());
}
return connection;
}
}
Is it possible to store a database connection as a separate class, then call the database objects from a main code? ie;
public class main{
public static void main{
try{
Class.forName("com.jdbc.driver");
Database to = new Database(1,"SERVER1","DATABASE");
Database from = new Database(2,"SERVER2","DATABASE");
String QueryStr = String.format("SELECT * FROM TABLE WHERE Id = %i", to.id)
to.results = sql.executeQuery(QueryStr);
while (to.results.next()) {
String QueryStr = String.format("INSERT INTO Table (A,B) VALUES (%s,%s)",to.results.getString(1),to.results.getString(2));
from.sql.executeQuery("QueryStr");
}
to.connection.close()
from.connection.close()
} catch (Exception ex) {
ex.printStackTrace();
{ finally {
if (to.connection != null)
try {
to.connection.close();
} catch (SQLException x) {
}
if (from.connection != null)
try {
from.connection.close();
} catch (SQLException x) {
}
}
}
public static class Database {
public int id;
public String server;
public String database;
public Connection connection;
public ResultSet results;
public Statement sql;
public Database(int _id, String _server, String _database) {
id = _id;
server = _server;
database = _database;
String connectStr = String.format("jdbc:driver://SERVER=%s;port=6322;DATABASE=%s",server,database);
connection = DriverManager.getConnection(connectStr);
sql = connection.createStatement;
}
}
}
I keep getting a "Connection object is closed" error when I call to.results = sql.executeQuery("SELECT * FROM TABLE"); like the connection closes as soon as the Database is done initializing.
The reason I ask is I have multiple databases that are all about the same that I am dumping into a master database. I thought it would be nice to setup a loop to go through each from database and insert into each to database using the same class. Is this not possible? Database will also contain more methods than shown as well. I am pretty new to java, so hopefully this makes sense...
Also, my code is probably riddled with syntax errors as is, so try not to focus on that.
Connection object is closed doesn't mean that the connection is closed, but that the object relative to the connection is closed (it could be a Statement or a ResultSet).
It's difficult to see from your example, since it has been trimmed/re-arranged, but it looks like you may be trying to use a ResultSet after having re-used its corresponding Statement. See 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.
In your example, it may be because autoCommit is set to true by default. You can override this on the java.sql.Connection class. Better yet is to use a transaction framework if you're updating multiple tables.