3

I'm concerned about my Java client directly connecting to the MySQL server due to all of the issues that could occur, and the security risks I believe it could pose. Such as someone being able to decompile the file and get the login details for the database. As beautiful as it would be, I'm too scared to take that risk. I've written a PHP script to echo data that the client can interpret. The PHP script is what connects to the MySQL.

It's rather simple: Java->PHP->MySQL

I'm going to provide screenshots of the MySQL structure, so you may better understand when trying to visualize this. enter image description here http://i.imgur.com/5EViC.png enter image description here enter image description here

id: possibly tid/sid

tid: teacher id, used to link to the teacher

sid: student id, used to link to the student

gid: grade id

aid: assignment id

gp: gained points

pp: possible points

Grading rows are for each assignment per student. So for example if a teacher had 30 students assigned to one assignment, there would be 30 rows in the grading tab and one in the assignments. Duplicate assignment names are NOT allowed.

When the client is requesting the data, I just use a buffered reader & URL to download the string. This is the example output of when the client receives the assignment names.

Test Assignment;Secondary Test Assignment;

This is what it looks like to the client once the column names are downloaded: enter image description here

As you can see the first two columns are there by default, the last two are assignment names.

I want each row in the table to be a student. However, here is where my trouble comes in. I'm trying to receive the proper data from grading. I don't know how I'm going to do this. I have about 3 months experience with Java, so you could definitely call me a newbie.

Here is my idea, but I didn't think it was so great of an idea: Search through all of the column names and insert the value into the proper column in that row where assignment name matches.

I didn't know how difficult that would be. I'm guessing the nice people who developed swing built something in for that, but I can't find any resources.

Does anyone have any recommendations on what to do in this situation? I feel lost.

kamaci
  • 72,915
  • 69
  • 228
  • 366
dead beef
  • 673
  • 2
  • 6
  • 20
  • 1
    possible duplicate of [JTable+JDBC: Easiest way](http://stackoverflow.com/q/8775076/230513) or [how to display all the data from the database to jtable?](http://stackoverflow.com/questions/8165685/how-to-display-all-the-data-from-the-database-to-jtable) – trashgod Aug 16 '12 at 10:18
  • 1
    @trashgod No, I am rather offended that you just simply saw the question and never bothered reading it. This is NOT using JBDC, it is using a custom PHP bridge I made. – dead beef Aug 16 '12 at 13:21
  • 3
    Absent any knowledge of how your custom PHP bridge works, I'm guessing you will want to extend `AbstractTableModel` or a subclass, as shown in the examples cited. – trashgod Aug 16 '12 at 17:48

2 Answers2

1

As far as securing your database, I'd recommend creating a locked down user that can only execute stored procedures - then you don't have to worry about someone decompiling your code. They'd only be able to access what they can access through your code. Here's a tutorial on how to do that.

As far as your main question goes, I would recommend all your data gathering/sorting be done in your SQL query. If you're doing that in the JTable, you end up mixing your Model and View (see MVC for more detail).

So essentailly you want your data coming back from the query in this form:

Student; Student Name; Test Assignment; Secondary Test Assignment

Which means,

  1. You need to add a relation between your grade table and your assignment table (most likely addding aid to the grading table)
  2. You're going to need to come up with a slightly more complicated SQL Query - something like this:

    Select g.sid, g.name, a.name from ASSIGNMENTS a join GRADING g on a.aid = g.aid where g.tid = 123123 order by g.name

  3. Create a 2D array based on the data and put it in the table (If you're still using your PHP interface, you'll want to split the strings on your delimiters to create a 2D array.)

    ((DefaultTableModel)table.getModel).setDataVector(data, columnNames);

EDIT If you're convinced you just want to search through the rows for a value, and then update a column in the row you found - this should get you in the right direction:

Integer searchStudentID = 123123;
int searchColumn = 0;
String updateValue = "Value";
int updateColumn = 3;

//Look through the table for the right row
Vector<Vector<Object>> data = ((DefaultTableModel)table.getModel()).getDataVector();
for(Vector<Object> row : data){
    // If on the right row, update it
    if(row.elementAt(searchColumn).equals(searchStudentID)){
        row.setElementAt(updateValue, updateColumn);
    }
}
Nick Rippe
  • 6,465
  • 14
  • 30
  • This doesn't really work out and I believe it's more complex than my original design. I was only asking how I could make it so the client could match up the columns in rows properly for the received data. – dead beef Aug 20 '12 at 18:00
  • It'll be a bit more complex on the setup side, but much easier on the coding/maintenance side. Because each grade is associated with an assignment, it makes sense to do #1. To avoid all the code trying to match up Students to assignments (something SQL will easily do for you) it makes sense to do #2. And #3 is just explaining how you'd update a table with the data you received. If you want some guidance on how to `Search through all of the column names and insert the value into the proper column in that row where assignment name matches.`, I'll edit my answer to add that. – Nick Rippe Aug 20 '12 at 19:15
1

Let's start with the Java client. Here is some code that reads from a php page and that creates a JTable out of it. (actually it's reading from a String for simplicity but you can easily change the code to match your real case, see the comment in the code).

