This is probably a easy question for you guys but I'm trying to access a variable set by an SQL statement to then be passed into another SQL statement in another class.
The idea is that when the user logs in, I get their StaffID then I want to use that number in another SELECT statement.
I've tried to make the variable public and access it from the other class but it returns empty.
LOGIN CODE:
public static String StaffID;
// SignIn ActionListener
signIn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try{
Class.forName(DRIVER);
// Connection to the Database
con = DriverManager.getConnection(DATABASE_URL,"root","");
// Gets text from textfields and assigns them to variables
s1 = tfUsername.getText();
s2 = tfPassword.getText();
Statement st = con.createStatement();
// SQL Statements
st.executeQuery("SELECT * FROM login WHERE UName= '"+s1+"' and PWord = '"+s2+"'");
// Extracts data from statement to a result set
ResultSet rs = st.getResultSet();
if (rs.next())
{
// Gets text from Textfields and assigns them to variables
StaffID = rs.getString("StaffID");
}
OTHER CLASS:
try{
Class.forName(DRIVER);
// Connection to the Database
con = DriverManager.getConnection(DATABASE_URL,"root","");
signIn sign = new signIn();
//Creates Statement Connection
Statement st = con.createStatement();
// SQL Statements
st.executeQuery("SELECT * FROM rota WHERE StaffID = '"+sign.StaffID+"'");
// Extracts data from statement to a result set
ResultSet rs = st.getResultSet();
if (rs.next()) {
tfRotaTask1.setText(rs.getString("Task1"));
tfRotaTask2.setText(rs.getString("Task2"));
tfRotaTask3.setText(rs.getString("Task3"));
tfRotaTask4.setText(rs.getString("Task4"));
tfRotaTask5.setText(rs.getString("Task5"));
tfRotaTask6.setText(rs.getString("Task6"));
tfRotaTask7.setText(rs.getString("Task7"));
tfRotaTask8.setText(rs.getString("Task8"));
}
else{
//JOptionPane.showMessageDialog(null, "Staff Member Not Found");
}
To put this into context, I'm making a staff managment rota system.
Sorry if my Java seems poor :(
Any help will do.
Ok first thing first, wrap your Queries in One Class for more easy use.
public class QueryUtils
{
public static String staffId(...yourArgs)
{
String staffId = "";
// Make the logic for getting the StringId
return staffId;
}
}
Ok so you can call this query from anywhere in your application. Even from other queries. Use basic OOP and Patter Desings and you will solve this issues.
you don't inti the value of the StaffID until the condition of rs.next() is be true
try to make else statement like this
if (rs.next())
{
// Gets text from Textfields and assigns them to variables
StaffID = rs.getString("StaffID");
}
and then test the value of the StaffID in the other class if it null then you have somthing wrong in the executeQuery
because i don't see any thing wrong in your code
Related
Well, I needed to take values from the database, and insert them into the combobox for selection.
Sounds easy enough to do just using 2 classes, UI class and Entity class, which contains all the SQL queries inside (anything to do with database, it's in there):
//This is the UI class
public void fillComboBox(){
Entity et = new Entity();
try{
//call out dbConnector method from Entity class
conn = et.dbConnector();
String query="select distinct Name from DbTable order by Name";
PreparedStatement pst = conn.prepareStatement(query);
ResultSet rs = pst.executeQuery();
while(rs.next()){
//shows topic data in combobox
comboBoxName.addItem(rs.getString("Name"));
}
}
catch(Exception e){
e.printStackTrace();
}
}
//runs method
fillComboBox();
Now, the above output works fine with no hitches. In my form, the combo box displays unique values taken from my database in my specified column.
The problem comes when implementing another tier within it.
In short, I have three classes now.
Class 1: UI -> this class purely handles UI
Class 2: Controller -> this class purely runs methods
Class 3: Entity -> this class purely runs anything that have to do with sql database queries
What I did, was to modify the above code, into this:
This is the UI class:
//Declare Variables
JComboBox comboBoxName = new JComboBox();
Controller ct = new Controller();
comboBoxName.addItem(ct.fillComboBox());
And a certain method within the Controller class:
//Declare Variables
Entity et = new Entity();
public String fillComboBox(){
return et.takeNames();
}
Lastly, my Entity class, which contains all sql queries within.
//Declare all variables first
Connection conn = null;
String task = null, names = null;
String query;
//This method connects to database
//There's nothing wrong with this method, I just placed it here to give a general overview of what this method exactly is for you to understand, as I will be calling it out later. Yes, I removed off the **URL** portion intentionally.
public static Connection dbConnector(){
try{
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite:URL");
JOptionPane.showMessageDialog(null, "Connected!");
return conn;
}
catch(Exception ex){
JOptionPane.showMessageDialog(null, ex);
return null;
}
}
public String takeNames(){
try{
conn = dbConnector();
query = "select distinct Name from DbTable order by Name";
PreparedStatement pst = conn.prepareStatement(query);
ResultSet rs = pst.executeQuery();
while(rs.next()){
//shows Name data in combobox
names = rs.getString("Name");
}
pst.close();
}
catch(Exception ex){
ex.printStackTrace();
}
return names;
}
Well, basically, how this "new" implementation runs is that, the UI class calls out the Controller class, which calls out the Entity class, which runs the method inside and parse back values all the way to UI.
This method is useful in the sense that it separates different portions of a program, making it look neater. Too bad it is a headache to implement. >.>
Now, the error in this would be that, it will retrieve only 1 value, instead of multiple values. What it does retrieve is the very first 'distinct' value in that particular column I specified. The remaining 'distinct' values are ignored.
I have a hunch it had everything to do with the rs setting, #:
ResultSet rs = pst.executeQuery();
What I had in mind was that it only takes 1 value and sets it, then ignores the rest. Does anyone have any solutions for this? I tried arraylist but failed on how to store numerous rs values in the arraylist (this really stumped me >.>)
I do apologize for the lengthy post, but I tried my best to do up till what I can, before I got stuck at this part for hours.....
modify takeNames() as follows
public ArrayList<String> takeNames(){
//This will collect all names from db
ArrayList<String> names = new ArrayList<>();
try{
conn = dbConnector();
query = "select distinct Name from DbTable order by Name";
PreparedStatement pst = conn.prepareStatement(query);
ResultSet rs = pst.executeQuery();
while(rs.next()){
//shows Name data in combobox
//Add data to the array list
names.add(rs.getString("Name"));
}
pst.close();
}
catch(Exception ex){
ex.printStackTrace();
}
//Return the array list you created
return names;
}
Modify fillComboBox() as follows
public ArrayList<String> fillComboBox(){
return et.takeNames();
}
And modify the rest as follows
JComboBox comboBoxName = new JComboBox();
Controller ct = new Controller();
ArrayList<String> nameList = ct.fillComboBox();
for(String name : nameList){
comboBoxName.addItem(name);
}
Code snippet:
On a button click, actionevent will be called
public void actionPerformed(ActionEvent e)
{
Function f = new Function();
Function is a nested class which i have used to establish the connection with the database.
The code snippet for function class is also provided in the end.
ResultSet rs = null;
String Cid ="cust_id";
String Pno="cust_phone";
String cat="cust_cat";
String start_date="st_date";
String Adv_amt="adv";
String Adv_end="end_date";
String Address="addr";
t2 is the Textfield name which i have used to get entry of customer name. I want to use this customer name as a PK to fetch all the other data about that customer from DB.
rs=f.find(t2.getText());
try{
if(rs.next())
{
t1.setText(rs.getString("cust_id"));
t3.setText(rs.getString("cust_phone"));
t4.setText(rs.getString("cust_cat"));
t5.setText(rs.getString("st_date"));
t6.setText(rs.getString("adv"));
t7.setText(rs.getString("end_date"));
t8.setText(rs.getString("addr"));
}
else
JOptionPane.showMessageDialog(null,"No data for this name");
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null,ex.getMessage());
}
}
Here is the code snippet for nested class Function which is inside the main class:
class Function{
Connection con=null;
ResultSet rs= null;
PreparedStatement ps = null;
public ResultSet find(String s)
{
try
{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
con = DriverManager.getConnection("jdbc:oracle:thin:#Localhost:1521:xe","system","qwerty");
ps= con.prepareStatement("Select * from gkkdb where cust_name='?'");
ps.setString(1,s);
rs= ps.executeQuery();
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null, ex.getMessage());
}
return rs;
}
}
Please help figure out the problem.
Don't put the parameter placeholder ? in single quotes.
This:
ps = con.prepareStatement("Select * from gkkdb where cust_name='?'");
should be
ps = con.prepareStatement("Select * from gkkdb where cust_name = ?");
The ? is not recognized as a placeholder if you enclose it in single quotes.
Sorting out the bind variable will fix your immediate issue.
You should explicitly specify what columns you want selected and that way you'll only get what you need (someone might add a BLOB column later) and you'll get them in the right order (someone might change the table create script before running on another DB instance, although you are looking up the columns by name, a different order would only impact if you were using positional indexes).
Ditto on the other answer re: bind variables (i.e. no quotes)
Plus, "select * from" is never a good idea, ask your DBA.
Obviously your code is for example, but you should make sure you free up any resources (Connection, Statement, ResultSet) as soon as they are done with. Use Java 7 try-with-resources.
i have a question: i am trying to make an insert-query with in java using the jdbc for mysql. I think my code is correct, but somehow i can't run the method i call in my main class. Here's my method i wanna call code:
public void wijzigAfspraak() {
try {
Statement stmt2 = conn.createStatement();
String query2 = "";
rs = stmt2.executeQuery(query2);
System.out.println("query uitgevoerd");
while (rs.next()){
String titel = rs.getString(1);
String datum = rs.getString(2);
int urgentie = rs.getInt(3);
String beschrijving = rs.getString(4);
System.out.println(titel+datum+urgentie+beschrijving);
}
}
catch (SQLException e){
e.printStackTrace();
}
}
here is my main class:
public class Main {
public static void main(String[] args){
AfspraakDaoImpl adi = new AfspraakDaoImpl();
Afspraak afs = new Afspraak("","",1,"");
afs.setTitel("hond");
afs.setAfspraakDatum("12juni");
afs.setUrgentie(123);
afs.setBeschrijving("test");
adi.voegAfspraakToe();
adi.wijzigAfspraak();
}
my console doesn't print anything and my database shows no difference in data, which means it didn't work right?
Thanks in advance!
Looks like you're executing empty SQL query here:
String query2 = "";
rs = stmt2.executeQuery(query2);
If you want to execute INSERT statement, You should invoke executeUpdate() method on you statement object stmt2 and pass SQL string as a parameter.
Moreover, consider using PreparedStatement instead of Statement as follows:
String sql = "INSERT INTO foo(value) VALUES(?)";
try (PreparedStatement ps = connection.prepareStatement(sql)) {
ps.setString(1, "bar");
ps.executeUpdate();
} catch (SQLException e) {
// handle error
}
One more thing. Looks like you keep ResultSet rs as a class field. Don't do so, try to minimize number of mutable state variables of your class, try to keep your components light and stateless. It's better to keep Statement and ResultSetin try-with-resources block.
Since you're using a DAO and using MYSQL Database ( witch is not specified here ;) ):
public void wijzigAfspraak(String 1, String 2, String 3, etc..) {
try {
Statement stmt2 = conn.createStatement();
String query2 = "insert into afspraken (column_1, column_2, etc...) values ( String 1, String 2, etc..)"; --> these values come from the wijzigafspraak(String 1, String 2, etc..)
stm2.executeUpdate(query2);
System.out.println("query is inserted correctly");
You do not want to use the rs.next(), witch is used for a "SELECT-STATEMENT", you do not receive data, vut you insert it.
then, your main class:
public class Main {
public static void main(String[] args){
AfspraakDaoImpl adi = new AfspraakDaoImpl();
Afspraak afs = new Afspraak("","",1,"");
afs.setTitel("hond");
afs.setAfspraakDatum("12juni");
afs.setUrgentie(123);
afs.setBeschrijving("test");
//adi.voegAfspraakToe();//this is not specified?? and probably does not work either
adi.wijzigAfspraak(afs.getTitel(), afs.getAfspraakDatum(), etc..);
where is your sql statement ? It should be :
String query2 = "select titel,datum,urgentie,beschrijving from Afspraak";
I created a Stored Procedure where I can fetch all my data that I inserted in my following textfields. How can I fetch all of this data by calling my Callable Statement? I think this is the easiest way than Batch Statement based on what I read. I only drag and drop this following components just a practice purposes.
Stored Procedure
CREATE PROCEDURE show_data(OUT FULLNAME VARCHAR(50), OUT ADDRESS VARCHAR(50))
PARAMETER STYLE JAVA
LANGUAGE JAVA
READS SQL DATA
DYNAMIC RESULT SETS 1
EXTERNAL NAME 'Frame.searchButton'
I used OUT parameter to retrieve values using getXXX() methods. I'm just little bit confuse since this is my first time to use Stored Procedure in derby.
GUI
After the user search the following record in Database. If the value exist it will print to the designated textfields.
SOURCE CODE
String searchRecord = searchTf.getText();
String searchQuery = "SELECT * FROM SAMPLEONLY";
ResultSet data[] = null;//Why should I use this array?
try (Connection myConn = DriverManager.getConnection(url, user, pass);
PreparedStatement myPs = myConn.prepareStatement(searchQuery);)
{
String addFullname = fullnameTf.getText();//first field
String addAddress = addressTf.getText();//second field
data[0] = myPs.executeQuery();
CallableStatement cs = myConn.prepareCall("{ call showData(?, ?)}");
cs.setString(1, addFullname);
cs.setString(2, addAddress);
boolean hasResults = cs.execute();
if (hasResults) {
ResultSet rs = cs.getResultSet();
while (rs.next()) {
String getFullname = rs.getString(1);//get the value
String getAddress = rs.getString(2);
fullnameTf.setText(getFullname);//set the text here
addressTf.setText(getAddress);
}//end of while
rs.close();//close the resultset
}//end of if
}//end of try
catch (SQLException e)
{
e.printStackTrace();
}
}//end of else
}
After I insert in Search textfields it throws me a error NullPointerExeption. I follow Derby Reference Manual so I can have a guide writing a proper Stored Procedure. This code is mine most of the part. Guide me if I missed something wrong. Feel free to comment thanks.
I want to fill the jComboBox with values from database. and these values depend on the text written in the textfield.
eg: if I write a in the texfield, the combobox will have all values starting with a. The values are from a databse
Here's my code:
private void FillCombo(){
String url = "jdbc:mysql://localhost:3306/pharmacy";
String driver = "com.mysql.jdbc.Driver";
String user = "root";
String pass = "test";
String sql = "select medicinename from medicine where medicinename like '%"+jTextField5.getText()+"%'";
try{
Class.forName(driver).newInstance();
System.out.println("1");
Connection con = (Connection)DriverManager.getConnection(url,user,pass);
System.out.println("Connected");
Statement st=(Statement) con.createStatement();
PreparedStatement pst = con.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
while(rs.next()){
String name = rs.getString("medicinename");
jComboBox1.addItem(name);
}
} catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}}
I want not just one caracter eg: if i write a, as, asp it fill aspirine myproblem is that the combobox is already filled. want it empty when i start.
Simply use JComboBox#removeAllItems() to removes all items from the item list on each stroke of any key in the JTextField.
Points to Remember
Don't load driver each time you enter a new character. Move it outside the FillCombo() method.
Use PreparedStatement instead of using single quoted query string that may cause issue. Find a sample on Using Prepared Statements
Don't forget to close the resources such as connection, result set and statement.
Use finally block to handle it or Read more about Java7 -The try-with-resources Statement