MySQL lag on get (SELECT) - java

My problem is that there is update troo at the get level so the server starts to lag 70% tps loss I do not know how to optimize its?
public static int getCoins(Player player) {
try {
PreparedStatement q = Main.sql.prepareStatement("SELECT Coins FROM Players WHERE Players_UUID = ?");
q.setString(1, player.getUniqueId().toString());
int coins= 0;
ResultSet rs = q.executeQuery();
while(rs.next()){
balance = rs.getInt("Coins");
}
q.close();
return coins;
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}

You don't need to do a sql query every time to get coins, just create a int or hashmap field with the data and check every X time if data has changed.
if it has changed send update to mysql server and mark that data has saved like two hashmap/int fields.
hashmap1 = database data
hashmap2 = server data
if hashmap1 and hashmap2 are same don't update.
Do the update in async function like schedulerAsync or thread.
Here a similar example:
package test;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import com.mysql.jdbc.Connection;
public class Event extends JavaPlugin implements Listener {
// Mysql update data
public static ConcurrentHashMap<UUID, Integer> player_zombiekills = new ConcurrentHashMap<UUID, Integer>();
// Mysql connection data
public static Connection connection;
private String host = "localhost";
private String database = "DB";
private String username = "user";
private String password = "123";
private int port = 3306;
//Kill zombie event
#EventHandler
public void zombieDeath(EntityDeathEvent eve) {
if (!(eve.getEntity() instanceof Zombie)) return; // Stop if death is not zombie
if (!(eve.getEntity().getKiller() instanceof Player)) return; // Stop if killer is not player
UUID uid = eve.getEntity().getKiller().getUniqueId(); // Save player uuid
if (player_zombiekills.contains(uid)) player_zombiekills.put(uid, 0); // Set kills 0 if not exist in hashmap
player_zombiekills.put(uid, player_zombiekills.get(uid) + 1); // plus 1 kills value
}
//On enable connection
public void onEnable() {
try {
if (connection != null && !connection.isClosed()) return;
Class.forName("com.mysql.jdbc.Driver");
connection = (Connection) DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database, username, password);
if (!connection.isClosed()) System.out.println("[MySQL] " + "Connected to '" + database + "'");
} catch (Exception e) {
System.err.println("[MySQL] " + e.getMessage());
}
new BukkitRunnable() {
public void run() {
// for updates
for (Entry<UUID, Integer> ent : player_zombiekills.entrySet()) {
try {
// send update
connection.createStatement().executeUpdate("UPDATE `tablename` SET `zombiekills`=`zombiekills`+" + ent.getValue() + " WHERE `uuid`='" + ent.getKey().toString() + "'");
// Sucess remove entry from hashmap to reset kills
player_zombiekills.remove(ent.getKey());
} catch (SQLException e) { // If error
System.err.println("[MySQL] " + e.getMessage()); // Print error in console
}
}
}
}.runTaskTimerAsynchronously(this, 20, 20 * 60 * 10); // Run async loop every 10 minutes
}
}

I do not see how to do because if you change the data in BDD it does not change on the server so if I do not get every 1 second its will not work so I have optimized with an async but how without return To get the coins...

Related

Pull data without loop

