我有一个类,它包含连接到数据库,运行查询以及将数据库中的数据分配到变量的方法。
此Java程序的目的是扫描包含客户端服务器安全威胁信息的数据库。当查询运行时,它应该在读取攻击次数(target_stats.num_attacks)大于0时从2个表(target_stats和attack_stats)返回选定的数据字段。
我可以成功从目标表中检索数据,但是我从攻击者表中获取了空值,并且我知道该字段在数据库中不为空。
我的问题:任何人都可以在我的查询中检测到导致不利结果的错误(很可能是逻辑错误)吗?我是初学程序员,对SQL很新。
另外,我正在学习这个程序中的setter和getter,所有检索到的数据都将在另一个类中使用,但我现在正在测试和学习目标字段。也许这会导致问题?
UPDATE 我在MySQL查询浏览器中查询并获得相同的不利结果,因此问题只出现在我的查询逻辑中。我在查询和加入方面做了一些研究,但仍然缺乏适当的知识。
我的代码(希望我在格式中正确发布):
public class Database {
String details = null;
int threat_level = 0;
ResultSet rslt = null;
private String target2;
Connection con;
public void createConnection() {
//Establish a connection
try {
con = DriverManager.getConnection("sensitiveInformation");
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("Database connected");
}
public ResultSet getData() {
String query = "SELECT target_stats.server_id, target_stats.target, target_stats.threat_level, target_stats.client_id, attack_stats.attacker, attack_stats.num_this_attack " +
" FROM target_stats " +
" LEFT OUTER JOIN attack_stats " +
" ON target_stats.target = attack_stats.target " +
" WHERE target_stats.num_attacks > '0' " +
" AND target_stats.interval_id>'2'";
Statement stmt = null;
try {
stmt = con.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
try {
rslt = stmt.executeQuery(query);
} catch (SQLException e) {
e.printStackTrace();
}
return rslt;
}
public void process() {
try {
String server_id = rslt.getString("server_id");
target2 = rslt.getString("target");
threat_level = rslt.getInt("threat_level");
int client_id = rslt.getInt("client_id");
String attacker = rslt.getString("attacker");
String num_this_attack = rslt.getString("num_this_attack");
details = "Target IP: " + target2 + " Server ID: " + server_id + " Client ID: " + client_id + " Threat Level: " + threat_level + " Attacker IP: " + attacker + " Number of attacks: " + num_this_attack;
System.out.println(details);
} catch (SQLException e) {
e.printStackTrace();
}
}
public String getTraget2() {
return target2;
}
}
更新:我应该提一下,我在另一个类中有一个while循环,可以正确读取每条记录。
更新2:这是主要类,我现在不关心GUI元素:
public class MainDisplay extends JFrame {
static Toolkit tk = Toolkit.getDefaultToolkit();
static int Width = (int)tk.getScreenSize().getWidth();
static int Height = (int)tk.getScreenSize().getHeight();
public static JFrame frame = new JFrame();
public static JLayeredPane lpane = new JLayeredPane();
public static String target;
public static void main(String [] args){ 新的MainDisplay();
}
public MainDisplay(){
frame.setPreferredSize(new Dimension(Width, Height));
frame.setLocation(0,0);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
//NoRisk Run = new NoRisk();
//Run.NoThreat();
ThreatPanel Run = new ThreatPanel();
Database Data = new Database();
//Create Connection to Database and run query
Data.createConnection();
Data.getData();
try {
while(Data.rslt.next()){
Data.process();
Run.TargetServer = Data.getTraget2();
System.out.print(Data.getTraget2()); //for testing purposes
Run.ShowThreats();
try {
Thread.sleep(1000*10); // sleeps for ten seconds
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
//Run.ShowThreats();
frame.setLayout(new BorderLayout());
frame.add(lpane, BorderLayout.CENTER);
lpane.setBounds(0,0, Width, Height);
frame.pack();
frame.setVisible(true);
} }
答案 0 :(得分:1)
您是否尝试在数据库中执行相同的查询?你提到它应该返回一些结果,但你在插入代码之前在数据库中尝试过吗?如果数据库没有返回所需的结果,我们将查看查询语句,例如,而不是左外连接,您可能必须使用内连接。
答案 1 :(得分:1)
攻击者表中的字段可能不为空,但是当你有LEFT OUTER JOIN时 - 如果在attack_stats表中没有相应的数据,则查询中将包含空值 - 请检查。
查询看起来没问题 - 尝试使用 LEFT INNER JOIN - 然后在attack_stats表中没有相应数据的情况下,您将看不到任何行。
答案 2 :(得分:0)
Pat,你可以发布你的主要方法,从你调用这段代码的地方。您还应该迭代结果集以移动游标。
while(rslt.next())
{
String server_id = rslt.getString("server_id");
target2 = rslt.getString("target");
threat_level = rslt.getInt("threat_level");
int client_id = rslt.getInt("client_id");
String attacker = rslt.getString("attacker");
String num_this_attack = rslt.getString("num_this_attack");
details = "Target IP: " + target2 + " Server ID: " + server_id + " Client ID: " + client_id + " Threat Level: " + threat_level + " Attacker IP: " + attacker + " Number of attacks: " + num_this_attack;
System.out.println(details);
}