I am creating a flight application in java and one of the things it is supposed to do is to add a new flight to the database. I am able to add the flight name with no issues, but I am having issues adding in the number of seats the flight has to the database. The database table is set to take in the number of seats as an integer value. In my code, my function that adds this value in from the user interface to the database takes a value as an integer argument. Then, in my event handler code for the actual button that adds a new flight, I convert the value from a string(this is what is accepted as a string from the text box) to an integer, so that the value can be entered into the database. However, when I run my code, I get an error saying the number of seats cant be accepted as a null value. Basically, the database is taking in the value as null. I am not sure what I am doing wrong in my code.
public class Flight extends Customer {
private static ArrayList<String> FlightNames;
private static ArrayList<Integer> Seats;
private static PreparedStatement getFlightnames;
private static PreparedStatement getFlightSeats;
private static PreparedStatement addFlightName;
private static PreparedStatement addSeats;
private static ResultSet fresult;
private static ResultSet sresult;
public static ArrayList <String> getFlightnames(){
//recieve flight names from database
try{
FlightNames = new ArrayList();
getFlightnames = getConnection().prepareStatement("select name from flight ");
fresult = getFlightnames.executeQuery();
while(fresult.next()){
FlightNames.add(fresult.getString(1));
}
}
catch(SQLException result){
result.printStackTrace();
}
return FlightNames;
}
public ArrayList<Integer> getFlightSeats(){
try{
Seats = new ArrayList();
//getFlightSeats = getConnection().prepareStatement("SELECT * FROM Flight WHERE Seats LIKE ?");
getFlightSeats = getConnection().prepareStatement("select seats from flight ");
sresult = getFlightSeats.executeQuery();
while(sresult.next()){
Seats.add(sresult.getInt(1));
}
}
catch(SQLException result){
result.printStackTrace();
}
return Seats;
}
public void addFlight(String flight){
try{
addFlightName = getConnection().prepareStatement("insert into bookings (flight) values(?)");
addFlightName.setString(1, flight);
addFlightName.executeUpdate();
}
catch(SQLException result){
result.printStackTrace();
}
}
public void addNumber(String flightNumber){
try{
addFlightName = getConnection().prepareStatement("insert into flight (name) values(?)");
addFlightName.setString(1, flightNumber);
addFlightName.executeUpdate();
}
catch(SQLException result){
result.printStackTrace();
}
}
public void addSeats(int seats){
try{
addSeats = getConnection().prepareStatement("insert into flight (seats) values(?)");
addSeats.setInt(1, seats);
addSeats.executeUpdate();
}
catch(SQLException result){
result.printStackTrace();
}
}
}
private void AddFlightButtonActionPerformed(java.awt.event.ActionEvent evt) {
Flight addnumber = new Flight();
Flight addseats = new Flight();
addnumber.getConnection();
addseats.getConnection();
String flight = FlightTextBox.getText();
String seats = SeatsTextBox.getText();
int seatsInt = Integer.parseInt(seats);
addnumber.addNumber(flight);
addseats.addSeats(seatsInt);
AddFlightStatusLabel.setText("The flight " + flight + " has been added with " + seats + " seats" );
BookFlightComboBox.setModel(new javax.swing.DefaultComboBoxModel(Flight.getFlightnames().toArray()));
StatusFlightComboBox.setModel(new javax.swing.DefaultComboBoxModel(Flight.getFlightnames().toArray()));
WaitFlightComboBox.setModel(new javax.swing.DefaultComboBoxModel(Flight.getFlightnames().toArray()));
}
Looks like you're using wrong table to add seats or wrong index for your table.
Edit:
After checking your table columns you need to add query like this for both functions but it's recommend to use only single method like this:
public void addFlightDetail(String flightNumber, int seats){
addFlightName = getConnection().prepareStatement("insert into flight (name, seats)
values(?,?)");
addFlightName.setString(1, flightNumber);
addFlightName.setInt(1, seats);
}
Related
I have to read Employee data from a text file(each record is separated by tab) into a ArrayList. Then I have to insert this employee objects from list to the Employee table in DB. For this, I am iterating the list elements one by one and inserting Employee details one at a time into DB. This approach is not recommended performance wise because we can have more than 100k records and it will take so much time to insert the whole data.
How can we use multi threading here while inserting data from list to db to improve performance. Also how can we use CountDownLatch and ExecutorService classes to optimize this scenario.
ReadWriteTest
public class ReadWriteTest {
public static void main(String... args) {
BufferedReader br = null;
String filePath = "C:\\Documents\\EmployeeData.txt";
try {
String sCurrentLine;
br = new BufferedReader(new FileReader(filePath));
List<Employee> empList = new ArrayList<Employee>();
while ((sCurrentLine = br.readLine()) != null) {
String[] record = sCurrentLine.split("\t");
Employee emp = new Employee();
emp.setId(record[0].trim());
emp.setName(record[1].trim());
emp.setAge(record[2].trim());
empList.add(emp);
}
System.out.println(empList);
writeData(empList);
} catch (IOException | SQLException e) {
e.printStackTrace();
}
}
public static void writeData(List<Employee> empList) throws SQLException {
Connection con =null;
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe","system","oracle");
for(Employee emp : empList)
{
PreparedStatement stmt=con.prepareStatement("insert into Employee values(?,?,?)");
stmt.setString(1,emp.getId());
stmt.setString(2,emp.getName());
stmt.setString(3,emp.getAge());
stmt.executeUpdate();
}
}catch(Exception e){
System.out.println(e);
}
finally{
con.close();
}
}
}
Employee Class
public class Employee {
String id;
String name;
String age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
#Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
EmployeeData.txt
1 Sachin 20
2 Sunil 30
3 Saurav 25
Direct import
An alternative to the Java application approach is a database approach. All major databases have tools which can import data directly from a text file to table.
Postgres has the COPY command. This can be run from the command line or from within SQL. See the wiki page for discussion.
Look at your database tool set.
I agree with #kuporific. Batch update will prove to be better from a performance point of view.
Give a try with the following edit to your code:
public static void writeData(List<Employee> empList) throws SQLException {
Connection con =null;
final int BATCH_SIZE = 1000; // just an indicative number
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe","system","oracle");
Statement statement = con.createStatement();
int counter = 0;
for(Employee emp : empList)
{
String query = "insert into Employee (id, name, city) values('"
emp.getId() + "','" + emp.getName() + "','" + emp.getAge() + "')";
statement.addBatch(query);
if (counter % BATCH_SIZE == 0){
statement.executeBatch();
}
counter++;
}
statement.close();
}catch(Exception e){
System.out.println(e);
}
finally{
con.close();
}
}
Depending on your application, it might make sense to put the DB update code on a thread off of the main application thread. You can do this using Executors for example.
You could also look into using batch updates instead.
I would suspect that trying to update the DB on multiple threads isn't going to speed things up because the DB has to maintain atomicity, so any table can only be updated by one thread at a time anyway.
You could go really crazy and do both actions off of the main thread using Java 8's CompletableFuture:
CompletableFuture.supplyAsync(new Supplier<List<Employee>>()
{
#Override
public List<Employee> get()
{
List<Employee> employees = new ArrayList<>();
// get employee list
return employees;
}
}).thenAcceptAsync(new Consumer<List<Employee>>()
{
#Override
public void accept(List<Employee> employees)
{
// put into DB using batching
}
});
The first supplyAsyc will call the given code on another thread. When it completes, the return value is passed to the Consumer in the thenAcceptAsync, and that function is also run on another thread.
This can be written more compactly as:
CompletableFuture.supplyAsync(() -> {
List<Employee> employees = new ArrayList<>();
// get employee list
return employees;
}).thenAcceptAsync(employees -> {
// put into DB using batching
});
Im try to insert data into Database using ArrayList.there is a Erro msg.
That is my Custmer.class method. this is what i got from when i going to pass ArrayList into another class.
incompatible types: ArrayList<String> cannot be converted to ArrayList<Inquiries>
I want to know how to do this using correct Using OOP concept
public void passingMsg(ArrayList<Inquiries> arrlist){
try {
System.out.println("Method "+arrlist);
String sq = "INSERT INTO Inquiries (name,mail,tp,msg)VALUES(?,?,?)";
PreparedStatement pr = con.prepareStatement(sq);
for(int i=0;i<arrlist.size();i++){
pr.setString(1,arrlist.get(i).getName());
pr.setString(2,arrlist.get(i).getMail());
pr.setString(3,arrlist.get(i).getTp());
pr.setString(4,arrlist.get(i).getMsg());
}
pr.executeQuery();//executeBatch();
} catch (SQLException ex) {
}
}
and this is how i get values from user
String name = txtName.getText();
String mail = txtEmail.getText();
String tp = txtTp.getText();
String msg = txtMsg.getText();
ArrayList<String> arrInq = new ArrayList<String>();
arrInq.add(name);
arrInq.add(mail);
arrInq.add(tp);
arrInq.add(msg);
Custmer c =new Custmer();
if( c.passingMsg(arrInq)){
try {
JOptionPane.showMessageDialog(this, "Successs!!");
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Unsuccesss!!");
e.printStackTrace();
}
}
and this is my Inquiries.class :
public class Inquiries {
private String name;
private String mail;
private String tp;
private String msg;
public Inquiries(String name,String mail,String tp,String msg){
this.name = name;
this.mail = mail;
this.tp = tp;
this.msg = msg;
}
//
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getTp() {
return tp;
}
public void setTp(String tp) {
this.tp = tp;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
Can Some one please explain whats wrong with this. please ?
Reason For Error
This was simply telling you that your types were incompatible for the operation you were trying to perform. In your passingMsg() method, you have its header as: public void passingMsg(ArrayList<Inquiries> arrlist). However, inside your "how i get values from user" area, which I will now refer to as "2nd Snippet", you have your method call declared as: if( c.passingMsg(arrInq)). This means that you are implying that your parameter being passed, arrInq in this case, is of the type ArrayList<Inquiries>, but it's not. It's being initialized in your 2nd Snippet as: ArrayList<String> arrInq = new ArrayList<String>();
Simple Fix
I take no responsibility for this code; use at your own risk. To fix this, you would want to change that entire 2nd Snippet to something similar to the following:
String name = txtName.getText();
String mail = txtEmail.getText();
String tp = txtTp.getText();
String msg = txtMsg.getText();
ArrayList<Inquiries> arrInq = new ArrayList<Inquiries>();
arrInq.add(new Inquiries(name, mail, tp, msg));
Custmer c = new Custmer();
try {
c.passingMsg(arrInq);
JOptionPane.showMessageDialog(this, "Successs!!");
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Unsuccesss!!");
e.printStackTrace();
}
You would also want to change the method header to either return a boolean, or fix it up a little bit to actually throw the exception. Such as:
public void passingMsg(ArrayList<Inquiries> arrlist) {
System.out.println("Method " + arrlist);
String sq = "INSERT INTO Inquiries(name,mail,tp,msg) VALUES(?,?,?)";
PreparedStatement pr = con.prepareStatement(sq);
for (Inquiries inquiries : arrlist) {
pr.setString(1, inquiries.getName());
pr.setString(2, inquiries.getMail());
pr.setString(3, inquiries.getTp());
pr.setString(4, inquiries.getMsg());
}
pr.executeQuery();//executeBatch();
}
Let's talk in O-O-P way.
Here Inquiries is your model, model is nothing but simple class that has instance members and public methods to get and set value of model's instance variable.
Generally we put all database related operations code in their respective models.
e.g. I have model "Model" which typically maps to database table say it as "TableModel" ,I would do something like this:
public class Model{
private int id;
private String attr;
//other properties of the model
public int getId(){
return id;
}
public void setId(int id){
this.id=id;
}
//other getters and setters
//here we write methods to performs database operations
public void save(){
//use "this" to get properties of object
//logic to save to this object in database table TableModel as record
}
public void delete(int id){
//logic to delete this object i.e. from database table TableModel
}
public Model get(int id){
//retrieve record from table TableModel with this id
}
//other methods to get data from database.
}
Now question is how I can use this in some another class. Let's say I have list of Model objects and I wish to insert them in to database.I will do it something like this:
public class AnotherClass{
public void someMethod(){
//create list of models objects e.g. get them from user interface
ArrayList<Model> models=new ArrayList<>();
for(int i=0;i<3;i++){
Model model=new Model();
model.setId(i);
model.setAttr("attr"+i);
models.add(model);
}
SomeOtherClass obj=new SomeOtherClass();
obj.insert(models);
}
}
public class SomeOtherClass{
//other code above.....
//my method that inserts each Model object in database
//Note: this is sample method , you should do it in optimized way
// e.g. batch insert
public void insert(ArrayList<Model> models){
for(Model myModel:models){
myModel.save();
}
}
//other code below.....
}
You are using the wrong type parameter for the ArrayList. Instead of ArrayList<String> you need ArrayList<Inquiries>. To fix the problem, you should remove this code ...
ArrayList<String> arrInq = new ArrayList<String>();
arrInq.add(name);
arrInq.add(mail);
arrInq.add(tp);
arrInq.add(msg);
... and replace it with this code:
ArrayList<Inquiries> arrInq = new ArrayList<Inquiries>();
arrInq.add(new Inquiries(name, mail, tp, msg));
I have created a database and every entry from the JList will be added to a table in the database. This work perfectly, but my next task is to get whatever is in the database to load to the JList. I have a function created within the button but it brings up errors. I'm struggling with how to fix this so I hope somebody can resolve it.
Thanks
Here is my code:
JButton btnDb1 = new JButton("J");
btnDb1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
ResultSet rs = st.executeQuery("SELECT * FROM patient");
while (rs.next()) {
Patient patient = new Patient(patientname, patientaddress, patientphone, patientid);
patient.setName(rs.getString("patientname"));
patient.setAddress(rs.getString("patientaddress"));
patient.setPhoneNum(rs.getString("patientphone"));
patient.setID(rs.getInt("patientid"));
MainDentist.model.addElement(patient);
}
} catch (Exception e) {
System.out.println(" Error ");
}
}
});
btnDb1.setBounds(200, 393, 120, 23);
contentPane.add(btnDb1);
Here is my patient class:
public class Patient {
public String patientName;
public String patientAddress;
public String patientPhone;
public int patientID;
public Patient(String patientname, String patientaddress, String patientphone,int patientid){
patientName = patientname;
patientAddress = patientaddress;
patientPhone = patientphone;
patientID = patientid;
}
public String setName(String patientname){
return patientName = patientname;
}
public String getName(){
return patientName;
}
public String setAddress(String patientaddress){
return patientAddress = patientaddress;
}
public String getAddress(){
return patientAddress;
}
public String setPhoneNum(String patientphone){
return patientPhone = patientphone;
}
public String getPhoneNum(){
return patientPhone;
}
public int setID(int patientid){
return patientID = patientid;
}
public int getID(){
return patientID;
}
public String toString() { // Printing the patient's details to the scroll pane
return "Patient Name: " + patientName + ", PatientAddress: "
+ patientAddress + ", PatientPhone: " + patientPhone
+ ", patientID: " + patientID +"" ;
}
}
Let me rephrase the actionlistener – posting code in comments isn't really helpfull :)
First I would put the code from your actionPerformed method somewhere else, best would be even to create some class that handles the whole reading and maybe writing of the database. That way you don't mix reading the database with pushing buttons (maybe you want to create another button that reads the database, too. Then you don't have to write all the code again). Anyway, this is an example:
JButton btnDb1 = new JButton("J");
btnDb1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
readDatabase();
}
});
public void onActionPerformed(){
try {
// I don't know where you have that part of code, but you didn't create any statement variable. So here an example DB-connection:
String url = "jdbc:mysql://localhost/myDatabase";
Connection connection = DriverManager.getConnection(url, "username", "password");
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery("SELECT * FROM patient");
while (rs.next()) {
// read the columns one by one, that way it may be easier to detect errors if one column is wrong
String name = rs.getString("patientname");
String address = rs.getString("patientaddress");
String phone = rs.getString("patientphone");
int id = rs.getInt("patientid");
// now that you have all values, create the patient and add it to the model
// if you have all parameters for the constructor, you don't need to use the setters to set the name and address …
MainDentist.model.addElement(new Patient(name, address, phone, id));
}
} catch (Exception e) {
// as JB Nizet suggested, it is easier to detect errors, when you print the whole stack trace (it will tell you in which line the exception gets thrown
e.printStackTrace();
}
}
This still may not work right away, if you get errors, edit your post and tell us what goes wrong. BTW: I noticed that you have your variables name, address and all this in the patient set to public. This isn't wrong but it is recommended to use getter and setters (as you do) and make the variables private. That way you can control how the variables get accessed from outside.
Hello all i want is to display entire content of my database table on Console. I am trying to fetch record from database first and store in ArrayList but it does not display any thing insted it display this:
[com.suven.java.EmployeeDTO#970c0e]
[com.suven.java.EmployeeDTO#970c0e, com.suven.java.EmployeeDTO#987197]
[com.suven.java.EmployeeDTO#970c0e, com.suven.java.EmployeeDTO#987197, com.suven.java.EmployeeDTO#497904]
I am fully confused to what to do. My code is:
EmployeeDTO java file
public class EmployeeDTO
{
//private properties
private int empNo;
private String eName;
private String jobTitle;
//setters
public void setEmpNo(int val){empNo=val;}
public void setEName(String val){eName=val;}
public void setJob(String val){jobTitle=val;}
// getters
public int getEmpNo(){return empNo;}
public String getEName(){return eName;}
public String getJob(){return jobTitle;}
}
My EmployeeList java code is:
public class EmployeeList
{
public static void main(String argv[])
{
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
try
{
// Load the JDBC driver
// This can be skipped for Derby, but derbyclient.jar has to be in the CLASSPATH
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String accessFileName = "E:/Database/java";
conn=DriverManager.getConnection("jdbc:odbc:DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ="+accessFileName+".accdb;");
// Build an SQL String
String sqlQuery = "SELECT * from Employee";
// Create a Statement object
stmt = conn.createStatement();
// Execute SQL and get obtain the ResultSet object
rs = stmt.executeQuery(sqlQuery);
ArrayList<EmployeeDTO> employees = new ArrayList<EmployeeDTO>();
// Process the result set - print Employees
while (rs.next())
{
EmployeeDTO currentEmp = new EmployeeDTO();
currentEmp.setEmpNo(rs.getInt("EMPNO"));
currentEmp.setEName(rs.getString("ENAME"));
currentEmp.setJob(rs.getString("JOB_TITLE"));
employees.add(currentEmp);
System.out.println(employees);
}
}
catch( SQLException se )
{
System.out.println ("SQLError: " + se.getMessage ()+ " code: " + se.getErrorCode ());
}
catch( Exception e )
{
System.out.println(e.getMessage());
e.printStackTrace();
}
finally
{
// clean up the system resources
try
{
rs.close();
stmt.close();
conn.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
My database is:
Employee
EMPN ENAME JOB_TITLE
1 abc xyz
2 pqr mno
3 lmn hij
Please help me i have posted my full code and database
where am i going wrong how to display it in a console
You have to implement toString() in your EmployeeDTO class. If you are using Eclipse you can generate the method: right click the class -> Source -> Generate toString()...
ArrayList<EmployeeDTO> employees = new ArrayList<EmployeeDTO>();
// Process the result set - print Employees
while (rs.next())
{
EmployeeDTO currentEmp = new EmployeeDTO();
currentEmp.setEmpNo(rs.getInt("EMPNO"));
currentEmp.setEName(rs.getString("ENAME"));
currentEmp.setJob(rs.getString("JOB_TITLE"));
employees.add(currentEmp);
System.out.println(employees);
}
In this code, you are putting Object into ArrayList, not an actual String/Value into it. That's why you are getting as com.suven.java.EmployeeDTO#970c0e
You need to override toString in your EmployeeDTO class. You could use String.format to do the formatting:
#Override
public String toString() {
return String.format("%d\t%s\t%s", empNo, eName, jobTitle);
}
To print each employee on a separate line you could use:
for (EmployeeDTO employee : employees) {
System.out.println(employee);
}
Looks like you need an implementation of toString() in your DTO. You'd implement that such that it returns a string consisting of your employee name, job etc... Here's a link to 10 tips for implementing toString().
I note also that you print the list of employees after you read each employee. I suspect rather that you need to print the employee itself.
System.out.println(employees); // this is the list itself!
You are doing it all right except in the line
System.out.println(employees);
in the while loop.
You cannot display ArrayList like that with out overloading toString() in your EmployeeDTO class.
Instead, to display array list, do this after the while loop
for(EmployeeDTO emp : employees)
{
System.out.println(emp.getEmpNo() + " " + emp.getEName() + " " + emp.getJob());
}
I'm working on a java swing application which handles Customer management for a shop.
I'm trying to build it based on the mvc pattern, but actually i'm somewhat unexperienced in it.
Basically, theres a View with some Textfields for Customer Creation and of course the class called Customer. If the form is submitted an object of Customer is created and saved to the database.
Now, my problem was setting up a view to show all Customers in a JTable. Actually, not the view itself was the problem, but refreshing the view, when a new customer was added or a customer was changed.
Therefore i created a new class called "Customers" which had an arraylist with all customers in it and everytime a customer was created, it was added to this arraylist.
When the mainframe of my application started, an object of "Customers" was created, fetching all customers from my database, putting it in the arraylist just for the jtable.
the jtable was added to the object of customers as a listener and had an interface called CustomerListener implemented, which set a new model everytime the arraylist of customers changed.
mh okay, now i really have problems explaining what my problem is but, basically i thought this class "customers" was redundant, so i just added the arraylist and stuff to my "normal" "Customer" class:
package v1a;
import java.sql.ResultSet;
import java.util.ArrayList;
public class Customer {
public static final String KUNDENNUMMER = "Kundennummer";
public static final String ANREDE = "Anrede";
public static final String NACHNAME = "Nachname";
public static final String VORNAME = "Vorname";
public static final String PLZ = "PLZ";
public static final String ORT = "Ort";
public static final String STRASSE = "Strasse";
public static final String LAND = "Land";
public static final String TELEFON = "Telefon";
public static final String MOBIL = "Mobil";
public static final String EMAIL = "Email";
public static final String[] CUSTOMER_FIELDS = { KUNDENNUMMER, ANREDE, NACHNAME, VORNAME, PLZ, ORT, STRASSE, LAND, TELEFON, MOBIL, EMAIL };
private String kn, anrede, nachname, vorname, plz, ort, strasse, land, telefon, mobil = "", email = "";
private ArrayList<Customer> customers = new ArrayList<Customer>();
private ArrayList<ICustomerModelListener> listeners = new ArrayList<ICustomerModelListener>();
public Customer() {
getAllFromDatabase();
}
public Customer(String[] str) {
this.kn = str[0];
this.anrede = str[1];
this.nachname = str[2];
this.vorname = str[3];
this.plz = str[4];
this.ort = str[5];
this.strasse = str[6];
this.land = str[7];
this.telefon = str[8];
this.mobil = str[9];
this.email = str[10];
}
public void getAllFromDatabase(){
SQL.getInstance();
ArrayList<Customer> arrlist = new ArrayList<Customer>();
ResultSet rs = SQL.select("SELECT kundennummer, anrede, name, vorname, strasse, plz, ort, land, telefon, mobil, email FROM kunden");
try {
while(rs.next()){
String[] values = new String[Customer.CUSTOMER_FIELDS.length];
values[0] = String.valueOf(rs.getInt("kundennummer"));
values[1] = rs.getString("anrede");
values[2] = rs.getString("name");
values[3] = rs.getString("vorname");
values[4] = rs.getString("strasse");
values[5] = String.valueOf(rs.getInt("plz"));
values[6] = rs.getString("ort");
values[7] = rs.getString("land");
values[8] = rs.getString("telefon");
values[9] = rs.getString("mobil");
values[10] = rs.getString("email");
Customer c = new Customer(values);
arrlist.add(c);
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
SQL.cleanup();
this.customers = arrlist;
for(ICustomerModelListener l : listeners){
l.CustomerChanged();
}
}
public ArrayList<Customer> getAll(){
return customers;
}
public void addCustomer(Customer customer){
customers.add(customer);
for(ICustomerModelListener l : listeners){
l.CustomerChanged();
}
}
public void addListener(ICustomerModelListener listener){
listeners.add(listener);
}
public static boolean knExists(int kn){
boolean bool = false;
SQL.getInstance();
ResultSet rs = SQL.select("SELECT kundennummer FROM kunden WHERE kundennummer = "+kn);
try {
while(rs.next()){
bool = true;
}
} catch (Exception e){
System.out.println(e.getMessage());
}
SQL.cleanup();
return bool;
}
public static int getFreeKn(){
SQL.getInstance();
ResultSet rs = SQL.select("SELECT kundennummer FROM kunden ORDER BY kundennummer DESC LIMIT 1");
int kn = 0;
try {
while(rs.next()){
kn = rs.getInt("kundennummer");
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
kn++;
SQL.cleanup();
return kn;
}
public static Customer getByKn(int kn){
if(knExists(kn)){
SQL.getInstance();
ResultSet rs = SQL.select("SELECT * FROM kunden WHERE kundennummer = "+kn);
String[] values = new String[CUSTOMER_FIELDS.length];
try {
while(rs.next()){
values[0] = String.valueOf(rs.getInt("kundennummer"));
values[1] = rs.getString("anrede");
values[2] = rs.getString("name");
values[3] = rs.getString("vorname");
values[4] = String.valueOf(rs.getInt("plz"));
values[5] = rs.getString("ort");
values[6] = rs.getString("strasse");
values[7] = rs.getString("land");
values[8] = rs.getString("telefon");
values[9] = rs.getString("mobil");
values[10] = rs.getString("email");
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
Customer customer = new Customer(values);
SQL.cleanup();
return customer;
} else {
return null;
}
}
public boolean save() {
SQL.getInstance();
boolean bool = SQL.saveUser(this.kn, this.anrede, this.nachname, this.vorname, this.plz, this.ort, this.strasse, this.land, this.telefon, this.mobil, this.email);
SQL.cleanup();
return bool;
}
public String getValue(String s){
switch (s){
case KUNDENNUMMER:
return this.kn;
case ANREDE:
return this.anrede;
case NACHNAME:
return this.nachname;
case VORNAME:
return this.vorname;
case PLZ:
return this.plz;
case ORT:
return this.ort;
case STRASSE:
return this.strasse;
case LAND:
return this.land;
case TELEFON:
return this.telefon;
case MOBIL:
return this.mobil;
case EMAIL:
return this.email;
default :
return "";
}
}
}
NOW to my question:
is this the right way of modelling such a class regarding mvc pattern?
maybe my first approach was "cleaner" because i had something like a "container" which had all customers in it and the "real" customer class.
The current approach would drive me mad. You have a Customer class with 2 completely distinct behaviors:
When using the default constructor, you are actually storing the contents of the whole database in memory (well, at least of the customer table). So in this case a Customer instance actually represents the whole list of customers
When using the constructor with parameters, a Customer object now represents one Customer
In short, whenever you encounter a Customer instance in your code, you know absolutely nothing.
Further, storing the whole database in memory might be a bit overkill (although probably doable for a limited amount of customers). However, if you will be using this approach for more tables, you will quickly run out-of-memory. Consider only retrieving the data you actually need (for example in a JTable only a certain numbers of customers are visible at the same time, so no need to fetch them all).
And then their is the problem of mixing the business logic with the database logic. I would suggest to clearly separate your Customer class from the actual database access. You never know you will switch databases in the future (or opt for something different then a database). You do not want to rewrite your whole application at that point, just the data-access layer
No, Customer should have no database code in it and should not have an ArrayList<Customer> as these should be handled by other classes. It needs to be pure and needs to simply encapsulate the essence of a Customer, and that's it.
You need to refactor and subdivide some more.