2016-11-10 35 views
0

循環運行的MySQL我有以下內容的3個表:用java

Author 
idAuthor INT 
name VARCHAR 

Publication 
idPublication INT 
Title VARCHAR 
Date YEAR 
Type VARCHAR 
Conference 

author_has_publication 
author_idAuthor INT 
publication_idPublication INT 

我嘗試做了作者的關係模式。目標是顯示他們共同發表的刊物數量。作者姓名是參數,我最多可以有8個名字。我的代碼給出了兩位作者之間的常見發佈數量,所以我必須循環它。我目前使用Java循環和SQL語句來做到這一點。這裏是SQL部分

private int runQuery(String a1, String a2){ // a1 author 1 and a2 author 2 
     try { 
      auth1 = new ArrayList<String>(); 
      Class.forName("com.mysql.jdbc.Driver"); 
      Connection connection = DriverManager.getConnection(
        "jdbc:mysql://localhost:3306/mydb", "root", "ROOT"); 
      Statement stmt = connection.createStatement(); 
      long start = System.currentTimeMillis(); 


      String queryUpdate1 = "DROP TABLE IF EXISTS temp1;"; 
      String queryUpdate2 = "DROP TABLE IF EXISTS temp2;"; 
      String queryUpdate3 = "CREATE TEMPORARY TABLE IF NOT EXISTS temp1 AS (SELECT Author.name, Publication.idPublication, Publication.title FROM Author INNER JOIN Author_has_Publication ON Author_has_Publication.author_idAuthor=author.idAuthor INNER JOIN Publication ON Author_has_Publication.publication_idPublication=publication.idPublication WHERE Author.name='"+ a1+"');"; 
      String queryUpdate4 = "CREATE TEMPORARY TABLE IF NOT EXISTS temp2 AS (SELECT Author.name, Publication.idPublication, Publication.title FROM Author INNER JOIN Author_has_Publication ON Author_has_Publication.author_idAuthor=author.idAuthor INNER JOIN Publication ON Author_has_Publication.publication_idPublication=publication.idPublication WHERE Author.name='"+ a2+"');"; 
      String query = "SELECT COUNT(*) FROM (SELECT temp1.title from temp1 INNER JOIN temp2 on temp1.idPublication = temp2.idPublication) as t;"; 

      stmt.executeUpdate(queryUpdate1); 
      stmt.executeUpdate(queryUpdate2); 
      stmt.executeUpdate(queryUpdate3); 
      stmt.executeUpdate(queryUpdate4); 
      ResultSet rs = stmt.executeQuery(query); 
      int result = -1; 
      while (rs.next()) { 
       result = rs.getInt(1); 
      } 

      System.out.println("result = " + result); 
      long end = System.currentTimeMillis() - start; 
      queryTimeLabel.setText("Query Execution Time :"+end); 
      connection.close(); 
      return result; 
     } catch (Exception e) { 
      System.out.println(e); 
     } 
     return -1; 
    } 

這裏是循環的一部分(重複時,有鑑於超過2名作家的SQL),並生成圖形:

public void actionPerformed(ActionEvent e) { 

    graph = new mxGraph(); 
    Object parent = graph.getDefaultParent(); 
    authVertex = getAuthors(); 



    // /////////////////////////////////// 
    // CREATES GRAPH, Graph only shows up after you resize the window 
    graph.getModel().beginUpdate(); 
    try { 

     int i = 0; 
     for(String a: authVertex.keySet()){ 
      int j = 0; 
      for(String b: authVertex.keySet()){ 
       if(j > i) { 
        graph.insertEdge(parent, null, String.valueOf(runQuery(a,b)), authVertex.get(a), authVertex.get(b)); // loop the SQL statement 2 by 2. 
       } 
       j++; 
      } 
      i++; 
     } 
    } finally { 
     graph.getModel().endUpdate(); 
    } 

    graphComponent = new mxGraphComponent(graph); 
    graphPan.removeAll(); 
    graphPan.add(graphComponent); 
    setVisible(true); 
    // ///////////////////////////////////////// 


} 

我的代碼目前正在,但我想知道是否有可能通過將所有內容傳遞到MySQL來提高性能,這意味着我在參數中輸入作者名稱並且循環由MySQL掛起,我檢查MySQL過程,但是我的問題是如何處理作者姓名參數,因爲它是一個變量。

+0

閱讀了關於JOIN – e4c5

+0

你應該使用'Prepared' statements.If你有沒有考慮過這個,我可以寫一個答案吧,和一些性能改進技術。 – GOXR3PLUS

+0

我認爲你可以使用子查詢和連接來完成它。 – chomnoue

回答

0

的一種方式,在單個語句:

SELECT COUNT(*) 
    FROM Author_has_Publication AS ap1 
    JOIN Author_has_Publication AS ap2 ON ap1.publication_idPublication = 
              ap2.publication_idPublication 
    JOIN Author AS a1 ON ap1.author_idAuthor = a1.id_Author 
    JOIN Author AS a2 ON ap2.author_idAuthor = a2.id_Author 
    WHERE a1.name = '...' 
     AND a2.name = '...' 

另一種方式可能是

SELECT COUNT(*) 
    FROM 
    (
     SELECT ahp.publication_idPublication, COUNT(*) 
      FROM Author_has_Publication AS ahp 
      JOIN Author AS a ON a.id_Author = ahp.author_idAuthor 
      WHERE a.name IN ('...', '...') 
      GROUP BY ahp.publication_idPublication 
      HAVING COUNT(*) = 2 -- Number of authors 
    ) x 

複合索引需要:

Author_has_Publication: (author_idAuthor, publication_idPublication) 
Author_has_Publication: (publication_idPublication, author_idAuthor) 
Author: (name, id) 

注:每個技術可以相當容易地擴展給2個以上的作者。第二個查詢甚至可以適用於「這5位作者中至少有3位」:INHAVING COUNT(*) >= 3中的5個名稱。