解释数据字符串并将其插入到 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 中的主要内容,如果未能解决你的问题,请参考以下文章