public static void main(String[] args) throws Exception {
    String receivedFromPHP = "Student ID;Student Name;Test Assignment;Secondary Test Assignment;\n"
            + "1;Luc;Test assignment 1;Secondary Test assignment 1;\n"
            + "2;Vador;Test assignment 2;Secondary Test assignment 2;";

    BufferedReader br = new BufferedReader(new StringReader(receivedFromPHP));
    // For real: br = new BufferedReader(new InputStreamReader(new URL("http://localhost/yourPhpPage.php").openStream()));

    DefaultTableModel dtm = new DefaultTableModel();

    String line;
    boolean headersReceived = false;
    while ((line = br.readLine()) != null) {
        String[] columns = line.split(";");
        if (!headersReceived) {

            dtm.setColumnIdentifiers(columns);
            headersReceived = true;
        } else {
            dtm.addRow(columns);
        }
    }

    JTable table = new JTable(dtm);
    JFrame f = new JFrame();
    f.add(new JScrollPane(table));
    f.pack();
    f.setLocationRelativeTo(null);
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

Nothing really difficult until now. The real thing is to write the php page with the proper query. Obviously, you know better what you want your page to output but I guess your are going for something like this:

<?php

$mysqli = new mysqli("localhost", "my_user", "my_password", "pinkfluf_dvonx");

/* check connection */
if ($mysqli->connect_errno) {
    printf("Connect failed: %s\n", $mysqli->connect_error);
    exit();
}


/* Select queries return a resultset */
if ($result = $mysqli->query("SELECT Name FROM City LIMIT 10")) {
    printf("Select returned %d rows.\n", $result->num_rows);

    /* free result set */
    $result->close();
}

/* If we have to retrieve large amount of data we use MYSQLI_USE_RESULT */
if ($result = $mysqli->query('SELECT u.id AS "Student ID", u.username AS "Student Name", ... FROM members u, grading g, assignments a WHERE ...')) {

    while($row = $result->fetch_array(MYSQLI_NUM)) {
        for ($i=0; $i<sizeof($row); $i++) {
            echo $row[$i] . ";";
        }
        echo "\n";
    }

    $result->close();
}

$mysqli->close();
?>

Of course, the code I give here is very approximative (given the information I could extract from your question) so it's certain that you'll need to adapt the code to make it work as you'd like to but I hope it can help you getting started (keep going :)).

aymeric
  • 3,877
  • 2
  • 28
  • 42
  • Thank you, this is exactly what I was looking for. Thank you for your input also Nick, it was good. This is just my preferred answer. I can easily apply this to my current project, I'll just need to brainstorm some. – dead beef Aug 21 '12 at 01:26