2012-04-24 73 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

哇,这段代码极易受SQL注入攻击。想象一下,如果某人提交给定名称(不含双引号)“myname”; DROP TABLE agent; - “会发生什么情况。您至少需要使用参数化查询。 – 2012-04-24 03:11:36

+0

虽然不是直接的答案,但我强烈建议您查看(a)Facelets/JSF2和(b)JPA2。无论如何,请显示您正在从工作和非工作测试用例生成的查询文本。 – 2012-04-24 03:14:13

+0

据推测,如果DoB没有被给出,它不会匹配任何东西。这意味着您的给定名称/姓氏WHERE子句总是评估为false。没有数据,为什么很难说。这可能是大小写敏感,引用或各种各样的事情。 – 2012-04-24 03:17:09

回答

2

为了重申别人在上面指出的内容,这是“危险的”代码。通过不使用PreparedStatements,您可以自己开始使用SQL注入攻击 - 通过这种攻击,恶意用户可以制作SQL语句以删除表中的所有数据。正如@ craig-ringer所指出的那样,提交数据将会从数据库中删除表。

已经指出了这一点,强调了几次,在荧光黄色标记突出它,让我们继续前进,并尝试回答您的问题:

1)您可以通过使用SQL连接查询从多个表中的数据。 Here's a PostgreSQL tutorial on JOINS - 那里还有很多其他的东西,我只是挑选了我发现的第一个。

2)如果没有数据库中的确切数据以及提供的确切参数,很难回答 - 但是,我认为问题是区分大小写。 PostgreSQL中的比较区分大小写 - 所以如果数据库中的姓氏是'Smith'并且参数是'smith',则不会找到任何数据。因此,为了简单起见,您需要将参数和数据转换为相同的情况,例如降低。例如SELECT * FROM agent where LOWER(familyname)='smith'

我还想指出,您可能遇到日期格式化问题 - 这也将通过使用预处理语句解决。

看来你对java,SQL和JDBC来说是相当新的东西;我建议你尝试一些教程并阅读一些书。有很多事情需要处理 - 祝你好运!

+0

请注意,连接并不总是从多个表中检索数据集的最佳方法。除非它们都是纯粹的1:1关系,否则您通常不得不去除重复的内容。我经常喜欢从一个表中取出,然后从另一个SELECT中的另一个表中取出。它是否比加入速度快很多,取决于往返时间与带宽与CPU成本等因素,但它肯定会更好地阅读,并且在DB上更容易。看起来PostgreSQL将能够很快返回结构化的JSON或YAML查询结果:-) – 2012-04-24 13:30:53

+0

你怎么做两次Craig? – krest 2012-04-25 16:55:09