preparedstatement batch fo insert and update? - java

i have query = "select * from user_message where username = 'john777#gmail.com';" . There is a column 'is_read'( When message is sent to user , is_read is false by default , it means user has not read message yet), after first selection i have to change that column to true UPDATE user_message
SET is_read=true where username = 'john777#gmail.com'; Which means user has read message . so question is can i make one query and execute it throught batch or should i make two different queries ? Which way is better ?

You are write one method with two parameters username and is_read. You can call this method any-time when you needed.

I think your update statement is incorrect since it doesn't pass a message id
I'm guessing it's something like:
UPDATE user_message
SET is_read=true
where username = 'john777#gmail.com'
and user_message_id = 123
If you'd like to set multiple messages to read you could do this via:
UPDATE user_message
SET is_read=true
where username = 'john777#gmail.com'
and user_message_id in (123, 234, 456)
This feels like a design flaw to me. Why does the user_message table have the email? What happens if the user changes their email? You should really decouple the email from the user by giving each user a unique (integer) id which you use as a foreign key.

Based on the assumption the you have a Collection of parameters say emails, I would suggest the following:
String sql = "Your statement";
PreparedStatement stmt = conection.prepare(sql);
for(String email : emails){
stmt.setString(1, email);
stmt.executeUpdate();
stmt.clearParameters();
}
This I think will help you.

Related

How to replace a string in a string with integer type in java?

I have a requirement. The technology is quite old doesn't support spring at all . It is pure java application with jdbc connection.
Requirement is :
Suppose
select * from employee where empid = <<empid>> and designation = 'Doctor'
I am trying to replace <> with actual int value in java . How I can do it ?
String query = "select * from employee where empid = <<empid>> and designation = 'Doctor'";
if(query.contains("<<empid>>"))
/// Here I want to replace <<empid>> with actual int value in java
Any leads will be helpful
The code you didn't paste, that actually executes the SQL is either [A] a massive security leak that needs serious rewrites, or [B] is using PreparedStatement.
Here's the problem: SQL injection. Creating the SQL string by mixing a template or a bunch of string constants together with a bunch of user input is a security leak. For example, if you try to make SELECT * FROM users WHERE email = 'foo#bar.com' by e.g. String sql = "SELECT * FROM users WHERE email = '" + email + "'";, the problem is, what if the user puts in the web form, in the 'email' field: whatever#foo.com'; DROP TABLE users CASCADE; EXEC 'FORMAT C: /y /force'; --? Then the SQL becomes:
SELECT * FROM users WHERE email = 'whatever#foo.com'; DROP TABLE users CASCADE; EXEC 'FORMAT C: /y /force'; --';
That is legal SQL and you really, really, really don't want your DB engine to execute it.
Each DB engine has its own ideas on what's actually legal, and may do crazy things such as treating curly quotes as real quotes, etc. So, there is no feasible blacklist or whitelist technology you can think of that will properly cover all the bases: You need to ask your DB engine to do this for you, you can't fix this hole yourself.
Java supports this, via java.sql.PreparedStatement. You instead always pass a fully constant SQL string to the engine, and then fill in the blanks, so to speak:
PreparedStatement ps = con.prepareStatement("SELECT * FROM users WHERE email = ?");
ps.setString(1, "foo#whatever.com");
ps.query();
That's how you do it (and add try-with-resources just like you should already be doing here; statements and resultsets are resources you must always close). Even if you call .setString(1, "foo#whatever.com'; DROP TABLE users CASCADE; --"), then it'll simply look for a row in the database that has that mouthful in the email field. It will not delete the entire users table. Security hole eliminated (and this is the only feasible way to eliminate it).
So, check out that code. Is it using preparedstatement? In that case, well, one way or another that code needs to be calling:
ps.setInt(1, 999);
Where ps is the PreparedStatement object created with connection.prepareStatement(...) where ... is either an SQL constant or at least your input string where the <<empid>> was replaced with a question mark and never with any string input from an untrusted source. The 1 in ps.setInt(1, 999) is the position of the question mark (1 = the first question becomes 999), and the 999 is your actual number. It may look like:
if (input instanceof String) {
ps.setString(idx++, (String) input);
} else if (input instanceof Integer) {
ps.setInt(idx++, ((Integer) input).intValue());
} ...
etcetera. If you don't see that, find the setInt invoke and figure out how to get there. If you don't see any setInt, then what you want is not possible without making some updates to this code.
If you don't even see PreparedStatement anywhere in the code, oh dear! Take that server offline right now, research if a security leak has occurred, if this server stored european data you have 72 hours to notify all users if it has or you can't reasonably figure out e.g. by inspecting logs that it hasn't, or you're in breach of the GDPR. Then rewrite that part using PreparedStatement to solve the problem.

