2012-04-24 18 views
0

複数のテーブルからデータを取得するのが難しい。これは、検索フォームとそのリレーショナルデータベースになります。Java Servletの複数のテーブル(PostgreSQL)からデータを取得するにはどうすればよいですか?

質問1:今、複数のテーブルからデータを取得するにはどうすればよいですか?

質問2:同時に私が直面するもう一つの問題は、名前または姓でしか検索しようとしても結果が得られないということです。私は生年月日を使用した場合にのみ結果を得ます。どうして?

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 

     java.io.PrintWriter out = response.getWriter(); 
     Connection conn = null;{ // while there is no connections, proceed to the next step 
     try { 
      Class.forName("org.postgresql.Driver"); // importing the driver to use the getConnection method 
      conn = DriverManager.getConnection(
        "jdbc:postgresql://localhost:5432/caglar", "postgres", //?searchpath=cag 
        "abracadabra"); 
      System.out.println("Connected to the database"); // console message 
      String agent_name = request.getParameter("givenname"); // variable - reads from user input 
      String agent_lastname = request.getParameter("familyname"); // variable - reads from user input 
      String dob = request.getParameter("birthyear"); // variable - reads from user input 

      ArrayList al=null; 
      ArrayList agent_list =new ArrayList(); 

      //Problem 1: If dob is not given, it is not searching by name or lastname. 

      //String query = "select * from agent where givenname='"+agent_name+"' or familyname='"+agent_lastname+"' or birthyear='"+dob+"' order by givenname"; 

      String query = "select * from agent where givenname='"+agent_name+"' or familyname='"+agent_lastname+"' "; 
      if(dob!=null && !"".equals(dob)) // if date of birth fiel is left blank, it will still proceed to the results page 
       query = query + " or birthyear='"+dob+"'"; // if date of birth exists, it will take it into account as well 

      query = query+ "order by givenname"; // ordering by first name 


      System.out.println("query" + query); // console message 
      Statement st = conn.createStatement(); // connection statement 
      ResultSet rs = st.executeQuery(query); // executing our query 


      while(rs.next()) 
      { 
       al = new ArrayList(); 

       al.add(rs.getString(1));//id 
       al.add(rs.getString(2));//dob 
       al.add(rs.getString(3));//name 
       al.add(rs.getString(4));//lastname 
       System.out.println("al :: "+al); 
       agent_list.add(al); 
      } 

      request.setAttribute("agentList",agent_list); 
+2

Woah、そのコードはSQLインジェクションに対して非常に脆弱です。もしも誰かが:(二重引用符なし) "myname '; DROP TABLE agent; - "の与えられた名前を提出するとどうなるか想像してみてください。少なくともパラメータ化されたクエリを使用する必要があります。 –

+0

直接回答ではありませんが、(a)Facelets/JSF2と(b)JPA2をチェックアウトすることを強くお勧めします。とにかく、あなたが作っているクエリーテキストを、動作中および動作していないテストケースから表示してください。 –

+0

おそらく、DoBが与えられていないと、それは何も一致しません。つまり、givenname/lastname WHERE句は常にfalseと評価されます。なぜデータなしで言うのは難しいのですか?大文字と小文字を区別したり、引用符で囲んだりすることができます。 –

答えて

2

他の人が上記のことを繰り返し述べると、これは「危険な」コードです。 PreparedStatementsを使用しないと、悪意のあるユーザーがSQL文を作成してテーブル内のすべてのデータを削除できるSQLインジェクション攻撃を開始します。上記の@craig-ringerが指摘しているように、データベースからテーブルを削除するデータは簡単に送信されます。あなたが参加SQLを使用して、複数のテーブルからデータを照会することができます)

1:それを指摘した

は、それを数回下線、蛍光黄色のマークでそれを強調し、上に移動し、ご質問にお答えしようとすることができます。 Here's a PostgreSQL tutorial on JOINS - そこには他にも多くのものがあります。最初に見つけたものを選んだだけです。

2)データベースに正確なデータがなく、正確なパラメータが提供されていないと、回答するのが難しいですが、問題の大文字と小文字が区別されると思います。 PostgreSQLの比較では大文字と小文字が区別されるため、データベースの姓が 'Smith'で、パラメータが 'smith'の場合はデータが見つかりません。したがって、簡単にするために、パラメータとデータの両方を同じケースに変換する必要があります。低い。例えばSELECT * FROM agent LOWER(familyname)= 'smith'

また、日付書式の問題に遭遇する可能性があることも指摘しておきます。

これは、あなたがJava、SQL、JDBCで新しくなったようです。いくつかのチュートリアルに従い、いくつかの本を読むことをお勧めします。グリップを得るにはかなりのことがあります - 幸運!

+0

複数の表からデータ・セットを検索するには、結合が必ずしも最良の方法とは限りません。すべてがきちんとした1:1の関係でなければ、しばしばコンテンツを重複排除する必要があります。私は頻繁に1つのテーブルからフェッチし、別のSELECTの別のテーブルからフェッチする方が好きです。往復時間と帯域幅とCPUコストなどによって、参加よりも速いかどうかは多少異なりますが、DBの方が読みやすく、しばしば簡単です。 PostgreSQLはJSONまたはYAMLの構造化された結果をすぐに返すことができます:-) –

+0

Craigを2回やりますか? – krest

関連する問題