I have this code which I want to use to verify file processing from database status table:
package com.file.verifier;
import java.io.IOException;
import java.nio.file.*;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class Application extends SqlUtils {
private static String folderPath = "D:\\EntityImportEversana";
public static void main(final String[] args) throws IOException, InterruptedException {
System.out.println("Running file verifier");
System.out.println("monitoring folder " + folderPath);
SqlUtils sql = new SqlUtils();
WatchService watchService = FileSystems.getDefault().newWatchService();
Path path = Paths.get(folderPath);
path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
WatchKey key;
while ((key = watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
System.out.println("Event kind:" + event.kind() + ". File affected: " + event.context() + ".");
if(event.kind().equals(StandardWatchEventKinds.ENTRY_DELETE)){
Instant start = Instant.now();
boolean flag = true;
while(flag) {
while ((key = watchService.take()) != null) {
HashMap<String, List> map = sql.checkFileImport();
List values = map.get(event.context()); // get values by file name
if(values.contains("Completed")){
// exit the monitoring while loop
flag = false;
}
}
Thread.sleep(1000);
}
Instant end = Instant.now();
System.out.println(Duration.between(start,end));
long seconds = TimeUnit.MILLISECONDS.toSeconds(Duration.between(start,end).getSeconds());
long minutes = TimeUnit.MILLISECONDS.toMinutes(Duration.between(start,end).getSeconds());
System.out.format("Execution time %d minutes %d seconds", minutes, seconds);
}
}
key.reset();
}
watchService.close();
}
}
SQL requests file:
package com.file.verifier;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;
public class SqlUtils {
String connectionUrl =
"jdbc:sqlserver://......";
protected HashMap<String, List> checkFileImport(){
ResultSet resultSet = null;
HashMap<String, List> map = new HashMap<>();
try (Connection connection = DriverManager.getConnection(connectionUrl);
Statement statement = connection.createStatement();) {
// Create and execute a SELECT SQL statement.
String selectSql = "SELECT * from integration.EntityImportRequests";
resultSet = statement.executeQuery(selectSql);
// Print results from select statement
while (resultSet.next()) {
map.put(resultSet.getString(3), Arrays.asList(resultSet.getString(5),
resultSet.getString(6),
resultSet.getString(7)));
}
}
catch (SQLException e) {
e.printStackTrace();
}
return map;
}
}
I use this code to detect the file import. How I can replace the while loop with something better? When there is a error status I would like to stop the execution and print and print the processing error.

Open CSV Performance to write data

