I need reading data from database(MySQL) and transfer to client.
Can i somehow transfer the Object of type TopickOfVote to the client or only through String?
Writer and reader:
writer = new PrintWriter(new OutputStreamWriter(clientAPP.getWriter()));
reader = new BufferedReader(new InputStreamReader(clientAPP.getReader()));
Server:
private void LoadOfTopics() throws SQLException {
resultSet = statement.executeQuery("SELECT * FROM kursach.TopicOfVote");
StringBuffer id;
StringBuffer topic;
while(resultSet.next()){
TopicOfVote topicOfVote = new TopicOfVote();
topicOfVote.setId(Integer.parseInt(resultSet.getString("idVote")));
topicOfVote.setTopic(resultSet.getString("topic"));
ResultSet ans = statement.executeQuery("SELECT * FROM kursach.Answers_vote WHERE idVote=" + topicOfVote.getId());
ArrayList<Answer> answers = new ArrayList<>();
while (ans.next()){
Answer answer = new Answer();
answer.setId(Integer.parseInt(ans.getString("idAnswer")));
answer.setAnswer(ans.getString("answer"));
answer.setIdOfTopic(Integer.parseInt(ans.getString("idVote")));
answers.add(answer);
}
topicOfVote.setAnswers(answers);
writer.println(topicOfVote); // ???
writer.flush();
ans.close();
}
}
Client:
private void createPanelTopics(){
try {
writer.println(HandlerQueries.GET_VOTES + "?");
writer.flush();
reader.readLine();//?????
} catch (IOException e) {
e.printStackTrace();
}
}
Can i somehow transfer the Object of type TopickOfVote to the client
Yes, with Object Serialization, provided TopickOfVote implements Serializable and does all the other right things associated, such as defining a private static final long serialVersionUID, and doesn't evolve incompatibly.
or only through String? Writer and reader:
Yes, with XML, JSON, ...
I have written a DAO class which allows several threads invoked by ExecutorServices to write to MySQL DB.
EDIT: I am using c3p0 to create a JDBC ConnectionPool. So every new thread will get a new JDBC Connection by calling
DataBaseManager.getInstance().getConnection()
There seems to be random concurrency issue while executing, e.g:
java.sql.SQLException: No value specified for parameter 1
at com.eanurag.dao.DataBaseManager.writeData(DataBaseManager.java:102)
I am not able to understand all the issues with the code. Should I just synchronize entire writeData() ?
public class DataBaseManager {
private final static Logger logger = Logger.getLogger(DataBaseManager.class);
private static volatile DataBaseManager dbInstance = null;
private DataBaseManager() {
cpds = new ComboPooledDataSource();
try {
cpds.setDriverClass("com.mysql.jdbc.Driver");
} catch (PropertyVetoException e) {
logger.error("Error in Initializing DB Driver class", e);
}
cpds.setJdbcUrl("jdbc:mysql://" + DB_HOST + "/" + DB_NAME);
cpds.setUser(DB_USER);
cpds.setPassword(DB_PASS);
cpds.setMinPoolSize(MINIMUM_POOL_SIZE);
cpds.setAcquireIncrement(INCREMENT_SIZE);
cpds.setMaxPoolSize(MAXIMUM_POOL_SIZE);
cpds.setMaxStatements(MAX_STATEMENTS);
}
public static DataBaseManager getInstance() {
if (dbInstance == null) {
synchronized (WorkerManager.class) {
if (dbInstance == null) {
dbInstance = new DataBaseManager();
}
}
}
return dbInstance;
}
private ComboPooledDataSource cpds;
private static final Integer MINIMUM_POOL_SIZE = 10;
private static final Integer MAXIMUM_POOL_SIZE = 1000;
private static final Integer INCREMENT_SIZE = 5;
private static final Integer MAX_STATEMENTS = 200;
private volatile Connection connection = null;
private volatile Statement statement = null;
private volatile PreparedStatement preparedStatement = null;
private static final String DB_HOST = "localhost";
private static final String DB_PORT = "3306";
private static final String DB_USER = "root";
private static final String DB_PASS = "";
private static final String DB_NAME = "crawly";
private static final String URL_TABLE = "url";
public Connection getConnection() throws SQLException {
logger.info("Creating connection to DB!");
return this.cpds.getConnection();
}
public Boolean writeData(URL url) {
StringBuffer writeDBStatement = new StringBuffer();
writeDBStatement.append("insert into");
writeDBStatement.append(" ");
writeDBStatement.append(DB_NAME);
writeDBStatement.append(".");
writeDBStatement.append(URL_TABLE);
writeDBStatement.append(" ");
writeDBStatement.append("values (?,?,default)");
Boolean dbWriteResult = false;
try {
connection = DataBaseManager.getInstance().getConnection();
preparedStatement = connection.prepareStatement(writeDBStatement.toString());
preparedStatement.setString(1, url.getURL());
preparedStatement.setString(2, String.valueOf(url.hashCode()));
dbWriteResult = (preparedStatement.executeUpdate() == 1) ? true : false;
if(dbWriteResult){
logger.info("Successfully written to DB!");
}
} catch (SQLException e) {
logger.error("Error in writing to DB", e);
} finally {
try {
preparedStatement.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return dbWriteResult;
}
}
The connection and preparedStatement variables must be local, not instance members.
No synchronization required.
What is happening here?
public Connection getConnection() throws SQLException {
logger.info("Creating connection to DB!");
return this.cpds.getConnection();
}
Namely, what does cpds.getConnection() do? When you call:
connection = DataBaseManager.getInstance().getConnection();
Your connection object is a member of what's supposed to be a singleton class here but every call to writeData() overwrites it it with a new getConnection() call. Is the getConnection() call thread unsafe as well?
Also, why is the connection object declared as a class member and then overwritten each time writeData() is called? In a multi-threaded environment, the code as it exists allows for the connection object to be overwritten by another getConnection() call immediately before prepareStatement() is called, since access to writeData() is not locked. Same for preparedStatement. Move those into the writeData() method.
I'm doing my dissertation on software engineering and im building a small application that makes use of a SQL DB, in this case MySQL. I'm also using the application controller pattern. So the code I have working for retrieving data from the db is;
public static void main(String[] args)
{
try
{
String url = "jdbc:mysql://localhost:3306/tm470_returns_stock_management_system";
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection(url,"root","root");
Statement st = con.createStatement();
ResultSet res = st.executeQuery("SELECT * FROM test_table");
while (res.next())
{
int id = res.getInt("test_id");
String msg = res.getString("test_info");
System.out.println(id + "\t" + msg);
}
con.close();
}
catch(Exception e)
{
System.out.println("DB connection unsuccesful");
}
}
I now want to transfer this out of my Main class/string and into my Application Controller Class (which is called Facility).
Now my question is, for every method in my Facility Class that needs to access the DB, do i have to do the full code each time? Or can i create a method within the Facility class that each application method can just call whenever it needs to access the DB. If i can condense all this into a method, can you advise me how to go about it please?
Be gentle with me guys, I am a learner :)
How about adding a utility class like ConnectionUtil and using the static method to access the connection.
import java.sql.Connection;
import java.sql.DriverManager;
public class ConnectionUtil{
static final String url = "jdbc:mysql://localhost:3306/";
static final String dbName = "test";
static final String driver = "com.mysql.jdbc.Driver";
static final String userName = "userparatest";
static final String password = "userparatest";
Connection con = null;
static Connection getConnection() throws Exception {
if(con == null)
{ Class.forName(driver).newInstance();
con = DriverManager.getConnection(url + dbName, userName,password);
}
return con;
}
}
this can be further improved but just providing a start..
just call below whenever you want a statement..
Statement st = ConnectionUtil.getConnection().createStatement();
I would map it as a own class, which is used by your application other classes. When you define it as a singleton you will only need one instance in your complete application
Yes , you can write a method for accessing db and you can reuse it across all the applications.
Keep the following in a method and reuse it.
String url = "jdbc:mysql://localhost:3306/tm470_returns_stock_management_system";
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection(url,"root","root");
Statement st = con.createStatement();
int productID = 6;
String skuCode = "ABC123";
ResultSet res = st.executeQuery("SELECT * FROM test_table");
while (res.next())
{
int id = res.getInt("test_id");
String msg = res.getString("test_info");
System.out.println(id + "\t" + msg);
}
I am new to programming and i am trying to make an small Java swing application using netbeans IDE and i have designed the Form and created an table too i used the following code to insert data into database from the form but i am getting many errors please help me to correct this code:
import java.sql.*;
public class db
{
static final String JDBC_DRIVER="com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/userdb";
static final String USER="root";
static final String PASS="toor";
Connection conn = null;
Statement stmt = null;
static final String d_unit=jTextField2.getText();
static final String d_name=jTextField3.getText();
static final String d_dob=jDateChooser2.getText();
//static final String d_gender="gender";
static final String d_age=jTextField4.getText();
static final String d_doorno=jTextField5.getText();
static final String d_street=jTextField6.getText();
static final String d_vc=jTextField7.getText();
static final String d_district=jTextField8.getText();
static final String d_pin=jTextField9.getText();
static final String d_phone=jTextField10.getText();
static final String d_mail=jTextField11.getText();
static final String d_occupations=jTextField12.getText();
try
{
Class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection(DB_URL,USER,PASS);
stmt = conn.createStatement();
stmt.executeUpdate("insert into donors (unit,name,dob,age,doorno,street,vc,district,pin,phone,mail,occupation) values('"+d_unit+"','"+d_name+"','"+d_dob+"','"+d_age+"','"+d_doorno+"','"+d_street+"','"+d_vc+"','"+d_district+"','"+d_pin+"','"+d_phone+"','"+d_mail+"','"+d_occupations+"')");
JOptionPane.showMessageDialog(null,"Inserted Successfully!");
}
catch(Exception e)
{ }
}
You may not use the final String because, then you can't modify these Strings, and the other code is correct, but i think you can use the ? in the line:
String sql="INSERT INTO ´donors´ (unit,name) VALUES (?,?)";
//put the rest of the sentence
try {
PreparedStatement pdt = cn.prepareStatement(sql);
pdt.setString(1, jTextField2.getText();
pdt.setString(2, jTextField3.getText();
//put the rest of the code
int n1=pdt.executeUpdate();
if(n1>0)
{
JOptionPane.showMessageDialog(null,"Inserted Successfully!");
}
}catch (SQLException ex) { }
Well, that's the largest way, but the most correct. I hope this helps.
private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {
String itemCode = txtItemCode.getText();
String itemName = txtItemName.getText();
String unitPrice = txtUnitPrice.getText();
String qty = txtQty.getText();
String query = "insert into items values ('"+itemCode+"','"+itemName+"','"+unitPrice+"','"+qty+"')";
System.out.println(query);
try {
Connection c = DBClass.getConnection();
Statement stmt = c.createStatement();
stmt.executeUpdate(query);
JOptionPane.showMessageDialog(this, "Saved");
} catch (Exception e) {
e.printStackTrace();
}
// DBClass
import java.sql.Connection;
import java.sql.DriverManager;
/**
*
* #author Nadun
*/
public class DBClass {
static private Connection connection;
public static Connection getConnection() throws Exception{
if(connection == null){
//JDBC
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/stock", "root", "123");
}
return connection;
}
}
Everything looks alright. Maybe the trouble is on your mysql database?
Check the data type of your row in mysql, if your data type in the current row is "int", then it should be like this
try
{
Class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection(DB_URL,USER,PASS);
stmt = conn.createStatement();
stmt.executeUpdate("insert into donors (name, age) values('"+d_name+"',,'"+Integer.valueOf(d_age.getText().toString())+"')");
JOptionPane.showMessageDialog(null,"Inserted Successfully!");
}
catch(Exception e){ }
}
You should be careful with data types. If your mysql row is int type then in your java you should give it int time as well.
I guess your data type of "name" row is text that use string, and your data type of "age" row is int?
I check your code is giving a string value from your java to your int mysql row. that's the error.
So you should convert the string to the int first
Integer.valueOf(d_age.getText().toString());
try proceeding like this for simplicity and less error-prone
String sql = "INSERT INTO donors(unit,name,dob,age,doorno,street,vc,district,pin,phone,mail,occupation) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)";
stmt.executeUpdate(sql);
I'm having trouble working out why java can't see my mysql driver:
I've downloaded the driver .jar from the mysql website
I've added the jar to my runtime classpath
I can confirm the jar is on the classpath, by printing out the relevant system property
But I'm still getting ClassNotFound Exceptions. Is there anything else I need to be doing?
class example:
package org.rcz.dbtest;
import java.sql.*;
public class DB {
private Connection connect = null;
private Statement stmt = null;
private PreparedStatement prepared = null;
private ResultSet rset = null;
private String driverClassName = "com.myqsl.jdbc.Driver";
private String jdbcUrl = "jdbc:mysql://localhost/ctic_local?user=root&password=server";
private String queryString;
public DB(String query)
{
System.out.println(System.getProperty("java.class.path"));
queryString = query;
}
public void readFromDatabase()
{
try
{
Class.forName(driverClassName);
connect = DriverManager.getConnection(jdbcUrl);
stmt = connect.createStatement();
rset = stmt.executeQuery(queryString);
writeResultSet(rset);
}
catch (ClassNotFoundException cex)
{
System.out.println("Could not find mysql class");
}
catch(SQLException sqex)
{
}
}
private void writeResultSet(ResultSet resultSet) throws SQLException {
// ResultSet is initially before the first data set
while (resultSet.next()) {
// It is possible to get the columns via name
// also possible to get the columns via the column number
// which starts at 1
// e.g. resultSet.getSTring(2);
String user = resultSet.getString("name");
String comment = resultSet.getString("comment");
System.out.println("User: " + user);
System.out.println("Comment: " + comment);
}
}
}
My main class simply passes the query into the DB class:
package org.rcz.dbtest;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException
{
String qstring = "SELECT * FROM comments";
new DB(qstring).readFromDatabase();
System.in.read();
}
}
You've a typo in the driver class name.
private String driverClassName = "com.myqsl.jdbc.Driver";
it should be
private String driverClassName = "com.mysql.jdbc.Driver";
// -------------------------------------^
Unrelated to the concrete problem, holding DB resources like Connection, Statement and ResultSet as an instance variable of the class is a bad idea. You need to create, use and close them in the shortest possible scope in a try-finally block to prevent resource leaking. See also among others this question/answer: When my app loses connection, how should I recover it?