Hi i am trying to use an Access data bases within java and i am having a spot of trouble. below i have set up a connection to my database.
public class DBAccess {
DBAccess() {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=CFPDB.mdb;";
Connection conn = DriverManager.getConnection(database, "", "");
Statement s = conn.createStatement();
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}
I need to access the 's' variable form with my gui class in order to check a password:
else if(event.getSource() == loginSubmitButton){
DBAccess loginCheck;
String selFromTable = "SELECT PASSWORD FROM USERS WHERE USERNAME = '" + loginUsername.getText() + "'; ";
loginCheck.s.execute(selFromTable);
ResultSet retrievedPassword = loginCheck.s.getResultSet();
String password = retrievedPassword.getString(1);
String password_entered = loginPassword.getText();
}
But my compiler says it can't find symbol - variable 's'.
Class DBAccess is in a separate file to my gui, but are both in the same package. any help would be great. :)
Java doesn't work like this, each variable has its own scope, indicating where is it defined, where is it prone to be used and when will be collected by Garbage Collector. In general, a good way to remember it at the begining is that variable will only 'live' while inside the nearest brackets {}.
In this case, your 's' variable has a limited scope for the try-catch block, so as soon as that block ends, the s variable is not accessible anymore, you can verify this by trying to compile this code:
DBAccess() {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=CFPDB.mdb;";
Connection conn = DriverManager.getConnection(database, "", "");
Statement s = conn.createStatement();
s.execute(""); // compiles without problem.
}
catch(Exception ex) {
s.execute(""); // does not compile.
ex.printStackTrace();
}
s.execute(""); // does not compile.
}
So your best option is to declare s as a class field:
public class DBAccess {
private Statement s;
DBAccess() {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=CFPDB.mdb;";
Connection conn = DriverManager.getConnection(database, "", "");
s = conn.createStatement();
}
catch(Exception ex) {
ex.printStackTrace();
}
}
public Statement getStatement() {
return s;
}
}
And then accessible it via it's getter method. By the way, remember to instantiate your object via its constructor (line 2)
else if(event.getSource() == loginSubmitButton){
DBAccess loginCheck = new DBAccess(); // invoke constructor
String selFromTable = "SELECT PASSWORD FROM USERS WHERE USERNAME = '" + loginUsername.getText() + "'; ";
loginCheck.getStatement().execute(selFromTable);
ResultSet retrievedPassword = loginCheck.getStatement().getResultSet();
String password = retrievedPassword.getString(1);
String password_entered = loginPassword.getText();
}
Another option which I don't really recommend (but state here just for you to know) is to declare the s field as public:
public class DBAccess {
public Statement s;
DBAccess() {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=CFPDB.mdb;";
Connection conn = DriverManager.getConnection(database, "", "");
s = conn.createStatement();
}
catch(Exception ex) {
ex.printStackTrace();
}
}
Then you can access it the way you wanted:
loginCheck.s.execute(selFromTable);
You need to make field from s, because field exists as long as object owning it exists. The s now disappears when DBAccess constructor finishes. So you want something like this:
public class DBAccess {
private Statement s;
DBAccess() {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=CFPDB.mdb;";
Connection conn = DriverManager.getConnection(database, "", "");
s = conn.createStatement();
}
catch(Exception ex) {
ex.printStackTrace();
}
}
public Statement getStatement() {
return s;
}
}
and in your gui class access the s using getter:
else if(event.getSource() == loginSubmitButton){
DBAccess loginCheck;
String selFromTable = "SELECT PASSWORD FROM USERS WHERE USERNAME = '" + loginUsername.getText() + "'; "; //this is vulnerable to SQL injection, use prepared statements, see for example, here https://www.mkyong.com/jdbc/jdbc-preparestatement-example-select-list-of-the-records/
loginCheck.getStatement().execute(selFromTable);
ResultSet retrievedPassword = loginCheck.s.getResultSet();
String password = retrievedPassword.getString(1);
String password_entered = loginPassword.getText();
}
Related
I am connecting my Java Program to a database stored in the program folder, and I am having users answer quiz questions and I want the results to be stored in the database. The Update statement is not working, and I don't know if it's a problem with the actual statement or the database connection.
I've tried creating a new database with the same tables and reconnecting to that database, but nothing seems to be working.
//database connection class
public class databaseConnection {
public static Connection dbConnector() {
try {
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager
.getConnection("jdbc:sqlite:D:\\Users\\mariammahmoud\\eclipse-workspace\\ia_2019_final\\testjava.db");
return conn;
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
return null;
}
}
}
public class student {
public static final String DB_NAME = "testjava.db";
public static final String TABLE_STUDENTS = "students";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_GRADE = "grade";
public static final String COLUMN_RESULTS = "results";
public static final String COLUMN_EVENTS = "events";
public static final String COLUMN_USERNAME = "username";
public void main() {
try {
String user_name = login_student.sendQuiz();
Connection conn = databaseConnection.dbConnector();
ArrayList<String> results = new ArrayList<String>(15);
instructions();
questions(results);
results.trimToSize();
System.out.println("Here are the events that you should consider competing in:");
System.out.println(results);
String separator = ",";
int total = results.size() * separator.length();
for (String finalResults : results) {
total += finalResults.length();
}
StringBuilder sb = new StringBuilder(total);
for (String finalResults : results) {
sb.append(separator).append(finalResults);
}
String resultsDatabase = sb.substring(separator.length());
String sql = "UPDATE students SET events = ? WHERE username = " +user_name;
PreparedStatement myStmt = conn.prepareStatement(sql);
myStmt.setString(1, resultsDatabase);
myStmt.executeUpdate();
} catch (SQLException e) {
System.out.println("Something went wrong:" + e.getMessage());
e.printStackTrace();
}
}
I expected the update statement to update the testjava.db database, but everything is staying the same. What should I do? Thank you in advance!
Your problem is that while you wisely used a prepared statement in your code for the update, you never actually used it for the username column in the WHERE clause. Hence, the query you are executing currently won't be interpreted as comparing some input against username. Rather, the username value will be interpreted as a column. Try this version:
String resultsDatabase = sb.substring(separator.length());
String sql = "UPDATE students SET events = ? WHERE username = ?";
PreparedStatement myStmt = conn.prepareStatement(sql);
myStmt.setString(1, resultsDatabase);
myStmt.setString(2, user_name);
myStmt.executeUpdate();
Note that you could have just tried the following:
String sql = "UPDATE students SET events = ? WHERE username = '" + user_name + "'";
But, please bind a value to a ? placeholder instead, as I have suggested above. One benefit of using statements is that it frees you from having to worry about how to escape your data in the query.
i have been using this JDBC conection in all of my class that had to run query but i created a new class which i dont want the constructor with a parameter of the DConnection from JDBC Class(main Database Class).
but i keep on getting NullPointExceptions. Can anyway figur out what that problem may be.
Thanks.
public class UsersDao {
// associating the Database Connection objekt
private DConnector connector;
private final Connection myConn;
// Constructor
public UsersDao() throws CZeitExceptionHand,SQLException {
myConn = connector.getConnenction();
}
public boolean updateUsers(String mitarb, int mid) throws SQLException{
// PreparedStatement myStmt = null;
Statement stmt = myConn.createStatement();
try {
String myStmt = "SELECT Bly "
+ "" + mid + ";";
return stmt.execute(myStmt);
} finally {
close(stmt);
}
}
Example like this Method which is working but in different class
String[][] getAllTheWorkers(DConnector connector) throws CZeitExceptionHand {
try {
Connection connect = connector.getConnenction();
Statement stmt = connect.createStatement();
ResultSet result = stmt.executeQuery("SELECT ");
result.last();
int nt = result.getRow();
result.beforeFirst();
}
return results;
} catch (SQLException e) {
throw new CZeitExceptionHand("Error: " + e);
}
}
The object does not seem to be initialized.
Can you please post which method is not working and from where it is invoked ?
P.S : Unable to add a comment - that is why have answered !
I'm getting this error even though I am not trying to edit the table/column:
com.ibm.db2.jcc.am.SqlSyntaxErrorException: The operation failed because the operation is not supported with the type of the specified table. Specified table: "DASH103985.wajihs". Table type: "ORGANIZE BY COLUMN". Operation: "WITH RS".. SQLCODE=-1667, SQLSTATE=42858
#MultipartConfig
public class DemoServlet extends HttpServlet {
private static Logger logger = Logger.getLogger(DemoServlet.class.getName());
private static final long serialVersionUID = 1L;
#Resource(lookup="jdbc/db2")DataSource dataSource;
private String getDefaultText() {
TweetsCombined = new String(" ");
try {
// Connect to the Database
Connection con = null;
try {
System.out.println("Connecting to the database");
} catch (SQLException e) {
TweetsCombined = "first" +e;
}
// Try out some dynamic SQL Statements
Statement stmt = null;
try {
stmt = con.createStatement();
String tableName = "wajihs";// change table name here to one
// chosen in the first website
String columnName = "msgBody";// msgBody is where the tweets
// are stored
String query = "SELECT * FROM \"" + tableName + "\"";
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
content = rs.getString(columnName) + ". ";
if (content.toLowerCase().contains("RT".toLowerCase())
|| content.toLowerCase().contains("Repost: ".toLowerCase())) {
// do nothing
}
else {
TweetsCombined.concat(content);
}
}
// Close everything off
// Close the Statement
stmt.close();
// close
con.commit();
// Close the connection
con.close();
} catch (Exception e) {
TweetsCombined = "second" +e;
System.out.println(e.getMessage());
}
} catch (Exception e) {
TweetsCombined = "third" + e;
System.out.println(e);
}
return TweetsCombined;
}
As I explained here, dashDB, with its BLU Acceleration features, has certain limitations compared to DB2 without BLU Acceleration. In your case it is that you can only run queries with the CS isolation level against column-organized tables.
Either change your connection configuration to use CS isolation level or create your table(s) while explicitly specifying ORGANIZE BY ROW.
I'm doing my dissertation on software engineering and im building a small application that makes use of a SQL DB, in this case MySQL. I'm also using the application controller pattern. So the code I have working for retrieving data from the db is;
public static void main(String[] args)
{
try
{
String url = "jdbc:mysql://localhost:3306/tm470_returns_stock_management_system";
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection(url,"root","root");
Statement st = con.createStatement();
ResultSet res = st.executeQuery("SELECT * FROM test_table");
while (res.next())
{
int id = res.getInt("test_id");
String msg = res.getString("test_info");
System.out.println(id + "\t" + msg);
}
con.close();
}
catch(Exception e)
{
System.out.println("DB connection unsuccesful");
}
}
I now want to transfer this out of my Main class/string and into my Application Controller Class (which is called Facility).
Now my question is, for every method in my Facility Class that needs to access the DB, do i have to do the full code each time? Or can i create a method within the Facility class that each application method can just call whenever it needs to access the DB. If i can condense all this into a method, can you advise me how to go about it please?
Be gentle with me guys, I am a learner :)
How about adding a utility class like ConnectionUtil and using the static method to access the connection.
import java.sql.Connection;
import java.sql.DriverManager;
public class ConnectionUtil{
static final String url = "jdbc:mysql://localhost:3306/";
static final String dbName = "test";
static final String driver = "com.mysql.jdbc.Driver";
static final String userName = "userparatest";
static final String password = "userparatest";
Connection con = null;
static Connection getConnection() throws Exception {
if(con == null)
{ Class.forName(driver).newInstance();
con = DriverManager.getConnection(url + dbName, userName,password);
}
return con;
}
}
this can be further improved but just providing a start..
just call below whenever you want a statement..
Statement st = ConnectionUtil.getConnection().createStatement();
I would map it as a own class, which is used by your application other classes. When you define it as a singleton you will only need one instance in your complete application
Yes , you can write a method for accessing db and you can reuse it across all the applications.
Keep the following in a method and reuse it.
String url = "jdbc:mysql://localhost:3306/tm470_returns_stock_management_system";
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection(url,"root","root");
Statement st = con.createStatement();
int productID = 6;
String skuCode = "ABC123";
ResultSet res = st.executeQuery("SELECT * FROM test_table");
while (res.next())
{
int id = res.getInt("test_id");
String msg = res.getString("test_info");
System.out.println(id + "\t" + msg);
}
I have some issues with the conection between java application and mysql.
This is my file(this file work very well):
import java.sql.*;
import javax.swing.JFrame;
public class MysqlConnect{
public static void main(String[] args) throws SQLException {
Connection conn = null;
String url = "jdbc:mysql://localhost:3306/";
String dbName = "jdbctutorial";
String driver = "com.mysql.jdbc.Driver";
String userName = "birthday";
String password = "123456";
try {
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url+dbName,userName,password);
System.out.println("Connected to the database");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Is possible "to separate" the main and mysql connection ??
My idea is something like that :I have the MysqlConnection file and another GUI file.
In the GUi file I have a button (ADD) and whenever I click this button some datas will be stored to database .My problem is that I don't know how run the query ,because I need the Statement variable ,Connection variable,etc..What I suppose to do ?To do the mysqlConnection and GUI in the same file ?Another idea of mine is to do an object of type MysqlConnection and work with that object.And here is the problem :If I remove the (public void main .....) i have an error at try and catch.
Sorry if my english is bad but I hope i make myself clear .
Thanks in advance .
What I understand from your question is that you want to make an application that shows data from a database in a GUI. Maybe you should look into an architecture like MVC (Model-View-Controller) where you have the model as an representation of the data in the database and having the view as a graphical representation of the model.
Since it didn't came to mind to apply a certain architecture, I would recommend you to look into that first, do a little bit of research and then implement your system. When looking into the MVC-architecture, I recommend you to start here. This is really the most easy example you could think of.
About your database connection: your setup looks good, though first of all, put it in a separate class and add query functionality to it. While implementing that part, this would come in handy. After that, you can let the Controller call the database to manipulate the Model on a button press, which will update the View (GUI) in your MVC-architecture.
So, do NOT put your database connection and your Main or GUI in the same class! This is a bad code style, violates the Single Responsibility Principle and will give you more trouble in future developing! Instead, use a proper architecture
If you want further help, always feel free to ask! I have recently studied this kind of stuff and made an application like this.
Hi RvanHeest thank you very much for your time.I try to do like that :
MysqlConnect.java
public class MysqlConnect{
public Connection conn = null;
public String url = "jdbc:mysql://localhost:3306/";
public String dbName = "jdbctutorial";
public String driver = "com.mysql.jdbc.Driver";
public String userName = "birthday";
public String password = "123456";
public String query="Select * From Person";
public Statement stmt;
public ResultSet rs;
public void crearedatabase(){
try {
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url+dbName,userName,password);
System.out.println("Connected to the database");
Statement stmt = conn.createStatement();
} catch (Exception e) {
System.out.println("Error!!!");
}
}
}
and in mine Gui class like that :
GUi file:
.................
................
MysqlConnect mysqlitem = new MysqlConnect();
mysqlitem.crearedatabase();
String query = "INSERT INTO persons("
+ "id"
+ "name"
+ "lastname"
+ "date) "
+ "VALUES(null,Maxim,Alexandru-Vasile,1990-12-28)";
try{
mysqlitem.rs=mysqlitem.stmt.executeQuery(query);
}
catch(Exception e1){
System.out.println("Eroare");
}
On the " mysqlitem.rs=mysqlitem.stmt.executeQuery(query);" I have an Exeption error and I don't know how to resolve..
Thank you very much again !!!
I ran in to the same issue.
I found the root cause to be that you are declaring the stmt variable twice.
Your code should look this like:
public class MysqlConnect{
public Connection conn = null;
public String url = "jdbc:mysql://localhost:3306/";
public String dbName = "jdbctutorial";
public String driver = "com.mysql.jdbc.Driver";
public String userName = "birthday";
public String password = "123456";
public String query="Select * From Person";
public Statement stmt;
public ResultSet rs;
public void crearedatabase(){
try {
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url+dbName,userName,password);
System.out.println("Connected to the database");
stmt = conn.createStatement();
} catch (Exception e) {
System.out.println("Error!!!");
}
}
}
Note the change to the line 18 "stmt = conn.createStatement();"
I wrote this code for create a separate dbconnection class on a separate java file and its working fine for me.
public class dbConnection{
public Connection getConnection()
{
String url = "jdbc:mysql://localhost:88/shop";
String username = "root";
String password = "";
Connection con = null;
try
{
Class.forName("com.mysql.jdbc.Driver");
}
catch (ClassNotFoundException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
try
{
con = DriverManager.getConnection(url, username, password);
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return con;
}
}
// USING THE ABOVE CONNECTION ON DIFF CLASS
-----------
Connection con=new dbConnection().getConnection();
------------
Credits to StackOverFlow...
public class LoadDriver {
public static void sqlDriver(String[] args) throws InstantiationException,
IllegalAccessException, ClassNotFoundException {
// TODO Auto-generated method stub
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
and in your main class
try {
LoadDriver.sqlDriver(null);