*Markus: SELECT mit Parameter mit Spring

Hallo,

kann mir jemand sagen, wie man mit Spring _vernünftig_ Ein SELECT ausführt, bei dem man zusätzlich Parameter angibt? Natürlich könnte ich den SQL-String zusammenstückeln, aber das ist meiner Meinung nach nicht wirklich sauber.
Gibt es wirklich keine Möglichkeit, die Parameter _einfach_ zu übergeben?
Bei INSERT musste ich bei der Parameterliste immerhin auch schon mit new Object[]{....} arbeiten. Bei SELECT-Parametern funktioniert das offensichtlicht nicht. Ich bekomme folgenden Fehler:

Caused by: org.postgresql.util.PSQLException: Der in SQL für eine Instanz von java.lang.Character zu verwendende Datentyp kann nicht abgeleitet werden. Benutzen Sie 'setObject()' mit einem expliziten Typ, um ihn festzulegen.

Was heißt das, Benutzen sie setObject()? Wie, wo? Aus welcher Klasse heraus?

Die Methode sieht so aus:

  
 @SuppressWarnings("unchecked")  
 @Override  
 public List<Fallbsp1KundenMitProduktenDerKategorieXBo> getKundenMitProduktenDerKategorieX(char kategorie) {  
        return (List<Fallbsp1KundenMitProduktenDerKategorieXBo>)getJdbcTemplate().query(  
          "SELECT k_vorname, k_nachname, p_produktbezeichnung, p_preis " +  
          "FROM kunde INNER JOIN preis ON p_id = p_k_kunde " +  
          "WHERE p_k_preiskategorie = ?", new Object[]{kategorie}, new RowMapper(){  
                @Override  
                public Object mapRow(ResultSet rs, int arg1) throws SQLException {  
                     Fallbsp1KundenMitProduktenDerKategorieXBo b = new Fallbsp1KundenMitProduktenDerKategorieXBo();  
                    b.setK_vn(rs.getString("k_vorname"));  
                    b.setK_nn(rs.getString("k_nachname"));  
                    b.setProdukt(rs.getString("p_produktbezeichnung"));  
                    b.setPreis(rs.getFloat("p_preis"));  
                return b;  
     }  
          });  
 }  
  

