I want to generate Sequential Trnsaction ID's for employees to store in the Database ... I wrote the below jsp code(This ain't the code to insert Tx ID in the database) ..The code works fine .. When i use order by clause to see the latest transaction ..i'm not getting the expected transation ID...How can i make the transaction ID's unique , Sequential so that i can retrieve them in a particular sequence by using Order By clause?
<%
String url = "jdbc:mysql://localhost:3306/";
String dbName = "ystem";
String driver = "com.mysql.jdbc.Driver";
String userName = "root";
String password = "";
try {
Class.forName(driver).newInstance();
Connection conn = DriverManager.getConnection(url+dbName,userName,password);
Statement stat=conn.createStatement();
ResultSet rs=stat.executeQuery("select count(*) from `employee`");
int x=0;
UUID idOne = UUID.randomUUID();
while(rs.next()) {
x=Integer.parseInt(rs.getString(1))+1;
}
out.println(idOne.toString().toUpperCase()+"-"+String.valueOf(x));
stat.close(); conn.close();
}
catch(Exception x) {
out.println(x.getMessage());
}
%>
Leaving aside the wisdom of this approach, appending the count to the UUID isn't going to give you something that will be meaningfully orderable by an order by clause because you are creating something in the form RANDOMSTUFF-2. That can't be ordered in any sequence because order by will sort a string column lexically starting with the first character.
So instead, put the counter at the beginning of your string. Then you'll have something order by can meaningfully sort:
String s = String.valueOf(x) + "-" + idOne.toString().toUpperCase();
(Though you'll probably want/need to zero-pad the output of String.valueOf(x) because otherwise "1000" will be sorted to be before "2". So you need "2" to output as "0002", for example.)
(and of course you should use StringBuilder.append() (or StringBuffer if your version of Java is old enough) rather than string concatenation).
Related
say I've got a JSON like this:
{"name": "tom", "id":1, "clothes":[{"shirt":"yellow"},{"shoes":black},.......]}
I'm trying to insert it, as is, into a column in a mysql DB using Java.
void insertVal(JsonObject json){
Connection conn = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/Orders?user=root", "root", "1234");
Statement st = conn.createStatement();
StringBuilder values = new StringBuilder("(");
for (String key : json.keySet()){
if (key.equals("clothes")){
//do something to deal with this array
break;
}
values.append(json.get(key)).append(",");
}
values.append(")");
String insert = "INSERT INTO ORDERS VALUES " + values;
st.executeUpdate(insert);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This code works fine up to clothes key. So far, I've tried using JSON OBJECT and JSON MERGE but the format doesn't quite match, and I'd rather not parse right now.
So, is it possible to add clothes or do I have to parse it somehow? if so, what format would work best?
Thanks a lot
To all those concerned: The problem was the " string. mysql, and probably SQL in general, don't handle these well. There are two options. The first, and less recommended:
String parsed = json.get(key).toString().replace("\"", "");
Then, insert normally.
The second, much more recommended - use PreparedStatement. This way, you can write an insert/update query without minding the escape characters. Example, after i've inserted 'null' values for the clothes column:
PreparedStatement ps = conn.prepareStatement("UPDATE ORDERS set CLOTHES = ? WHERE ID = ?");
ps.setString(1, clothes); // clothes - get(key).toString()
ps.setInt(2, count); // count - counts which iteration we are
ps.executeUpdate();
I hope anyone in the future finds this useful.
I am having some trouble in returning the NEXT record within the database, my code currently only returns the last record entered. I have tried creating an instance of a List/ArrayList, tried adding statements to my createStatement(); and just tried everything. I've searched the web, however, I always seem to get the last value returned. I was hoping as to whether someone could help me out. I am using .Swing and this is all executed within an ActionListener.
Essentially I want this function to get the next record in the database. As opposed to returning the last record.
nextEmployee.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Connection connection = null;
Statement statement = null;
try {
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:employeeDatabase.sqlite");
connection.setAutoCommit(false);
System.out.println("Read operation - database successfully opened");
statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
ResultSet resultset = statement.executeQuery( "SELECT * from employees" );
while (resultset.next()) {
ArrayList<Employee> selectAllEmployees = new ArrayList<Employee>();
String id = resultset.getString("id");
String name = resultset.getString("name");
String email = resultset.getString("email");
String gender = resultset.getString("gender");
String dob = resultset.getString("dob");
String Address = resultset.getString("address");
String Postcode = resultset.getString("Postcode");
String NIN = resultset.getString("NIN");
String JobTitle = resultset.getString("JobTitle");
String StartDate = resultset.getString("StartDate");
String Salary = resultset.getString("Salary");
idTextField.setText(id);
nameTextField.setText(name);
genderTextField.setText(gender);
dobTextField.setText(dob);
addressTextField.setText(Address);
postcodeTextField.setText(Postcode);
ninTextField.setText(NIN);
jobtitleTextField.setText(JobTitle);
startdateTextField.setText(StartDate);
salaryTextField.setText(Salary);
emailTextField.setText(email);
}
resultset.close();
statement.close();
connection.close();
} catch ( Exception e1 ) {
System.err.println( e1.getClass().getName() + ": " + e1.getMessage() );
System.exit(0);
}
}});
Thank you for your time and effort.
One of two things is happening. Either:
You have a bug in the code which populates the database, so you think you have rows A, B, and C in the database, but in fact you only have row C
Or:
Your code as listed populates your controls with the contents of row A, then it repeats to populate the exact same controls with contents of row B, and then the exact same controls once more with the contents of row C. So, naturally, the values you are left with are the values of the last row.
It helps to think precisely what it is that you are trying to do, precisely what is happening, precisely what you expected to happen instead, and most importantly, what makes you believe that the code should do that which you expect it to do rather than what it actually does.
This is what I am trying to do
The user enters a string. This gets passed into a java program which then run a query against sql server and tries to find the records where this string occurs. The query that eventually runs against the sql server is something like this
Select * from users where name like '*userPassedInText*'
The problem I have is that if this string has certain characters such as ' the query breaks. I know the ideal way to do this is to use
PreparedStatement statement= con.prepareStatement (myStatement );
But for certain reasons I have to pass in a string. Having said that is there any utility in java that prepares a string to be sent to SQL server?
To answer your immediate question: you simply need to replace all "single quote" characters with TWO single quote characters:
String original ="it's a problem when you have a single quote in SQL params"; // String contains a single quote
String escaped = original.replaceAll("'","''"); // replace all single quotes with 2 single quotes
But I cry for you not to simply take whatever the user passes in (especially given that your variable has the name userPassedInText!!). I would strongly urge everyone to read this:
https://www.owasp.org/index.php/Preventing_SQL_Injection_in_Java
... because if you just take whatever the user types in, then they can type in "some text with single quotes' OR 1==1". And you SQL will return ALL records from your DB table. You definitely want to use preparedStatements. And, as a bonus, you won't have to manually replace single quotes with two single quotes.
i think u could try this way, creating a connection, and giving the query by prepareStatement method:
try {
String url = "jdbc:odbc:databaseName";
String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
String user = "guest";
String password = "guest";
Class.forName(driver);
Connection connection = DriverManager.getConnection(url,user, password);
String changeLastName = "UPDATE authors SET lastname = ? WHERE authid = ?";
PreparedStatement updateLastName = connection.prepareStatement(changeLastName);
updateLastName.setString(1, "Martin"); // Set lastname placeholder value
updateLastName.setInt(2, 4); // Set author ID placeholder value
int rowsUpdated = updateLastName.executeUpdate(); // execute the update
System.out.println("Rows affected: " + rowsUpdated);
connection.close();
} catch (ClassNotFoundException cnfe) {
System.err.println(cnfe);
} catch (SQLException sqle) {
System.err.println(sqle);
}
here original link: http://www.java2s.com/Code/JavaAPI/java.sql/ConnectionprepareStatementStringsql.htm
This is my latest attempt to read a text file into a Netbeans Derby database. The file contains 5 rows with each row containing 7 items delineated by commas. The program runs without any errors but the database is not updated at all. I would appreciate any help in fixing this code.
<% Connection connection = null;
PreparedStatement ps = null;
String urlanddatabasename = "jdbc:derby://localhost:1527/ProgramName
String userName = "root";
String password = "root";
Class.forName("org.apache.derby.jdbc.ClientDriver");
connection = DriverManager.getConnection(urlanddatabasename,userName,password);
try{
String fileName = saveFile;
File file = new File(fileName);
Scanner inputStream = new Scanner(file);
String[] array = new String[7];
Statement statement = connection.createStatement();
while(inputStream.hasNext()){//reads from the file until there are no items left
String data = inputStream.next();
array = data.split(",");
String reportidString = array[0];
String coursenameString = array[1];
String tardiesString = array[2];
String absencesString = array[3];
String totalgradeString = array[4];
String teachernameString = array[5];
String schoolnameString = array[6];
statement.executeUpdate("INSERT INTO report(reportid, coursename, tardies, absences, totalgrade, teachername, schoolname) values(reportidString, coursenameString,tardiesString, absencesString, totalgradeString, teachernameString, teachernameString, schoolnameString)");
}
inputStream.close();
}catch(FileNotFoundException e){e.printStackTrace();}
%>
It seems that you are using this code inside a JSP scriptlet. This is very bad style. Especially for code without any relation to the view representation.
So the first thing you should do, is to create an ordinary Java class and put that code inside. Then you will remark that Class.forName() throws a checked exception (ClassNotFoundException) and some other parts like DriverManager.getConnection(), connection.createStatement() and statement.executeUpdate() throw SQLException. You shouldn't let the servlet container catch these exceptions.
Then write a simple main() method to check if your code is working or even better a JUnit test.
You declared a PreparedStatement variable but never used it. Instead later you used a simple Statement. The first one fits better here. So use something like that:
ps = connection.prepareStatement("INSERT INTO "
+ "report(reportid, coursename, tardies, absences, totalgrade, teachername, schoolname) "
+ "values(?, ?, ?, ?, ?, ?, ?)");
Use the ? as a placeholder for the actual values.
Then later you set the values. Beware that the prepared statement index begins at 1. After the execution of all SQL inserts, you should commit the transaction. In case of an exception use abort().
while(inputStream.hasNext()){//reads from the file until there are no items left
// ...
ps.setString(1, reportidString);
ps.setString(2, coursenameString);
// ...
ps.executeUpdate();
}
connection.commit();
Afterwards you should clean up and free the ressources. The best place is in a finally of a try block:
} finally {
try {
ps.close();
} catch(SQLException e) {
e.printStackTrace();
}
try {
connection.close();
} catch(SQLException e) {
e.printStackTrace();
}
}
Some further considerations:
If you really want to use plain JSP, then make use of the Front Controller pattern. So every request goes to the front controller servlet. There you decide what kind of action to execute and collect the data for the view. In the end forward to a JSP to create the view. Inside the JSP you should not use any scriptlets.
Consider to use a MVC framework like Struts or Spring MVC. But the current standard is Java Server Faces which is more component based.
Use a connection pool for the database connection.
Use logging instead of System.out.println() or e.printStackTrace()
To efficiently insert larger files into the database use batch inserts.
There is a system procedure in Derby that may help:
http://db.apache.org/derby/docs/10.11/ref/rrefimportproc.html
http://db.apache.org/derby/docs/10.11/adminguide/cadminimport16245.html
I inserted one column in sql with null value from java.while retrieving back it is not working with null.i also checked with string.length().But when i printed the value in System.out. the value is showing as null (just null).when i checked it with condition it is not entering into loop.
String id ="1234";
String name="pratap";
String gender=null;
String email=null;
String service="GOOGLE";
log.info(id+name+gender+email) //output is 1234pratapnullnull
String insert = "INSERT INTO oauthuser VALUES('"+id+"','"+name+"','"+gender+"','"+email+"','"+service"')";
In the retrieval
query ="Select * FROM oauthuser where id="+"'"+id+"'";
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection (dbUrl);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
while(rs.next())
{
id=rs.getString(1);
name=rs.getString(2);
gender=rs.getString(3);
email=rs.getString(4);
service_provider_name=rs.getString(5);
System.out.println(gender+email+name);//output is nullnullpratap
}
if(gender!="male" && gender!="female")
System.out.println("it is printing");
if(gender==null)
System.out.println("it is not printing");
con.close();
From your somewhat cryptic description of the problem I suspect that you may have inserted the string "null" rather than the SQL NULL value. The two are not the same (very different, in fact).
edit Having reviewed the code, this is exactly what happens. Take, for example, gender:
String gender = null;
...'"+gender+"',...
The above converts it to 'null' (i.e. the SQL string "null"), and inserts that into the database.
My basic advice would be to read up on PreparedStatement and use that instead of building the SQL query bit by bit as you're doing right now.
Finally, the following is broken:
if(gender!="male" && gender!="female")
This should be
if(!gender.equals("male") && !gender.equals("female"))
you can try "null" instead of NULL , but better to show us the code
after your update
remove + sign from your query like this
String id ="1234";
String name="pratap";
String gender="null";
String email="null";
String service="GOOGLE";
log.info(id+name+gender+email) //output is 1234pratapnullnull
String insert = "INSERT INTO oauthuser VALUES('"id"','"name"','"gender"','"email"','"service"')"
and when you select , modify like this
if(gender.equals("null"))
System.out.println("it is not printing");
Maybe your value is not null but "null" string? Start your application in debug, put break point and check it.