MySQL Selecting Status from Database Issue - java

Ok, so I am a little new to MySQL querys and I am wondering if this would be the correct syntax to get if a value is false in a row.
"SELECT `status`
FROM `friends`
WHERE `requester`= '"+requester+"'
AND `requested` = '"+requested+"'
AND `status`= 'false'";
If that is wrong, I'm trying to fetch the requests where you are the requester and the status is false through a java method.

first thing i would do is check to be sure the variables contain what you want them to. maybe even put in the data directly to the query at first without variables. get it to what you want it to be.
System.out.println("the requester is: ");
System.out.println(requester);
System.out.println("the requested is: ");
System.out.println(requested);
"SELECT 0 FROM friends WHERE requester= '"+requester+"' AND requested = '"+requested+"' AND status= 'false'"
generally 0 is false and 1 is true in programming languages so you can just pull out a 0 when its false.
you may want to also do a like comparison on the requester and requested. you could do it on the status column if you want but that shouldn't be necessary
"SELECT 0 FROM friends WHERE requester LIKE '%"+requester+"%' AND requested LIKE '%"+requested+"%' AND status= 'false'"

Your query want work only if there is some white space char in your value else your query is fine to check try this use like
SELECT status FROM friends WHERE requester= '"+requester+"' AND requested = '"+requested+"' AND status like '%false';

try this man
status is false
in your case, false is a string, not a boolean

Related

Login Function Improvement and Solve Looping Issue