Markus

  1. Nachtrag:

    Zur Probe stückelte ich mal den SQL-String zusammen und musste feststellen, dass die Ausgabe mit einem Join so überhaupt nicht klappt. Es wird der erste Treffer richtig ausgegeben. Ab dem 2. Treffer werden die Werte aus "Preis", also p_produktbezeichnung, p_preis nicht mehr richtig ausgelesen. Es werden nämlich ab dem 2. Treffer immer wieder die Werte des ersten Treffers ausgegeben. Die Namen werden richtig ausgelesen.
    Was für ein Mist ist denn da passiert?

    Markus

    1. Ok vergesst das mit den doppelten Einträgen. Mein SQL-Statement war falsch.
      Ich würde somit nur gerne die erste Frage beantwortet bekommen.

      Markus

  2. Hej,

    Vorab: ich kenn mich mit Spring überhaupt nicht aus, aber mal schaun ob ich doch helfen kann:

    Gibt es wirklich keine Möglichkeit, die Parameter _einfach_ zu übergeben?

    Du meinst noch einfacher als ein return über 18 Zeichen zu programmieren? Mal im Ernst, wenn du bei dem Code den Überblick behälst nehm ich meinen Hut vor dir ,-)

    Bei INSERT musste ich bei der Parameterliste immerhin auch schon mit new Object[]{....} arbeiten.

    naja, als Behelf kann man sowas machen, aber ich finds recht dreckig.

    Caused by: org.postgresql.util.PSQLException: Der in SQL für eine Instanz von java.lang.Character zu verwendende Datentyp kann nicht abgeleitet werden. Benutzen Sie 'setObject()' mit einem expliziten Typ, um ihn festzulegen.

    Was heißt das, Benutzen sie setObject()? Wie, wo? Aus welcher Klasse heraus?

    Du wirst wahrscheinlich gebeten, anstatt der Methode JDBCTemplate.query( String sql, Object[] args, RowMapper rowMapper ), die Methode [link:http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jdbc/core/JdbcTemplate.html#query(java.lang.String,%20org.springframework.jdbc.core.PreparedStatementSetter,%20org.springframework.jdbc.core.RowMapper)@title=JDBCTemplate.query( String sql, PreparedStatementSetter psm, RowMapper rowMapper );] zu verwenden. Dem PreparedStatementSetter musst du ein java.sql.PreparedStatement übergeben, welches die Methode [link:http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html#setObject(int,%20java.lang.Object)@title=setObject( int ParameterIndex, Object x)] kennt.

    Beste Grüße
    Biesterfeld

    --
    Art.1: Et es wie et es
    Art.2: Et kütt wie et kütt
    Art.3: Et hätt noch immer jot jejange
    Das Kölsche Grundgesetz
    1. Hej,

      Vorab: ich kenn mich mit Spring überhaupt nicht aus, aber mal schaun ob ich doch helfen kann:

      Gibt es wirklich keine Möglichkeit, die Parameter _einfach_ zu übergeben?

      Du meinst noch einfacher als ein return über 18 Zeichen zu programmieren? Mal im Ernst, wenn du bei dem Code den Überblick behälst nehm ich meinen Hut vor dir ,-)

      Ich finde es auch schrecklich. Es gibt aber offensichtlich bei Spring keine Methoden mit vernünftigen Parametern, wo ich es "einfach" programmieren könnte.

      Bei INSERT musste ich bei der Parameterliste immerhin auch schon mit new Object[]{....} arbeiten.

      naja, als Behelf kann man sowas machen, aber ich finds recht dreckig.

      Ich auch. Diese Lösung bekam ich sogar von der Java-Newsgroup. Vorher sah es noch viel dreckiger aus. Ich sagte ja, man kann offensichtlich die Parameter nicht vernünftig übergeben.

      Du wirst wahrscheinlich gebeten, anstatt der Methode JDBCTemplate.query( String sql, Object[] args, RowMapper rowMapper ), die Methode [link:http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jdbc/core/JdbcTemplate.html#query(java.lang.String,%20org.springframework.jdbc.core.PreparedStatementSetter,%20org.springframework.jdbc.core.RowMapper)@title=JDBCTemplate.query( String sql, PreparedStatementSetter psm, RowMapper rowMapper );] zu verwenden. Dem PreparedStatementSetter musst du ein java.sql.PreparedStatement übergeben, welches die Methode [link:http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html#setObject(int,%20java.lang.Object)@title=setObject( int ParameterIndex, Object x)] kennt.

      Ich verstehe nicht, wie ich es verwenden soll. Ich habe keine Connection, mit der ich das Statement vorbereiten kann, da das Connection Handling Spring übernimmt.

      Markus

      1. Hej,

        Du wirst wahrscheinlich gebeten, anstatt der Methode JDBCTemplate.query( String sql, Object[] args, RowMapper rowMapper ), die Methode [link:http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jdbc/core/JdbcTemplate.html#query(java.lang.String,%20org.springframework.jdbc.core.PreparedStatementSetter,%20org.springframework.jdbc.core.RowMapper)@title=JDBCTemplate.query( String sql, PreparedStatementSetter psm, RowMapper rowMapper );] zu verwenden. Dem PreparedStatementSetter musst du ein java.sql.PreparedStatement übergeben, welches die Methode [link:http://java.sun.com/javase/6/docs/api/java/sql/PreparedStatement.html#setObject(int,%20java.lang.Object)@title=setObject( int ParameterIndex, Object x)] kennt.

        Ich verstehe nicht, wie ich es verwenden soll. Ich habe keine Connection, mit der ich das Statement vorbereiten kann, da das Connection Handling Spring übernimmt.

        Ich hatte auch einen Denkfehler drin: PreparedStatementSetter ist ein Interface, welches du selber, z.B. anonym überschreiben musst. Das PreparedStatement bekommst du durch die Implementierung der Methode [link:http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jdbc/core/PreparedStatementSetter.html#setValues(java.sql.PreparedStatement)@title=PreparedStatementSetter.setValues( PreparedStatement ps )] übergeben und musst entsprechend nur noch die Werte setzen, also z.B. durch

          
        new PreparedStatmentSetter() {  
          void setValues( PreparedStatement ps ) {  
            ps.setObject( 0, kategorie );  
          }  
        };  
        
        

        Oder so ähnlich. Wie gesagt ich kenn mich mit Spring nich aus. Aber dadurch würdest du zumindest den Aufruf der query( String sql, Object[] args, RowMapper rowMapper ) Methode umgehen können, die dir offensichtlich Probleme bereitet.

        Beste Grüße
        Biesterfeld

        --
        Art.1: Et es wie et es
        Art.2: Et kütt wie et kütt
        Art.3: Et hätt noch immer jot jejange
        Das Kölsche Grundgesetz
        1. Danke für deine Hilfe.
          Ich werde mir das morgen genauer ansehen.

          Markus