I came through a link: https://github.com/hyee/OpenCSV which drastically improves the writing time of the JDBC ResultSet to CSV due to setAsyncMode, RESULT_FETCH_SIZE
//Extract ResultSet to CSV file, auto-compress if the fileName extension is ".zip" or ".gz"
//Returns number of records extracted
public int ResultSet2CSV(final ResultSet rs, final String fileName, final String header, final boolean aync) throws Exception {
try (CSVWriter writer = new CSVWriter(fileName)) {
//Define fetch size(default as 30000 rows), higher to be faster performance but takes more memory
ResultSetHelperService.RESULT_FETCH_SIZE=10000;
//Define MAX extract rows, -1 means unlimited.
ResultSetHelperService.MAX_FETCH_ROWS=20000;
writer.setAsyncMode(aync);
int result = writer.writeAll(rs, true);
return result - 1;
}
}
But the problem is I don't know how I can merge above into my requirement. As the link has many other classes involved which I am not sure what they do and if I even need it for my requirement. Still, I tried but it fails to compile whenever I enable 2 commented line code. Below is my code.
Any help on how I can achieve this will be greatly appreciated.
package test;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Date;
import com.opencsv.CSVWriter;
import com.opencsv.ResultSetHelperService;
public class OpenCSVTest1
{
static Connection con =null;
static Statement stmt = null;
static ResultSet rs = null;
public static void main(String args[]) throws Exception
{
connection ();
retrieveData(con);
}
private static void connection() throws Exception
{
try
{
Class.forName("<jdbcdriver>");
con = DriverManager.getConnection("jdbc:","<username>","<pass>");
System.out.println("Connection successful");
}
catch (Exception e)
{
System.out.println("Exception while establishing sql connection");
throw e;
}
}
private static void retrieveData(Connection con) throws Exception
{
try
{
stmt=con.createStatement();
stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
String query = "SELECT * FROM dbo.tablename";
rs=stmt.executeQuery(query);
CSVWriter writer = new CSVWriter(new BufferedWriter(new FileWriter("C:\\Data\\File1.csv")));
ResultSetHelperService service = new ResultSetHelperService();
/*** ResultSetHelperService.RESULT_FETCH_SIZE=10000; ***/ // to add
service.setDateTimeFormat("yyyy-MM-dd HH:mm:ss.SSS");
System.out.println("**** Started writing Data to CSV **** " + new Date());
writer.setResultService(service);
/*** writer.setAsyncMode(aync); ***/ // to add
int lines = writer.writeAll(rs, true, true, false);
writer.flush();
writer.close();
System.out.println("** OpenCSV -Completed writing the resultSet at " + new Date() + " Number of lines written to the file " + lines);
}
catch (Exception e)
{
System.out.println("Exception while retrieving data" );
e.printStackTrace();
throw e;
}
finally
{
rs.close();
stmt.close();
con.close();
}
}
}
UPDATE
I have updated my code. Right now code is writing complete resultset in CSV at once using writeAll method which is resulting in time consumption.
Now what I want to do is write resultset to CSV in batches as resultset's first column will always have dynamically generated via SELECT query Auto Increment column (Sqno) with values as (1,2,3..) So not sure how I can read result sets first column and split it accoridngly to write in CSV. may be HashMap might help, so I have also added resultset-tohashmap conversion code if required.
import com.opencsv.CSVWriter;
import com.opencsv.ResultSetHelperService;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class OpenCSVTest1
{
static int fetchlimit_src = 100;
static Connection con =null;
static Statement stmt = null;
static ResultSet rs = null;
static String filename = "C:\\Data\\filename.csv";
static CSVWriter writer;
public static void main(String args[])
{
try
{
connection();
retrieveData(con);
}
catch(Exception e)
{
System.out.println(e);
}
}
private static void connection() throws Exception
{
try
{
Class.forName("<jdbcdriver>");
con = DriverManager.getConnection("jdbc:","<username>","<pass>");
System.out.println("Connection successful");
}
catch (Exception e)
{
System.out.println("Exception while establishing sql connection");
throw e;
}
}
private static void retrieveData(Connection con) throws Exception
{
try
{
stmt=con.createStatement();
String query = "SELECT ROWNUM AS Sqno, * FROM dbo.tablename "; // Oracle
// String query = "SELECT ROW_NUMBER() OVER(ORDER BY Id ASC) AS Sqno, * FROM dbo.tablename "; // SQLServer
System.out.println(query);
stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(fetchlimit_src);
System.out.println("**** Started querying src **** " + new Date());
rs=stmt.executeQuery(query);
System.out.println("**** Completing querying src **** " + new Date());
// resultset_List(rs); // If required store resultset(rs) to HashMap
writetoCSV(rs,filename);
/** How to write resultset to CSV in batches instead of writing all at once to speed up write performance ?
* Hint: resultset first column is Autoincrement [Sqno] (1,2,3...) which might help to split result in batches.
*
**/
}
catch (Exception e)
{
System.out.println("Exception while retrieving data" );
e.printStackTrace();
throw e;
}
finally
{
rs.close();
stmt.close();
con.close();
}
}
private static List<Map<String, Object>> resultset_List(ResultSet rs) throws SQLException
{
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
List<Map<String, Object>> rows = new ArrayList<Map<String, Object>>();
while (rs.next())
{
Map<String, Object> row = new HashMap<String, Object>(columns);
for(int i = 1; i <= columns; ++i)
{
row.put(md.getColumnName(i), rs.getObject(i));
}
rows.add(row);
}
// System.out.println(rows.toString());
return rows;
}
private static void writetoCSV(ResultSet rs, String filename) throws Exception
{
try
{
writer = new CSVWriter(new BufferedWriter(new FileWriter(filename)));
ResultSetHelperService service = new ResultSetHelperService();
service.setDateTimeFormat("yyyy-MM-dd HH:mm:ss.SSS");
long batchlimit = 1000;
long Sqno = 1;
ResultSetMetaData rsmd = rs.getMetaData();
String columnname = rsmd.getColumnLabel(1); // To retrieve columns with labels (for example SELECT ROWNUM AS Sqno)
System.out.println("**** Started writing Data to CSV **** " + new Date());
writer.setResultService(service);
int lines = writer.writeAll(rs, true, true, false);
System.out.println("** OpenCSV -Completed writing the resultSet at " + new Date() + " Number of lines written to the file " + lines);
}
catch (Exception e)
{
System.out.println("Exception while writing data" );
e.printStackTrace();
throw e;
}
finally
{
writer.flush();
writer.close();
}
}
}
You should be able to use the OpenCSV sample, pretty much exactly as it is provided in the documentation. So, there should be no need for you to write any of your own batching logic.
I was able to write a 6 million record result set to a CSV file in about 10 seconds. To be clear -that was just the file-write time, not the DB data-fetch time - but I think that should be fast enough for your needs.
Here is your code, with adaptations for using OpenCSV based on its documented approach... But please see the warning at the end of my notes!
import com.opencsv.CSVWriter;
import com.opencsv.ResultSetHelperService;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Date;
import java.text.SimpleDateFormat;
public class OpenCSVDemo {
static int fetchlimit_src = 100;
static Connection con = null;
static Statement stmt = null;
static ResultSet rs = null;
static String filename = "C:\\Data\\filename.csv";
public static void main(String args[]) {
try {
connection();
retrieveData(con);
} catch (Exception e) {
System.out.println(e);
}
}
private static void connection() throws Exception {
try {
final String jdbcDriver = "YOURS GOES HERE";
final String dbUrl = "YOURS GOES HERE";
final String user = "YOURS GOES HERE";
final String pass = "YOURS GOES HERE";
Class.forName(jdbcDriver);
con = DriverManager.getConnection(dbUrl, user, pass);
System.out.println("Connection successful");
} catch (Exception e) {
System.out.println("Exception while establishing sql connection");
throw e;
}
}
private static void retrieveData(Connection con) throws Exception {
try {
stmt = con.createStatement();
String query = "select title_id, primary_title from imdb.title";
System.out.println(query);
stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(fetchlimit_src);
System.out.println("**** Started querying src **** " + new Date());
rs = stmt.executeQuery(query);
System.out.println("**** Completing querying src **** " + new Date());
// resultset_List(rs); // If required store resultset(rs) to HashMap
System.out.println();
String timeStamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
System.out.println("Started writing CSV: " + timeStamp);
writeToCsv(rs, filename, null, Boolean.FALSE);
timeStamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
System.out.println("Finished writing CSV: " + timeStamp);
System.out.println();
} catch (Exception e) {
System.out.println("Exception while retrieving data");
e.printStackTrace();
throw e;
} finally {
rs.close();
stmt.close();
con.close();
}
}
public static int writeToCsv(final ResultSet rs, final String fileName,
final String header, final boolean aync) throws Exception {
try (CSVWriter writer = new CSVWriter(fileName)) {
//Define fetch size(default as 30000 rows), higher to be faster performance but takes more memory
ResultSetHelperService.RESULT_FETCH_SIZE = 1000;
//Define MAX extract rows, -1 means unlimited.
ResultSetHelperService.MAX_FETCH_ROWS = 2000;
writer.setAsyncMode(aync);
int result = writer.writeAll(rs, true);
return result - 1;
}
}
}
Points to note:
1) I used "async" set to false:
writeToCsv(rs, filename, null, Boolean.FALSE);
You may want to experiment with this and the other settings to see if they make any significant difference for you.
2) Regarding your comment "the link has many other classes involved": The OpenCSV library's entire JAR file needs to be included in your project, as does the related disruptor JAR:
opencsv.jar
disruptor-3.3.6.jar
To get the JAR files, go to the GitHub page, click on the green button, select the zip download, unzip the zip file, and look in the "OpenCSV-master\release" folder.
Add these two JARs to your project in the usual way (depends on how you build your project).
3) WARNING: This code runs OK when you use Oracle's Java 8 JDK/JRE. If you try to use OpenJDK (e.g. for Java 13 or similar) it will not run. This is because of some changes behind the scenes to hidden classes. If you are interested, there are more details here.
If you need to use an OpenJDK version of Java, you may therefore have better luck with the library on which this CSV library is based: see here.

