解释数据字符串并将其插入到 Java 中正确列位置的 JTable 中

Posted

技术标签:

【中文标题】解释数据字符串并将其插入到 Java 中正确列位置的 JTable 中【英文标题】:Interpreting data strings and inserting it into a JTable in the correct column positions in Java 【发布时间】:2012-08-15 15:42:03 【问题描述】:

我担心我的 Java 客户端直接连接到 mysql 服务器,因为这可能会出现所有问题,并且我认为它可能会带来安全风险。例如有人能够反编译文件并获取数据库的登录详细信息。尽管它很漂亮,但我不敢冒这个险。我编写了一个 php 脚本来回显客户端可以解释的数据。 PHP 脚本是连接到 MySQL 的。

比较简单:Java->PHP->MySQL

我将提供 MySQL 结构的屏幕截图,以便您在尝试将其可视化时更好地理解。

id: 可能是 tid/sid

tid:教师编号,用于链接教师

sid:学生id,用于链接学生

gid:成绩编号

aid:作业 ID

gp:获得积分

pp:可能的点

评分行是针对每个学生的每个作业。因此,例如,如果一位教师将 30 名学生分配给一项作业,那么评分选项卡中将有 30 行,而作业中将有 1 行。不允许使用重复的作业名称。

当客户端请求数据时,我只是使用缓冲的阅读器和 URL 来下载字符串。这是客户端收到分配名称时的示例输出。

Test Assignment;Secondary Test Assignment;

这是下载列名后客户端的外观:

如您所见,前两列默认存在,后两列是分配名称。

我希望表格中的每一行都是学生。但是,这就是我的麻烦所在。我正在尝试从分级中接收正确的数据。我不知道我要怎么做。我有大约 3 个月的 Java 经验,所以你绝对可以称我为新手。

这是我的想法,但我不认为这是个好主意: 搜索所有列名并将值插入到与分配名称匹配的行中的正确列中。

我不知道那会有多困难。我猜开发swing的好人为此做了一些事情,但我找不到任何资源。

有人对在这种情况下该怎么做有任何建议吗?我感到迷茫。

【问题讨论】:

JTable+JDBC: Easiest way 或 how to display all the data from the database to jtable? 的可能重复 @trashgod 不,我很生气,你只是看到了这个问题,却从不打扰阅读它。这不是使用 JBDC,而是使用我制作的自定义 PHP 桥。 不了解您的自定义 PHP 桥接器的工作原理,我猜您会想要扩展 AbstractTableModel 或子类,如引用的示例所示。 【参考方案1】:

让我们从 Java 客户端开始。下面是一些从 php 页面读取并从中创建 JTable 的代码。 (实际上它是从String 读取的,为简单起见,但您可以轻松更改代码以匹配您的实际情况,请参阅代码中的注释)。

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);

直到现在都没有什么困难的。真正的事情是使用正确的查询编写 php 页面。显然,你更清楚你希望你的页面输出什么,但我想你会这样做:

<?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();
?>

当然,我在这里提供的代码是非常近似的(鉴于我可以从您的问题中提取的信息),因此可以肯定的是,您需要调整代码以使其按您的意愿工作,但我希望它可以帮助您入门(继续前进:))。

【讨论】:

谢谢,这正是我想要的。谢谢你的意见,也尼克,这很好。这只是我的首选答案。我可以轻松地将其应用到我当前的项目中,我只需要集思广益。【参考方案2】:

就保护您的数据库而言,我建议创建一个只能执行存储过程的锁定用户 - 这样您就不必担心有人会反编译您的代码。他们只能通过您的代码访问他们可以访问的内容。 Here's a tutorial 如何做到这一点。

就您的主要问题而言,我建议您在 SQL 查询中完成所有数据收集/排序。如果您在JTable 中这样做,您最终会混合您的模型和视图(请参阅MVC 了解更多详细信息)。

因此,您基本上希望您的数据以这种形式从查询中返回:

Student; Student Name; Test Assignment; Secondary Test Assignment

也就是说,

    您需要在成绩表和作业表之间添加关系(很可能将 aid 添加到 grading 表中)

    你需要想出一个稍微复杂一点的 SQL 查询 - 像这样:

    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

    根据数据创建一个二维数组并将其放入表中(如果您仍在使用 PHP 界面,则需要拆分分隔符上的字符串以创建一个二维数组。)

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

编辑 如果您确信您只想在行中搜索一个值,然后更新您找到的行中的一列 - 这应该会让您朝着正确的方向前进:

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);
    

【讨论】:

这并没有真正解决,我相信它比我的原始设计更复杂。我只是在问我如何才能做到这一点,以便客户端可以为接收到的数据正确匹配行中的列。 在设置方面会稍微复杂一些,但在编码/维护方面会容易得多。因为每个成绩都与一项作业相关联,所以做 #1 是有意义的。为了避免所有代码试图将学生与作业匹配(SQL 很容易为您做这件事),做 #2 是有意义的。 #3 只是解释如何使用收到的数据更新表。如果您需要有关如何Search through all of the column names and insert the value into the proper column in that row where assignment name matches. 的指导,我将编辑我的答案以添加该内容。

以上是关于解释数据字符串并将其插入到 Java 中正确列位置的 JTable 中的主要内容,如果未能解决你的问题,请参考以下文章

java中对插入排序的理解以及实例

在java中插入超过8000个字符并带有换行符的sql列

从 SQL 获取数据并将其插入到 Java 文本字段中

JAVA 算法---插入排序算法

插入排序

算法——插入排序