Sql query error in java program

I have developed a java program and I need to update and insert the login details of users. I have two textfields created and two buttons name add user and edit the user. when I type the username and password in the two textfields the user added to the database successfully, the error is in the edit user, I want to update the password of the user based on username,
I'm getting SQL error when trying to update the user,
here is my SQL query for updating the password of a user based on his username,
String sql = "UPDATE Admin SET password='"+JT_pass1.getText()+"' WHERE
username = "+JT_username1.getText();
when i execute im getting this error,
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column
'sss' in 'where clause'
"sss" is what I entered to username field,
Mysql database I have admin table which consists of two columns admin and username,
I cannot figure out where am I getting wrong, please any help would be highly appreciated.
Your immediate problem is that you forgot to place single quotes around the username in your query. Hence, the database is interpreting sss as a column. But you should really be using prepared statements:
String query = "UPDATE Admin SET password=? WHERE username = ?";
PreparedStatement update = con.prepareStatement(query);
update.setString(JT_pass1.getText());
update.setString(JT_username1.getText());
update.executeUpdate();
There are many advantages to using prepared statements. First, it will automatically take care of proper escaping of strings and other types of data. In addition, it will prevent SQL injection from happening.
To get this to work, you need to add quotes around the username like so:
String sql = "UPDATE Admin SET password='"+JT_pass1.getText()+"' WHERE
username = '"+JT_username1.getText()+"'";
However, updating the database this way is vulnerable to SQL injection, so it would be much better to use Prepared Statements.
To consider "JT_username1.getText()" as a part of you query string, you have to enclose it under proper quotation.
Same like added "JT_pass1.getText()" between single and double quote, you have to add "JT_username1.getText()" as well.
String sql = "UPDATE Admin SET password='" + JT_pass1.getText() + "' WHERE username = '"+JT_username1.getText()+"'";

Spring JdbcTemplate with parameter returns empty List

I can't understand what wrong with it, i spent many hours trying to get my String object from method queryForList(..) and all for nothing. So here this stupid sql query:
String GET_EMAIL_BY_LDAP = "select ld.LDAP_EMAIL1 from IPS.ldap ld where ld.ldap_login = ?"
I have tried this also without '?' parameter and it is works perfectly.
Here is the way, how I use the method:
List<String> email = jdbcTemplate.queryForList(GET_EMAIL_BY_LDAP, String.class, userId.toUpperCase());
And this version of method also returns empty List:
List<String> email = jdbcTemplate.queryForList(GET_EMAIL_BY_LDAP, new Object[]{userId.toUpperCase()}, String.class);
P.S. getEmailById("DN270391RKA") - this is my user id parameter that passed. It hasn't spaces.
Type of ld.LDAP_EMAIL1 field in table is : NVARCHAR2(381 CHAR)
I have understood what it was!
ld.ldap_login values in my ( legacy :-D ) table have a tailing spaces. After minor editing of my sql statement it works. I just added TRIM() on this column.
"select ld.LDAP_EMAIL1 from IPS.ldap ld where TRIM(ld.ldap_login) = ?"
So, it seems if it is usual sql statement then when I execute query then oracle database does TRIM() automatically and in case of PreparedStatement doesn't.
List<String> email = jdbcTemplate.queryForList(GET_EMAIL_BY_LDAP, String.class, userId.toUpperCase());
This line is fully correct so it seems to be either a bad userID or your sql query is not correct.
Best way is to paste your sql query with an existing user id in your query browser and check if you get more than an empty result.
then use the jdbc template again and pass hardcoded previously working user id and check if you get the same results.
or: delete the userid clause and select all not specific to the user id.
Also make sure the ld.LDAP_EMAIL is String representation e.g varchar/text