Record not getting deleted from MySQL database's table while it's deleted from Java GUI?

Edited Question
When I click the delete button, The row in the table gets deleted in GUI but not from database in mysql server.
Here's the code:
// DatabaseStore. This part runs fine.
public class DatabaseStore {
private final String server = "jdbc:mysql://localhost/";
private final String database = "music_magic";
private final String user_name = "root";
private final String pass_word = "";
private final String driver = "com.mysql.jdbc.Driver";
public Connection doConnection() {
Connection c;
try {
//load the driver
Class.forName(driver);
c = DriverManager.getConnection(server + database, user_name, pass_word);
// JOptionPane.showMessageDialog(null, "Database connected");
} catch (Exception e) {
c = null;
JOptionPane.showMessageDialog(null, "Error : " + e.getMessage());
}
return c;
}
//
// Imports
import Database_music.DatabaseStore; //main database page where i connect to database
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
import magic_music.Items; //ignore this
//...
// Subject method
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
if(jTable1.getSelectedRow() >=0){
try{
DatabaseStore dtbs = new DatabaseStore();
Connection cn = dtbs.doConnection();
Statement stat = cn.createStatement();
String sql = "DELETE FROM products_info WHERE Product_id ='"+jTable1.getSelectedRow() +"'";
stat.executeUpdate(sql);
DefaultTableModel model = (DefaultTableModel)jTable1.getModel();
model.removeRow(jTable1.getSelectedRow());
}
catch (SQLException sqlException)
{
sqlException.printStackTrace();
JOptionPane.showMessageDialog(null, "sql err");
}
} else {
JOptionPane.showMessageDialog(null, "Please select an item to delete");
}
}
Please tell me what am I doing wrong?