I am new. Trying to do a database retrieve demo to login a system, here is my function code:
I will call goLogin function and pass in the input id and password for validation and I will also get all the id from Database for checking purpose. After ID is correct, only go check the password.
public void goLogin(String id, String pass){
String[99] allID = getAllIDFromDB();
for(int i=0;i<allID.length;i++){
if(allID[i]==id){
String passwordDB = getPasswordFromDB(id);
if(pass==password){
System.out.println("Correct Password");
}else{
System.out.println("Wrong Password");
}
}
}
My peers say I was using too much if else and I can shorten the code and make the program better, and I faced some issue on looping for example when ID and Password are correct, the program will still continue the loop.
Is there any suggestion to make this function better?
First of all, Why retrieve all the user IDs from the database instead make sql query to retrieve the row of this user based on this id.
something like this:
Select * from `users` where id = {id};
And if you want to stop looping a wrong password was found, add break in the else scope.
In my opinion, the main issue of your program is your logic to implement the Login Function.
Login Function implementation can be implemented with various pattern, Based on your program code I will assume you just want a Most Basic Login Function that allow the program to do validation on user input ID and Password.
Actually, this Basic validation can be done in your Database Query. You can just take the user input ID and Password and let Database Query to do filtering and determine if the user input ID and Password is valid or invalid.
First use this Query:
Select DATABASEID From Database Where DATABASEID=inputID and DATABASEPASSWORD=inputPassword;
Java Code:
public void goLogin(String id, String pass){
// Since i changed the Query, you need to pass in the ID and Password to let the Query to filtering
String DatabaseID = getIDFromDB(id, pass);
// Simple Logic, If DatabaseID have value which mean the ID and Password is correct
// Because the Database Query will return null if the ID and Password is Wrong
if(DatabaseID!=null){
System.out.println("ID and Password is Correct.");
}else{
System.out.println("ID or Password is Incorrect.");
}
}
This Logic is very simple, but also come with some drawback, the only Advantage Compare to your code are:
Still able to do basic validation on User Input ID and Password.
Remove for loop and other unnecessary if else.
Only access database for once.
Hope this would help.
Yes, you could even do:
Select * from `users` where id = {id} and password = {password}
Also, to compare Strings in Java, you should use string1.equals(string2), not the == operator.

Automatically generated database requests

How do you implement automatically generated database (let it be SQL) requests?
Let us have offline shop with filters:
The database is standalone offline.
SO if I want to filter items by Price the request would be something like:
select Snowboard.Name
from Snowboard
where Snowboard.Price between 400 and 600;
And if I filter by two characteristics e.g. Price from and Camber. There would be:
select s.Name, s.Camber
from Snowboard s
where s.Price between 400 and 600
and s.Camber in ('Rocker', 'Hybrid');
The question is how could it be implemented in Java so that these requests are generated automatically from any combination of filters selected?
Quick and dirty solution #1
Generate a query at run time & make clever use of WHERE 1=1 condition as the number of where clause are unknown. (This sample is in C# but works more or less the same with JAVA as well)
string sql= #"select Snowboard.Name
from Snowboard
where 1=1";
Now you can build your query based on the UI element selections like
string whereClause="";
if(yourCheckBoxPrice.Checked)
{
whereClause+= " AND Price BETWEEN "+ txtPriceFrom.Text + " AND "+ txtPriceTo.Text;
}
if(yourCheckBoxCamber.Checked)
{
whereClause+= " AND Camber IN ("+ /* your list of values go here */ +")";
}
sql += whereClause;
2nd Solution (Use SQL CASE)
You can use SQL CASE inside your query for each where clause to check for nulls or specific values. But beware, dynamic SQL will make your code pretty messy & hard to read (Can be done via a stored procedure as well)
SQL- CASE Statement
I advise you to use a stored procedure with a mix of both options 1 and 2. Implementing Dynamic SQL Where Clause. Keep it simple and you are good to go.

How to get last status message of each record using SQL?

Consider the following scenario.
I have a Java application which uses Oracle database to store some status codes and messages.
Ex: I have patient record that process in 3 layers (assume 1. Receiving class 2. Translation class 3. Sending class). We store data into database in each layer. When we run query it will show like this.
Name Status Status_Message
XYZ 11 XML message received
XYZ 21 XML message translated to swift format
XYZ 31 Completed message send to destination
ABC 11 XML message received
ABC 21 XML message translated to swift format
ABC 91 Failed message send to destination
On Java class I am executing the below query to get the last status message.
select STATUS_MESSAGE from INTERFACE_MESSAGE_STATUS
where NAME = ? order by STATUS
I publish this status message on a webpage. But my problem is I am not getting the last status message; it's behaving differently. It is printing sometimes "XML message received", sometimes "XML message translated to swift format", etc.
But I want to publish the last status like "Completed message send to destination" or "Failed message send to destination" depending on the last status. How can I do that? Please suggest.
You can use a query like this:
select
i.STATUS_MESSAGE
from
INTERFACE_MESSAGE_STATUS i,
(select
max(status) as last_status
from
INTERFACE_MESSAGE_STATUS
where
name = ?) s
where
i.name = ? and
i.status = s.last_status
In the above example I am assuming the status with the highest status is the last status.
I would recommend you to create a view out of this select query and then use that in your codebase. The reason is that it is much easier to read and makes it possible to easily select on multiple last_statuses without complicating your queries too much.
You have no explicit ordering specified. As the data is stored in a HEAP in Oracle, there is no specific order given. In other words: many factors influence the element you get. Only explicit ORDER BY guarantees desired order. And/or creating a index on some of the rows.
My suggestion: add a date_created field to your DB and sort based on that.

DynamoDB's withLimit clause with DynamoDBMapper.query

I am using DynamoDBMapper for a class, let's say "User" (username being the primary key) which has a field on it which says "Status". It is a Hash+Range key table, and everytime a user's status changes (changes are extremely infrequent), we add a new entry to the table alongwith the timestamp (which is the range key). To fetch the current status, this is what I am doing:
DynamoDBQueryExpression expr =
new DynamoDBQueryExpression(new AttributeValue().withS(userName))
.withScanIndexForward(false).withLimit(1);
PaginatedQueryList<User> result =
this.getMapper().query(User.class, expr);
if(result == null || result.size() == 0) {
return null;
}
for(final User user : result) {
System.out.println(user.getStatus());
}
This for some reason, is printing all the statuses a user has had till now. I have set scanIndexForward to false so that it is in descending order and I put limit of 1. I am expecting this to return the latest single entry in the table for that username.
However, when I even look into the wire logs of the same, I see a huge amount of entries being returned, much more than 1. For now, I am using:
final String currentStatus = result.get(0).getStatus();
What I am trying to understand here is, what is whole point of the withLimit clause in this case, or am I doing something wrong?
In March 2013 on the AWS forums a user complained about the same problem.
A representative from Amazon sent him to use the queryPage function.
It seems as if the limit is not preserved for elements but rather a limit on chunk of elements retrieved in a single API call, and the queryPage might help.
You could also look into the pagination loading strategy configuration
Also, you can always open a Github issue for the team.

Data not updating in JFrame in Java Netbeans

In my email management system, I am retrieving data from MySQL database into Java netbeans. But it is only showing the data for one person. It should move on to next row on each rs.next(), but it is not seemingly. Following code is written in the "Next" Button, which moves on to the next selection in a JList.
try {
DefaultListModel model = new DefaultListModel();
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection( "jdbc:mysql://localhost:3306/email management system","root", "ok" );
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from inbox,curlogin where inbox.rmail like curlogin.mail;");
String fname="";
list.setSelectedIndex((list.getSelectedIndex()+1));
rs.next();
fname = rs.getString("name");
String sender = rs.getString("First");
String reciever = rs.getString("recipent");
String sub = rs.getString("subject");
String msg = rs.getString("message");
String mail = rs.getString("Email");
Date d = rs.getDate("Date");
Timestamp ls = rs.getTimestamp("Seen");
Time t = rs.getTime("Time");
subject.setText(sub);
message.setText(msg);
date.setText(""+d);
time.setText(""+t);
lseen.setText(""+ls);
email.setText(mail);
// TODO add your handling code here:
} catch (ClassNotFoundException | SQLException ex) {
Logger.getLogger(inbox.class.getName()).log(Level.SEVERE, null, ex);
}
user2642282's answer is technically correct but it is lacking explanation and user2642282 misunderstood what your attempting to do. Your half way to the solution with your code but it requires some changes. Lets start with this:
rs.next()
What your doing here is accessing the result set and normally you would write your code like this to loop through all the returned results:
ResultSet rs = stmt.executeQuery("your SQL statement here");
while (rs.next()) {
fname = rs.getString("name");
//...all your original code here
email.setText(mail);
}
Notice how the code is basically exactly the same as your original code except we added the while loop. Normally this would allow you to write out, display, or store each record (email in this case) returned by the query however you want/ need to do something different. So I'll explain what options I think you have next but first here is a link to the Java Docs that will teach everything you need to know about the above code.
Option 1 - Traditional Way
The way most email desktop app's handle this is simply to load all the emails and store them on the file system. This would mean that you need to change your code to load all emails at certain times. Maybe at startup and then every 60 seconds after that check for new messages (usually you should limit checking to no lower than 5 minutes). Then when a user opens a message you load it from its file. When they press next or previous you simply load in the next or previous email from the file system. So your email app is more of a file reader that parses email files and loads their content into your window. You will need to devise a filing system as well. For example naming and saving the emails as their timestamp making it easy to find the next and previous emails. You will also have to deal with deleted emails.
Option 2 - Easy but Bad Practice
Without having to change your code to much you could track which row from the database you read last and run the SQL query every time the user presses the next or previous buttons. You would use the same code your originally posted but add the following:
Check for when next() returns false meaning there is no next or previous email
Add in a variable that keeps track of the last row you read from in the database
Change your SQL query to only return the next or previous row
Option 3 - Hybrid
You could attempt to change your code to the one I showed you and do a hybrid of option 2. What you would do is track the next and previous 10 rows from the database for example. So lets say you last read from row 50. You would run the code I gave you and save all the emails from row 40 to row 60. You have two options for saving the emails:
File system which creates a bit more work but saves memory.
As objects that could take a lot of memory but is easy and fast.
EDIT - Answer to question from comments
Here is how I imagine your code working using option 2 or 3. Notice that ... means I left out code you already have but would just get in the way of this example:
int lastRowRead = 0; // starts as 0 when the program starts
//...all your original code here
ResultSet rs = stmt.executeQuery("...LIMIT "+ lastRowRead +",20;");
if(rs.next()!=false) {
fname = rs.getString("name");
//...all your original code here
email.setText(mail);
}
This code is for option 3. The int lastRowRead should be a global variable that you can keep track of and change each time you run a query to get more messages. You will need to figure out how to catch errors, for example trying to query a row number that doesn't exist. I won't help you code this because it is a good learning opportunity. NOTE: In case you are not familiar with SQL LIMIT here is another example:
....LIMIT 40, 20;
What this means is go to row 40 in the table and read the next 20 rows. So it will return emails from 40 to 60. So if you want to go the super easy but not at all efficient route your SQL query could have:
...LIMIT 40, 1;
This will only return the row number requested. So all you have to do is track which row you last read from and add or subtract 1 from it and run the query again to get the next or previous email.
You are missing a loop that iterates over the resultset. The call
rs.next()
gives you the first row of your SQL result. Try to loop over the results using until rs.next() returns false
two points:
one: if JList current selected value has not changed, when you click next button , you should change your sql , then you can see one's email one by one. at the end of your sql, you should add
select * from inbox,curlogin where inbox.rmail like curlogin.mail limit #{offset} 1
to fix your sql . the offset is a veriable from 0,1,2,3.... it represents one's email from 1 to N
two: you haven't show some event code about JList after selected value was changed. if it was changed , your should get the selected item, and pass it to your sql to filter person's email. so your sql should accept person's name .

Categories

Resources