How can I avoid entering duplicate entries in my MySQL database?

So, what I'm trying to do here is check the user table in my users mySQL database for duplicate entries in the username row, before inserting a new username. Here's an example of my code. Currently, the results ResultSet does not do anything and I'm not exactly sure how to implement it into the IF statement that follows. And yes, I have the catches for the try, just not in this example. Sorry if this is a rather simple question, I just started programming with Java last week. Also, it's my first question on here and I definitely appreciate the help.
try{
String sequel = ("SELECT username FROM `users`.`user`");
PreparedStatement userNameInfo = conn.prepareStatement(sequel);
userNameInfo.executeQuery(sequel);
ResultSet results = userNameInfo.getResultSet();
if (sequel.equals("")) {
conn.setAutoCommit(false);
String sql = "INSERT INTO `users`.`user`(`username`,`password`,`email`) VALUES('" + newusername +"', '" + newpassword + "', '" + newemail +"')";
PreparedStatement prest = conn.prepareStatement(sql);
prest.executeUpdate(sql);
conn.commit();
conn.close();
System.out.println("Added Successfully!");
}
else {
System.out.println("Add failed!");
}
}
So I think what you trying to do - and should do I think, is select if the username is in the table then add or not. So the sql needs to be like:
select username from users where username = ?
then set the param in the query. See docs here:
http://docs.oracle.com/javase/6/docs/api/java/sql/PreparedStatement.html
You then need to check what is in the resultset after the query, and see if anything is in there. The API docs for this will be in about the same place as the PreparedStatement docs.
Adding a constraint in the db will also give you a belt and braces.
Hope this helps
When you define your SQL table, you can define some items to be unique.
So in your example, if you want usernames to be unique, you would add:
UNIQUE(username)
to your table declaration.
If you want the pair username / email to be unique, you would add:
UNIQUE(username, email)
The documentation is here
Have you created the primary key in the table? A primary key automatically prevents duplicate values.
If you want to prevent duplicate usernames, then make your username column the primary key.
Umm, I am not a java guy. But this may help you.
You can retrieve the row count of the first result set after the query executes. If the row count is equal to 0, that means database does not contain a similar record.

Generating a dymamic sql SELECT statement

I'm having some small trouble trying to dynamically generate an SQL SELECT statement generated from an entry from a webpage.
Basically i have a small search engine in the website, it accepts three parameters (price,city,brand), so i have a JavaBean built in the same way with only 3 attributes, the same ones.
When performing a SELECT on the database i could make it this way using PreparedStatement
String sql=select * from product where price<=? and city=? and brand=?;
prep=conn.prepareStatement(sql);
prep.setDouble(1,price);
prep.setString(2,city);
prep.setString(3,brand);
where prep is of course a PreparedStatement obj
My problem comes when the user does not insert a parameter in the field of the web page, because apparently he is not interested on a limitation.
I need to find a way to "cut" the entry at runtime, like:
city field=""? then take out city from the search criteria:
String sql=select * from product where price<=? and brand=?;
One way i could do that is filling in the code in the servlet with else-if but thats not the only solution i'm sure.
Another potential solution would be to use IFNULL(expr1,expr2) function of SQL but in case is null, then i should just remove the null-field from the query.
Do you have any advice?
i hope its clear enough the way i explained it.
You can use OR in your WHERE clause to do something like:
WHERE (Price<=? OR ? IS NULL)
AND (City = ? OR ? IS NULL)
AND (Brand = ? OR ? IS NULL)
Try to replace condition "=" with Like '%[input_value]%'. In this way if uset left blank field you don't have any restriction.
You can use like for strings.
String sql = "SELECT * FROM product WHERE price <= ? AND city like '?' AND brand like '?'";
prep = conn.prepareStatement(sql);
prep.setDouble(1, price);
prep.setString(2, city);
prep.setString(3, brand);
See Exact match with sql like and the bind
And in case city/brand is not selected, then set it
prep.setString(2, "%");
prep.setString(3, "%");
If price is not selected, then use some very big number.

Categories