データベースに接続し、クエリを実行し、データベースからのデータを変数に割り当てるメソッドを含むクラスがあります。
この Java プログラムの目的は、クライアントのサーバーのセキュリティ脅威に関する情報を格納するデータベースをスキャンすることです。クエリが実行されると、攻撃の数 (target_stats.num_attacks) が 0 を超えていることが読み取られると、2 つのテーブル (target_stats と attack_stats) から選択されたデータ フィールドが返されます。
ターゲット テーブルからデータを正常に取得できますが、攻撃者のテーブルから null 値が取得され、データベース内のフィールドが null ではないことがわかっています。
私の質問: 好ましくない結果を引き起こしている私のクエリでエラー (おそらく論理エラー) を検出できる人はいますか? 私は初心者のプログラマーで、SQL にはかなり慣れていません。
また、私はこのプログラムでセッターとゲッターを学習中です。取得したデータはすべて別のクラスで使用する予定ですが、今のところターゲットフィールドだけでテストおよび学習しています。おそらくそれが問題を引き起こしていますか?
更新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) { new 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);
} }