I currently have a very basic app that interacts with a database (Using netbeans and the jdbc) so that you can add teams, players and scores. I now need to be able to display items from each table together in a League Table/Team (With players) Table etc etc.
My question is how do I go about retrieving the information from the tables and how do I display it, I am literally clueless as to how I should go about it. I'm assuming I need to do a Join or Select statement (I'm a complete SQL novice) and then use a loop to select each table entry and display it in a table somehow?
The only current working features I have are adding to the database, IE add a new team add a new player etc, displaying what is in the tables on the form is where I am stumped.
Any tips or help is much appreciated.
The code I am currently using is this; (I still need to implement a score table and adding records to that, I also created the datbase using the GUI and so have no foreign keys set, is there a way to do this WITHIN netbeans as I have no "Create Table" code anywhere.
package football.game;
/*import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;*/
import football.game.DBconnection;
import java.sql.*;
/**
*
* #author Steffan Caine
*/
public class SportsConnection extends DBconnection {
public SportsConnection(final String dbName)
{
this.connectDatabase(dbName);
}
public void insertPlayer(final Integer PLAYERNUM,
final String PLAYERNAME, final String PLAYERPOS, final Integer TEAMNUM)
{
final String insertStmt = "INSERT INTO APP.PLAYERS (PLAYERNUM, PLAYERNAME, PLAYER_POS, TEAM_ID) VALUES (?,?, ?, ?)";
try
{
PreparedStatement pstmt = getConnection().prepareStatement(insertStmt);
pstmt.setInt(1, PLAYERNUM);
pstmt.setString(2, PLAYERNAME);
pstmt.setString(3, PLAYERPOS);
pstmt.setInt(4, TEAMNUM);
pstmt.executeUpdate();
}
catch (SQLException sqle)
{
System.out.println("Exception when inserting player record: " + sqle.toString());
}
}
public void insertTeam(final String NAME, final String MANAGER, final int ID)
{
final String insertStmt = "INSERT INTO APP.TEAMS (TEAMNAME, MANAGER, TEAM_ID) VALUES (?,?, ?)";
try
{
PreparedStatement pstmt = getConnection().prepareStatement(insertStmt);
pstmt.setString(1, NAME);
pstmt.setString(2, MANAGER);
pstmt.setInt(3, ID);
pstmt.executeUpdate();
}
catch (SQLException sqle)
{
System.out.println("Exception when inserting team record: " + sqle.toString());
}
}
public void printAllRecords()
{
this.setQuery(retrieveQuery);
this.runQuery();
ResultSet output = this.getResultSet();
try
{
if (null != output)
{
while(output.next())
{
String PLAYERNUM = output.getString(1);
String PLAYERNAME = output.getString(2);
System.out.println (PLAYERNUM + "\n" + PLAYERNAME + "\n");
}
}
}
catch (SQLException sqle)
{
System.out.println("Exception when printing all students: " + sqle.toString());
}
}
}
The "retrieveQuery" currently returns an error message, any help getting that part to work would be great as printing the records out in a console would add some much needed (If basic) functionality.
I also have classes for each form (AddPlayer/AddTeam/Navigation) but I am not using constructors to populate the database I am instead using Methods located in a Main class, is this a bad way to go about things as I am not using "Objects" as such?
Thanks.
I see three tables: PLAYER, TEAM, and LEAGUE.
A TEAM has many PLAYERs; a LEAGUE has many TEAMs. These should be one-to-many relationships, so you'll have foreign keys. Here's an example:
CREATE TABLE PLAYER (
int id not null auto increment,
first_name varchar(80),
last_name varchar(80),
int team_id,
primary key(id),
foreign key(team_id) references TEAM(id)
);
CREATE TABLE TEAM (
int id not null auto increment,
name varchar(80),
primary key(id)
);
So you might have Java classes like this:
package model;
public class Player {
private Integer id,
private String name;
// ctors, getters, etc.
}
public class Team {
private Integer id,
private String name,
List<Player> players;
// ctors, getters, etc.
}
You'll have a persistence layer that will have all your SQL in it:
package persistence;
public interface PlayerDao {
Player find(Integer id);
List<Player> find();
Integer save(Player p);
void update(Player p);
void delete(Player p);
}
Here's a sample implementation for PlayerDao:
package persistence;
public class PlayerDaoImpl implements PlayerDao {
private static final String SELECT_ALL = "SELECT id, name FROM PLAYER ";
private static final String SELECT_BY_ID = SELECT_ALL + "WHERE id = ?";
private Connection connection;
public PlayerDaoImpl(Connection connection) {
this.connection = connection;
}
public Player find(Integer id) {
Player p = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = this.connection.prepareStatement(SELECT_BY_ID);
ps.setInteger(1, id);
rs = ps.executeQuery();
while (rs.next()) {
Integer pid = rs.getInteger("id");
String name = rs.getString("name");
p = new Player(id, name);
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DatabaseUtils.close(rs);
DatabaseUtils.close(ps);
}
return p;
}
}
Printing records in consoles or user interfaces would indeed be useful, but that should be done by different classes in different packages. Have a view tier that handles that stuff. Classes should do one thing well. You should think about layering your applications appropriately.
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.
first time posting so sorry if my question is slightly strange.
So I have a project in school that requires us to create java classes using netbeans that open up a window with three options, check stock, purchase item and update stock.
We had a class called stockdata that held the details of 5 different items for us to use in our three classes to check, purchase and update items. The latest stage of our coursework requires us to create a derby database and enter the items into a table.
I have done this with no issues but I am having a problem getting the items from the table back into my classes to use. We were given the following code but I can't get it to work, even using the commented hints.
package stock;
// Skeleton version of StockData.java that links to a database.
// NOTE: You should not have to make any changes to the other
// Java GUI classes for this to work, if you complete it correctly.
// Indeed these classes shouldn't even need to be recompiled
import java.sql.*; // DB handling package
import java.io.*;
import org.apache.derby.drda.NetworkServerControl;
public class StockData {
private static Connection connection;
private static Statement stmt;
static {
// standard code to open a connection and statement to an Access database
try {
NetworkServerControl server = new NetworkServerControl();
server.start(null);
// Load JDBC driver
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
//Establish a connection
String sourceURL = "jdbc:derby://localhost:1527/"
+ new File("UserDB").getAbsolutePath() + ";";
connection = DriverManager.getConnection(sourceURL, "use", "use");
stmt = connection.createStatement();
} // The following exceptions must be caught
catch (ClassNotFoundException cnfe) {
System.out.println(cnfe);
} catch (SQLException sqle) {
System.out.println(sqle);
} catch (Exception e) {
System.out.println(e);
}
}
// You could make methods getName, getPrice and getQuantity simpler by using an auxiliary
// private String method getField(String key, int fieldNo) to return the appropriate field as a String
public static String getName(String key) {
try {
// Need single quote marks ' around the key field in SQL. This is easy to get wrong!
// For instance if key was "11" the SELECT statement would be:
// SELECT * FROM Stock WHERE stockKey = '11'
ResultSet res = stmt.executeQuery("SELECT * FROM Stock WHERE stockKey = '" + key + "'");
if (res.next()) { // there is a result
// the name field is the second one in the ResultSet
// Note that with ResultSet we count the fields starting from 1
return res.getString(2);
} else {
return null;
}
} catch (SQLException e) {
System.out.println(e);
return null;
}
}
public static double getPrice(String key) {
// Similar to getName. If no result, return -1.0
return 0;
}
public static int getQuantity(String key) {
// Similar to getName. If no result, return -1
return 0;
}
// update stock levels
// extra is +ve if adding stock
// extra is -ve if selling stock
public static void update(String key, int extra) {
// SQL UPDATE statement required. For instance if extra is 5 and stockKey is "11" then updateStr is
// UPDATE Stock SET stockQuantity = stockQuantity + 5 WHERE stockKey = '11'
String updateStr = "UPDATE Stock SET stockQuantity = stockQuantity + " + extra + " WHERE stockKey = '" + key + "'";
System.out.println(updateStr);
try {
stmt.executeUpdate(updateStr);
} catch (SQLException e) {
System.out.println(e);
}
}
// close the database
public static void close() {
try {
connection.close();
} catch (SQLException e) {
// this shouldn't happen
System.out.println(e);
}
}
}
Sorry if this seems a stupid question but I am fairly new to Java and was making good progress until this roadblock.
Thanks in advance!
Alex
Searching for "java sql" on Google delivers this link: https://docs.oracle.com/javase/tutorial/jdbc/basics/processingsqlstatements.html
From a connection you can create a statement (you can find this in the link and in your code) , then fetch a result set and loop over that with rs.next(). That should get your started.
Of course you have to make sure that the driver and database are there/running, just saying...
Here netbeans has nothing to do with database. This is a Java-based integrated development environment(IDE) that will help you to reduce syntactic error.
public void dataAccess(){
try {
String connectionUrl = "suitable connection url as per your database";
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
Class.forName("JDBC driver name as per your database");
con = DriverManager.getConnection(connectionUrl, userName, password);
String SQL = "SQL query as per your criteria";
stmt = con.createStatement();
rs = stmt.executeQuery(query);
while (rs.next()) {
// look into ResultSet api and use method as per your requirement
}
rs.close();
}
catch (Exception e) {
//log error message ;
}
}
I am trying to create a query for past orders from a oracle database and i want to search by Company name.
I am not sure where to start with accessing the database
Here is the basic command line prompt i created but i not sure
import java.util.Scanner;
public class PastOrders {
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
system.out.prinln("Welcome to Company XYZ Order Query");
system.out.println();
Sting companyName;
System.out.print("Enter Company Name to pull up previous orders: ";
}
}
First of all, you need to download and the Java Data Base Connector (JDBC) for you Database. For oracle you can find it here: http://www.oracle.com/technetwork/apps-tech/jdbc-112010-090769.html
Then you have to set up a connection, write and execute a query, like this (http://docs.oracle.com/javase/tutorial/jdbc/overview/index.html):
import java.sql.*;
public class UpdateCar {
public static void UpdateCarNum(int carNo, int empNo)
throws SQLException {
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DriverManager.getConnection(
"jdbc:default:connection");
pstmt = con.prepareStatement(
"UPDATE EMPLOYEES " +
"SET CAR_NUMBER = ? " +
"WHERE EMPLOYEE_NUMBER = ?");
pstmt.setInt(1, carNo);
pstmt.setInt(2, empNo);
pstmt.executeUpdate();
}
finally {
if (pstmt != null) pstmt.close();
}
}
}
The only thing you have to change in this sample code is the PreparedStatement(psmt - query) and the Connection(con).
I'm writing a simple java application (in study purpose) to manage employees and I need an advise: how to store and retrieve data from the database.
Code, that I have wrote so far is too big to put it here, so, in two words:
I have next hierarchy:
abstract class Employee: 4 attributes, getters, setters
class Salaried: 2 new attribute
class Hourly : 2 new attributes
class Director: 3 new attributes
class Manager : 1 new attribute
I have a MySQL data with 1 table (create script):
CREATE TABLE `employee` (
`SSN` int(9) NOT NULL PRIMARY KEY,
`FirstName` varchar(20) NOT NULL,
`LastName` varchar(20) NOT NULL,
`Department` varchar(20) NOT NULL,
`Salary` float(10) NULL,
`OvertimeHours` float(10) NULL,
`HourlyWage` float(10) NULL,
`NumberHours` float(10) NULL,
`Organization` varchar(30) NULL,
`Bonus` float(10) NULL
);
First 4 fields are general for all employees.
Salary and OvertimeHours are attributes of the Salaried class
HourlyWage and NumberHours are attributes of the Hourly class
Salary, Bonus and Organization are attributes of the Director class
Salary also is a attribute of the Manager class
I've created a static class Database to work with the MySQL.
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Connection;
public abstract class Database {
// constants
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String DBNAME = "records";
private static final String DBUSER = "root";
private static final String DBPASS = "";
private static final String CONURL = "jdbc:mysql://localhost/" + DBNAME;
// class attributes
private static Connection connection = null;
public static boolean fillEmployee(Employee emp, int ssn)
{
try {
PreparedStatement stm = connection.prepareStatement(
"SELECT FirstName, LastName, Department "
+ "FROM employee "
+ "WHERE SSN = ?"
);
stm.setInt(1, ssn);
ResultSet rs = stm.executeQuery();
if(!rs.next())
return false;
emp.setSocialSecurity(ssn);
emp.setFirstName(rs.getString("FirstName"));
emp.setLastName(rs.getString("LastName"));
emp.setDepartment(rs.getString("Department"));
stm.close();
rs.close();
} catch (Exception e) {
System.out.println(e.getMessage());
System.exit(0);
}
return true;
}
public static boolean deleteEmployee(int ssn){
try {
PreparedStatement stm = connection.prepareStatement(
"DELETE "
+ "FROM employee "
+ "WHERE SSN = ?"
);
stm.setInt(1, ssn);
return (stm.executeUpdate() == 1);
} catch (Exception e) {
System.out.println(e.getMessage());
System.exit(0);
}
return false;
}
// class methods
public static Salaried getSalariedEmployee(int ssn){
Salaried employee = new Salaried();
try {
if(!fillEmployee(employee, ssn))
return null;
PreparedStatement stm = connection.prepareStatement(
"SELECT Salary, OvertimeHours "
+ "FROM employee "
+ "WHERE SSN = ?"
);
stm.setInt(1, ssn);
ResultSet rs = stm.executeQuery();
employee.setSalary(rs.getFloat("Salary"));
employee.setOvertimeHours(rs.getFloat("OvertimeHours"));
stm.close();
rs.close();
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
System.exit(0);
}
return employee;
}
public static void createConnection() {
if (connection != null)
return;
try {
Class.forName(DRIVER);
connection = DriverManager.getConnection(CONURL, DBUSER, DBPASS);
} catch (Exception e) {
System.out.println(e.getMessage());
System.exit(0);
}
}
public static void closeConnection(){
if (connection == null)
return;
try{
connection.close();
connection = null;
} catch (Exception e) {
System.out.println(e.getMessage());
System.exit(0);
}
}
}
What are you thinking about getSalariedEmployee and fillEmployee methods?
How can I improve the overall design and architecture of my application?
The first thing I would do is stop using static methods for all your Database functions.
Also why is Database an abstract class? Is there another class that extends Database with specific implementations (like MyDatabase or OracleDatabase.
You might consider using static methods to return an instance of a Database and then convert the static methods to public instance methods.
Perhaps you should start with a good reading of the book Patterns of Enterprise Architecture. It has a good chapter covering the different ways in which we typically deal with the database.
You can read quick definitions of these in the companion web site:
Transaction Script
Table Data Gateway
Row Data Gateway
Active Record
Data Mapper
All the patterns have advantages and disadvantages and some of them have entire frameworks that help you write code for them.
I think you could wait for creating the employee object in getSalariedEmployee.
instantiate it only if you find the db object.
Because if you return null when not finding it, you still create the employee object.
I have my ORACLE table with structure as
desc extraction_log1
Name Null
Type
------------------------------ -------- ------------------------------------------------------------ ---------------------------------------------------------------------------------------------------- -----------------------------
ROW_NUM NOT NULL NUMBER
DATE_TIME TIMESTAMP(8)
USER_NAME VARCHAR2(32)
PLATFORM_NAME VARCHAR2(20)
R_OBJECT_ID VARCHAR2(16)
Then I created an object type in oracle as
create or replace type EXTRACTION_LOG_TYPE as object (
USER_NAME VARCHAR2(32),
R_OBJECT_ID VARCHAR2(16),
);
Then I created procedure in a package as
create or replace package body PAC_BEAN is
--The insert procedure will receive EXTRACTION_LOG_TYPE and put it into table EXTRACTION_LOG1.
procedure PRO_INSERT_LOG(ELT in EXTRACTION_LOG_TYPE) is
begin
insert into EXTRACTION_LOG1 ( R_OBJECT_ID, USER_NAME)
values (ELT.R_OBJECT_ID, ELT.USER_NAME);
commit;
exception
when others then
rollback;
end PRO_INSERT_LOG;
end PAC_BEAN;
and coming to my java side I have declared a bean with
public class ExtractionLogType {
//Name declared in Oracle
public static final String ORACLE_OBJECT_NAME = "EXTRACTION_LOG_TYPE";
//The attributes
private String R_OBJECT_ID;
private String USER_NAME;
//setters and getters
public String getR_OBJECT_ID() {
return R_OBJECT_ID;
}
public void setR_OBJECT_ID(String rOBJECTID) {
R_OBJECT_ID = rOBJECTID;
}
public String getUSER_NAME() {
return USER_NAME;
}
public void setUSER_NAME(String uSERNAME) {
USER_NAME = uSERNAME;
}
}
in my Class containing main
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBLogger{
String dbUrl;
Connection con;
//constructor for creation of connection object
as and when an object of DBLogger is instantiated
public DBLogger(){
dbUrl = "jdbc:oracle:thin#my url";
try {
//load Oracle Driver class
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.err.println("Oracle driver class not found");
}
try {
//instantiate connection object
con = DriverManager.getConnectio (dbUrl,"userId","pwd");
} catch (SQLException e) {
e.printStackTrace();
System.err.println("Connection object to oracle cant be established");
}
}
public static void main(String args[]){
try{
DBLogger db=new DBLogger();
CallableStatement cs = null;
ExtractionLogType elt=new ExtractionLogType();
elt.setR_OBJECT_ID("79479479A900");
elt.setUSER_NAME("Jeevan");
cs = db.con.prepareCall("{call PAC_BEAN.PRO_INSERT_LOG(?)}");
/*
* *code to insert the above object into our Database
*
*/
cs.execute();
System.out.println("insert procedure executed successfully");
db.con.close();
} //end try
catch (SQLException e) {
e.printStackTrace(); }
catch(Exception e) { e.printStackTrace();
}
}
}
I can't figure out the code to make the object get inserted into my database.
can anyone suggest me regarding this.
Thank You.
You will have to define a array descriptor for your database type, this example could help you:
final ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor("EXTRACTION_LOG_TYPE", con);
// create an Object Array
Object[] data = new Object[2];
// set the values in order of appearance
data[0] = elt.getUSER_NAME();
data[1] = elt.getR_OBJECT_ID();
// Create the Array
ARRAY array = new ARRAY(descriptor, con, data);
// put it on your statement
cs.setArray(1, array);
// execute ...
This is terrible idea to create any objects in SYSTEM schema of the database. It is the same bad idea to connect your app straight to this scheme either.
This looks like a lack of privileges disallowing you to get what you want. Create new schema, dedicated user of this schema and then create all required object using this new user (it will be the owner of your objects). This way you can avoid "issue" where you cannot access something you supposed to have an access to.