2010-04-21 5 views
2

Quelle est la meilleure façon d'assembler dynamiquement une requête SQL avec des conditions de jointure? Je ne veux pas coder la requête pour chaque condition différente sur une page Web ou un ensemble de pages Web. Est-ce que c'est même faisable?Assemblage dynamique de requêtes SQL en Java

J'obtenu aussi loin que d'être capable d'assembler des requêtes simples mais je m'y suis perplexe quand je besoin d'insérer des conditions de jointure, à savoir comment déterminer les dépendances pour les jointures, etc.

+0

StringBuffer est votre ami !!! :( –

+0

vous voulez dire stringbuilder ?? je suis déjà capable d'assembler des requêtes simples ... le problème est celui avec les conditions de jointure ... –

+0

Pouvez-vous donner un exemple? –

Répondre

0

Vous pouvez utiliser iBatis. Il a une caractéristique appelée Dynamic SQL. Avec cela, vous pouvez créer des requêtes dynamiques à l'exécution en fonction de plusieurs conditions.

+0

son un projet d'université .. suis à peu près p ositive ils n'ont pas installé sur leurs serveurs ...C'est pourquoi je suis en train d'écrire moi-même au lieu d'utiliser un orm ... –

+0

Quelqu'un at-il une idée sur la façon d'implémenter des conditions de jointure dans un modèle d'activationecord? –

1
public String AssembleSimpleSelectQuery(String TableName,Hashtable<String,String> criteria) { 
    Hashtable<String,String> columnlist = ReturnColumnList(TableName); 
    Iterator<String> iter = columnlist.keySet().iterator(); 
    int count = 0; 
    query=new StringBuilder(); 
    query.append("SELECT "); 
    while(iter.hasNext()) 
    { 
     count++; 
     query.append(iter.next()); 
     if(count < (columnlist.size())) 
     { 
      query.append(","); 
     } 
    } 
    query.append(" From " + TableName); 


    Iterator<String> crit = criteria.keySet().iterator(); 
    if(criteria.size()>0) 
    { 
     query.append(" where "); 
    } 
    count = 0; 
    while(crit.hasNext()) 
    { 
     count++; 
     String temp = crit.next(); 
     query.append(temp + "="); 
     if(columnlist.get(temp).equals("String") || columnlist.get(temp).equals("Id")) 
     { 
      query.append("'" + criteria.get(temp) + "'"); 
     } 
     else if(columnlist.get(temp).equals("Date")) 
     { 
      query.append("to_date('"+criteria.get(temp)+"','mm-dd-yyyy')"); 
     } 
     if(count < criteria.size()) 
     { 
      query.append(" and "); 
     } 
    } 
    return query.toString(); 
} 

/c'est la fonction d'échantillonnage qui crée une sélection requête simple -I appel returncolumnlist qui lit au large à partir d'un fichier XML qui stocke les noms de tables et leurs colonnes et renvoie une table de hachage des noms de colonnes et leurs types de données. ... --Je n'ai pas encore trouvé comment intégrer une condition de jointure (peut-être plus de 1) dans ce code ... donc la recherche d'idées pour cela ... je ne cherche pas de code .../

2

Mon approche préférée pour créer des requêtes dynamiques complexes est:

  1. Énumérer toutes les requêtes possibles (c.-à-d. modèles de requête) requis. Cela me permet de voir les points communs et de trouver des modèles pour lesquels un code générique peut être écrit.
  2. Générez chaque partie de l'instruction SQL séparément, puis concaténéz à la toute fin. par exemple. (Ce ne vise pas à être le code de travail, juste une esquisse d'une idée):

<pseudocode>

select_clause = 'SELECT ' 
from_clause = 'FROM ' 
where_clause = 'WHERE ' 
orderby_clause = 'ORDER BY ' 

if [query on person] then 
    select_clause += 'p.name, p.dob ' 
    from_clause += 'person p ' 
    orderby_clause += 'p.name ' 

    if [query on address] then 
    select_clause += 'a.address_text ' 
    from_clause += ', address a ' 
    where_clause += 'p.address_id = a.id AND a.id=:p1 ' 
    else 
    where_clause += 'p.id=:p1' 
    end if 

end if 

sql_stmt = select_clause + from_clause + where_clause + orderby_clause + ';' 

</pseudocode >

Ainsi, le code ci-dessus peut produire la les énoncés suivants:

SELECT p.name, p.dob 
FROM person p 
WHERE p.id=:p1 
ORDER BY p.name; 

SELECT p.name, p.dob, a.address_text 
FROM person p, address a 
WHERE p.address_id = a.id AND a.id=:p1 
ORDER BY p.name; 

Avec plus de paramètres Cette approche signifie que je n'ai pas à faire face à un nombre croissant de combinaisons possibles de critères.

0

Hibernate API pour construire des requêtes sans avoir à concaténer des chaînes du tout, voir ici:

http://docs.jboss.org/hibernate/core/3.5/api/org/hibernate/Criteria.html

+0

Il est toutefois peut-être exagéré d'utiliser Hibernate dans votre projet uniquement à cause de cette fonctionnalité particulière. – Juraj

+0

ouais .. c'est définitivement exagéré ... ce qui explique pourquoi je suis à écrire mon propre orm ici:) ... sorte de –