Question

Je prévois de remplacer les objets Statement exécutés à plusieurs reprises par des objets PreparedStatement afin d'améliorer les performances. J'utilise des arguments tels que la fonction MySQL now () et des variables de chaîne.

La plupart des requêtes PreparedStatement que j'ai vues contenaient des valeurs constantes (telles que 10 et des chaînes telles que "New York") en tant qu'arguments. utilisé pour le ? dans les requêtes. Comment pourrais-je utiliser des fonctions comme now () et des variables comme arguments? Est-il nécessaire d'utiliser les ? dans les requêtes au lieu des valeurs réelles? Je suis assez confus.

Était-ce utile?

La solution

Si vous avez des variables, utilisez le '?'

int temp = 75;
PreparedStatement pstmt = con.prepareStatement(
    "UPDATE test SET num = ?, due = now() ");
pstmt.setInt(1, temp); 
pstmt.executeUpdate():

Produit une instruction SQL ressemblant à:

UPDATE test SET num = 75, due = now();

Autres conseils

Si vous avez une variable qui provient d'une entrée utilisateur, il est essentiel que vous utilisiez le caractère? plutôt que de concaténer les chaînes. Les utilisateurs peuvent entrer une chaîne de manière malveillante et, si vous la déposez directement dans SQL, celle-ci peut exécuter une commande non voulue.

Je réalise que celui-ci est surutilisé, mais il le dit parfaitement:

Petites tables de Bobby

Vous n'avez pas besoin d'utiliser des espaces réservés dans un PreparedStatement. Quelque chose comme:

PreparedStatement stmt = con.prepareStatement("select sysdate from dual");

fonctionnerait très bien. Cependant, vous ne pouvez pas utiliser un espace réservé et y lier un appel de fonction. Quelque chose comme ça ne peut pas être utilisé pour appeler la fonction sysdate:

PreparedStatement stmt = con.prepareStatement("select ? from dual");
stmt.setSomethingOrOther(1, "sysdate");

Si vous appelez des fonctions intégrées de votre serveur SQL, utilisez PreparedStatement .

Si vous appelez des procédures stockées chargées sur votre serveur SQL, utilisez CallableStatement .

Utilisez des points d'interrogation comme espaces réservés pour les paramètres de fonction / procédure que vous transmettez et les valeurs renvoyées par la fonction que vous recevez.

J'ai développé une fonction qui vous permet d'utiliser des paramètres nommés dans vos requêtes SQL:

private PreparedStatement generatePreparedStatement(String query, Map<String, Object> parameters) throws DatabaseException
    {
        String paramKey = "";
        Object paramValue = null;
        PreparedStatement statement = null;
        Pattern paramRegex = null; 
        Matcher paramMatcher = null;
        int paramIndex = 1;

        try
        {
            //Create the condition
            paramRegex = Pattern.compile("(:[\\d\\w_-]+)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
            paramMatcher = paramRegex.matcher(query);
            statement = this.m_Connection.prepareStatement(paramMatcher.replaceAll("?"),
                                ResultSet.TYPE_FORWARD_ONLY,
                                ResultSet.CONCUR_READ_ONLY, 
                                ResultSet.HOLD_CURSORS_OVER_COMMIT);

            //Check if there are parameters
            paramMatcher = paramRegex.matcher(query);
            while (paramMatcher.find()) 
            {
                paramKey = paramMatcher.group().substring(1);
                if(parameters != null && parameters.containsKey(paramKey))
                {
                    //Add the parameter 
                    paramValue = parameters.get(paramKey);
                    if (paramValue instanceof Date) 
                    {
                        statement.setDate(paramIndex, (java.sql.Date)paramValue);                 
                    } 
                    else if (paramValue instanceof Double) 
                    {
                        statement.setDouble(paramIndex, (Double)paramValue);                  
                    } 
                    else if (paramValue instanceof Long) 
                    {
                        statement.setLong(paramIndex, (Long)paramValue);                  
                    } 
                    else if (paramValue instanceof Integer) 
                    {
                        statement.setInt(paramIndex, (Integer)paramValue);                
                    } 
                    else if (paramValue instanceof Boolean) 
                    {
                        statement.setBoolean(paramIndex, (Boolean)paramValue);                
                    } 
                    else 
                    {
                        statement.setString(paramIndex, paramValue.toString());     
                    }
                }
                else
                {
                    throw new DatabaseException("The parameter '" + paramKey + "' doesn't exists in the filter '" + query + "'");
                }

                paramIndex++;
            }
        }
        catch (SQLException  l_ex) 
        {
            throw new DatabaseException(tag.lib.common.ExceptionUtils.getFullMessage(l_ex));
        }

        return statement;
    }

Vous pouvez l'utiliser de cette façon:

Map<String, Object> pars = new HashMap<>();
pars.put("name", "O'Really");
String sql = "SELECT * FROM TABLE WHERE NAME = :name";
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top