Reading Visual Foxpro Data From Java using ODBC

I am trying to query a dbf table from my Java application. I put in reference this thread
I created a system data source using the ODBC Data Source Administrator, I set the data source name to be VFPDS and set the database type to .DBC finaly i set the path to the .dbc file.
the following is my java code:
import javax.swing.* ;
import java.awt.* ;
import java.awt.event.* ;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
// Import custom library containing myRadioListener
import java.sql.DriverManager;
public class testodbc {
public static void main( String args[] )
{
try
{
// Load the database driver
Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ) ;
// Get a connection to the database
Connection conn = DriverManager.getConnection( "jdbc:odbc:VFPDS" ) ;
// Print all warnings
for( SQLWarning warn = conn.getWarnings(); warn != null; warn = warn.getNextWarning() )
{
System.out.println( "SQL Warning:" ) ;
System.out.println( "State : " + warn.getSQLState() ) ;
System.out.println( "Message: " + warn.getMessage() ) ;
System.out.println( "Error : " + warn.getErrorCode() ) ;
}
// Get a statement from the connection
Statement stmt = conn.createStatement() ;
// Execute the query
ResultSet rs = stmt.executeQuery( "SELECT * FROM pmsquoteh" ) ;//code crashes here
// Loop through the result set
while( rs.next() )
System.out.println( rs.getString(1) ) ;
// Close the result set, statement and the connection
rs.close() ;
stmt.close() ;
conn.close() ;
}
catch( SQLException se )
{ se.printStackTrace();
System.out.println( "SQL Exception:" ) ;
// Loop through the SQL Exceptions
while( se != null )
{ se.printStackTrace();
System.out.println( "State : " + se.getSQLState() ) ;
System.out.println( "Message: " + se.getMessage() ) ;
System.out.println( "Error : " + se.getErrorCode() ) ;
se = se.getNextException() ;
}
}
catch( Exception e )
{
System.out.println( e ) ;
}
}
}
I got this exception :
java.sql.SQLException: [Microsoft][ODBC Visual FoxPro Driver]Not a table.
at sun.jdbc.odbc.JdbcOdbc.createSQLException(Unknown Source)
at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source)
at sun.jdbc.odbc.JdbcOdbc.SQLExecDirect(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcStatement.execute(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcStatement.executeQuery(Unknown Source)
at UsingButtons.main(testodbc.java:38)
SQL Exception:
State : S0002
Message: [Microsoft][ODBC Visual FoxPro Driver]Not a table.
Error : 123
I am sure that the table pmsquoteh exits in the database and my machine is a 64 bit machine.
What am i doing wrong ? I would appreciate specific answers.
I was able to access a FoxPro table with the jdbc-odbc bridge on Windows 7 but it took a number of steps. I already had the VFP driver installed, and I don't remember where I downloaded it from, so I don't have a link for that.
I copied the code from a jbdc:odbc example here: http://www.java2s.com/Code/Java/Database-SQL-JDBC/SimpleexampleofJDBCODBCfunctionality.htm.
The DriverManager.getConnection method takes a database URL. To create a URL you need to use the ODBC manager. Unfortunately for me, the ODBC manager that I could get to through the control panel only worked for 64 bit data sources. I am not aware of a 64 bit foxpro driver.
To generate a 32 bit DSN you need to run the 32 bit ODBC manager: odbcad32.exe. My machine had several copies. I ran the one from C:\Windows\SysWOW64. Go to the System DSN tab and select the Microsoft Visual Foxpro Driver. When you click finish, you will get a dialog that asks for a Data Source Name, description and path to the FoxPro database or tables. You also have to specify whether you want to connect to a .dbc or a free table directory. Your error message makes me wonder if you had the wrong option selected on your DSN.
The database URL I passed in to the getConnection method was "jdbc:odbc:mydsnname".
After I ran this, I received an error:
[Microsoft][ODBC Driver Manager] The specified DSN contains an
architecture mismatch between the Driver and Application
This was because I was using a 64 bit JVM with a 32 bit DSN. I downloaded a 32 bit JVM and was able to use it to run my sample class.
I do not know if there is a switch you can set on a 64 bit JVM to tell it to run as 32 bit.
I used the JDBC driver from here:
http://www.csv-jdbc.com/relational-junction/jdbc-database-drivers-products/new-relational-junction-dbf-jdbc-driver/
Works fine for me. In testing so far (about an hour), it reads MEMO files and seems to have had no issues with either DBC-containted tables or free DBFs.
Not sure how much this driver costs. The client will only probably pay $100 max since VFP is beyond obsolete.
I am using javadbf-0.4.0.jar for last six month without and problem.I will post my Java class and main program.
package foxtablereader.src;
import java.sql.Connection;
import java.sql.SQLException;
import sun.jdbc.rowset.CachedRowSet;
/**
*
* #author kalimk
*/
public class DbfMain {
static CachedRowSet crs;
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws SQLException {
DbfConnection foxconn = new DbfConnection();
Connection connection = null;
String inputTablePath = "c:\\vfp_table\\";
connection = foxconn.connection(inputTablePath);
String query = "SELECT * FROM TrigExport2.dbf ";
crs = foxconn.select(query, connection);
//crs = ft.query(query, inputTablePath);
System.out.println(" Size " + crs.size());
while (crs.next()) {
System.out.println("DESC " + crs.getString("Serialnum") + " " + crs.getString("cmailcode"));
}
inputTablePath = "C:\\sourcecode\\FoxTableReader\\";
connection = foxconn.connection(inputTablePath);
query = "SELECT * FROM TrigExports.dbf ";
crs = foxconn.select(query, connection);
System.out.println(" Size " + crs.size());
int z = 1;
while (crs.next()) {
System.out.println(z++ + " " + crs.getString("Serialnum") + " " + crs.getString("cmailcode"));
}
inputTablePath = "C:\\sourcecode\\FoxTableReader\\";
connection = foxconn.connection(inputTablePath);
String queryinsert = "insert into Mcdesc (Desc,Mailcode,Del_type,Column1) values ('Kalim','KHAN', 'ERUM','KHAN')";
foxconn.insertUpdate(queryinsert, connection);
inputTablePath = "C:\\sourcecode\\FoxTableReader\\";
connection = foxconn.connection(inputTablePath);
String queryupdate = "update Mcdesc set Column1= 'Sadiqquie' where Desc = 'Kalim'";
foxconn.insertUpdate(queryupdate, connection);
}
}
package foxtablereader.src;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import sun.jdbc.rowset.CachedRowSet;
/**
*
* #author kalimk
*/
public class DbfConnection {
public Connection connection(String inputTablePath) throws SQLException {
Connection con = null;
//String jdbURL = "jdbc:DBF:/C:\\vfp_table\\";
String jdbURL = "jdbc:DBF:/" + inputTablePath;
Properties props = new Properties();
props.setProperty("delayedClose", "0");
try {
Class.forName("com.caigen.sql.dbf.DBFDriver");
try {
con = DriverManager.getConnection(jdbURL, props);
} catch (SQLException ex) {
Logger.getLogger(DbfConnection.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (ClassNotFoundException ex) {
Logger.getLogger(DbfConnection.class.getName()).log(Level.SEVERE, null, ex);
}
return con;
}
public CachedRowSet select(String cQuery, Connection con) {
CachedRowSet crs = null;
try {
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(cQuery);
crs = new CachedRowSet();
crs.populate(rs);
stmt.close();
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
return crs;
}
public boolean insertUpdate(String cQuery, Connection con) {
boolean crs = false;
try {
PreparedStatement pStmnt = con.prepareStatement(cQuery);
crs = pStmnt.execute();
pStmnt.close();
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
return crs;
}
public int insertUpdateCount(String cQuery, Connection con) {
int count = 0;
try {
Statement stmt = con.createStatement();
count = stmt.executeUpdate(cQuery);
System.out.println("Number of rows updated in database = " + count);
stmt.close();
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
return count;
}
public int insertUpdateCount2(String cQuery, Connection con) {
int count = 0;
boolean crs = false;
try {
PreparedStatement pStmnt = con.prepareStatement(cQuery);
count = pStmnt.executeUpdate(cQuery);
pStmnt.close();
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
return count;
}
public static void DBDisconnect(Connection DBCon) {
try {
if (DBCon != null) {
DBCon.close();
}
} catch (SQLException e) {
System.out.println(e.toString());
} finally {
try {
DBCon.close();
//System.err.println("Fimally is always executed");
} catch (SQLException ex) {
Logger.getLogger(DbfConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}

Why the INSERT query doesn't work in this HttpServer code

Im trying to make a little server for my homework.This is very simple project yet i cant insert some variables (which i took from the client ,in an object form ,through serialization ) into the database .
It shows no errors! That's what i find strange and also the client receive the response without problems.
my Server class is as the following :
package server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import org.ietf.jgss.Oid;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class Server {
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(3333), 0);
server.createContext("/", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
}
static class MyHandler implements HttpHandler {
public void handle(HttpExchange t) throws IOException {
ObjectInputStream ios = new ObjectInputStream(t.getRequestBody());
final String url = "jdbc:mysql://localhost/httpServer";
final String user = "root";
final String password = "";
try {
Send oin = (Send) ios.readObject();
String response = "Kjo eshte nje pergjigje nga serveri! \n"
+ "Clienti me id "
+ oin.getId()
+ " dhe me emer "
+ oin.getName()
+ " ka pasur "
+ oin.getAmount()
+ "$ ne llogarine e tij ,por me pas ka terhequr "
+ oin.getPaid()
+ "$ nga llogaria \n"
+ "Kjo terheqe eshte ruajtur ne database dhe tani gjendja e re eshte "
+ (oin.getAmount() - oin.getPaid()) + "$ \n";
t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
int id = oin.getId();
String emri = oin.getName();
int amount = oin.getAmount();
int paid = oin.getPaid();
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(url, user,
password);
try {
Statement s = con.createStatement();
s.executeUpdate("INSERT INTO person VALUES ('" + id
+ "','" + emri + "','" + amount + "','" + paid
+ "')");
} catch (SQLException s) {
System.out
.println("Tabel or column or data type is not found!");
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
can you please help me ?
Or have any idea what the problem may is ?
Edit:
Maybe i am doing something wrong in the Client:
package server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
class Send implements Serializable {
// duhet te implementoje interfacin serizable ne menyre qe tja dergoj
// serverit
private static final long serialVersionUID = 1L;
public int getId() {
return id;
}
public int getAmount() {
return amount;
}
public int getPaid() {
return paid;
}
int id = 1;
int amount = 2000;
int paid = 800;
String name = "Andi Domi";
public String getName() {
return name;
}
}
public class Client {
public static void main(String[] args) throws Exception {
try {
URL url = new URL("http://localhost:3333");
HttpURLConnection s = (HttpURLConnection) url.openConnection();
s.setDoOutput(true);
s.setDoInput(true);
s.setRequestMethod("POST");
s.setUseCaches(false);
Send obj = new Send();
ObjectOutputStream objOut = new ObjectOutputStream(
s.getOutputStream());
objOut.writeObject(obj);
InputStream in = s.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
int c;
while ((c = br.read()) != -1) {
System.out.print((char) c);
}
objOut.close();
s.disconnect();
} catch (IOException ex) {
System.err.println(ex);
System.err.print("gabimi eshte ketu");
}
}
}
After your executeUpdate statement you need to do.
con.commit();
to save the transaction.
EDIT: Based on the chat discussion, we learned that the column named emri is actually Emri in the table and was throwing:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'emri' in 'field list'
Changing the name resolves the issue.
Now unrelated to your problem, you should be using a PreparedStatement instead and should be closing your connection and statement
try {
PreparedStatement s = con.prepareStatement("INSERT INTO person(id, emri, amount, paid) VALUES (?,?,?,?)");
s.setInt(1,id);
s.setString(2,emri);
s.setInt(3,amount);
s.setInt(4,paid);
int count = s.executeUpdate();
con.commit();
} catch(Exception e){
e.printStackTrace();
//something bad happened rollback
//any uncommitted changes
con.rollback();
} finally {
if (con != null) {
con.close();
}
}
first, use prepared statement[docs] to avoid from SQL INJECTION
String sql = "INSERT INTO person VALUES (?,?,?,?)";
PreparedStatement prest = con.prepareStatement(sql);
prest.setString(1,id);
prest.setString(2,emri); // or use setInt for integer
prest.setString(3,amount); // or use setInt for integer
prest.setString(4,paid);
prest.executeUpdate()
second, if the the number of values does not match the total number of columns in your table, it will also fail because you are using the implicit type of INSERT statement. To solve it, just supply the column names where you want the values should be stored, eg
String sql = "INSERT INTO person (col1, col2, col3, col4) VALUES (?,?,?,?)";

Categories