Je voudrais utiliser MyBatis3 uniquement pour produire la chaîne SQL (À l'aide du mappage xml), mais l'obtention de SQL i n'est pas valide.
Exemple, j'obtiens la chaîne SQL:
SELECT * FROM USER WHERE NAME = john
Dans ce sql n'est pas présent le 'char entourant la valeur de chaîne john
dans mybatis.xml :
...
<mappers>
<mapper resource="sql1.xml"/>
</mappers>
...
sql1.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="sql1">
<select id="select1" parameterType="map" resultType="String" >
SELECT * FROM USERS
WHERE
name LIKE ${name} AND num = ${number}
</select>
</mapper>
dans MyBatisSql.Java :
SqlSessionFactory sessionFactory = ConnectionFactory.getSqlSessionFactory();
Configuration configuration = sessionFactory.getConfiguration();
Map pars = new HashMap<String, Object>();
pars.put("name", "john");
pars.put("number", 1345);
MappedStatement ms = configuration.getMappedStatement("sql1.select1);
BoundSql boundSql = ms.getBoundSql(params);
String sql = boundSql.getSql();
System.out.println(sql);
le résultat est
SELECT * FROM USERS
WHERE
name LIKE john AND num = 12345
dans ce SQL, la chaîne john , n'est pas entourée par le 'charso n'est pas un code SQL valide (mon but est uniquement de produire une chaîne SQL valide à l'aide de myBatis). J'aimerais avoir:
SELECT * FROM USERS
WHERE
name LIKE 'john' AND num = 12345
merci
Vous devez utiliser # {nom} au lieu de $ {nom}.
L'exemple ci-dessous générera un code SQL valide
<mapper namespace="sql1">
<select id="select1" parameterType="map" resultType="String" >
SELECT * FROM USERS
WHERE
name LIKE #{name} AND num = #{number}
</select>
</mapper>
MyBatis copie et colle directement le paramètre chaîne si vous utilisez le caractère $. D'autre part, il utilise la liaison de paramètre si vous utilisez le caractère #.
Vous devez ensuite exécuter votre SQL avec selectMap, selectList ou selectOne,
List<String> resultSet = sessionFactory.openSession().selectList("sql1.select1", pars);
Cet appel liera automatiquement les paramètres à l'instruction et l'exécutera.
ATTENTION:
<select id="select1" parameterType="map" resultType="String" >
SELECT * FROM USERS
WHERE
name LIKE #{name} AND num = #{number}
</select>
l'exécution peut échouer car MyBatis ne peut pas mapper plusieurs colonnes (SELECT *) sur une seule chaîne (resultType = "String"). Deux corrections possibles de la requête sont présentées ci-dessous:
<!--Solution One-->
<select id="select1" parameterType="map" resultType="String" >
SELECT name FROM USERS
WHERE
name LIKE #{name} AND num = #{number}
</select>
<!--Solution Two-->
<select id="select1" parameterType="map" resultType="Java.util.LinkedHashMap" >
SELECT * FROM USERS
WHERE
name LIKE #{name} AND num = #{number}
</select>
Pour solution deux, vous devez exécuter la requête mybatis en utilisant le code Java ci-dessous:
List<Map<?, ?>> resultSet = sessionFactory.openSession().selectList("sql1.select1", pars);
La liaison des paramètres est effectuée au niveau du pilote afin que vous n'ayez pas une chaîne SQL comme celle-ci.
SELECT * FROM USERS
WHERE
name LIKE 'john' AND num = 12345
Au lieu de cela, vous aurez un modèle de requête SQL qui est prêt pour la liaison de paramètres,
SELECT * FROM USERS
WHERE
name LIKE ? AND num = ?
L'ajout de paramètres dans une chaîne sql autorise sql injection. La méthode la plus sûre consiste à utiliser la méthode de liaison de paramètre fournie avec SQL Driver et MyBatis utilise toujours la liaison de paramètre.
Supposons que vous ayez créé manuellement votre commande SQL en tant que chaîne et supposons que je sois un utilisateur malveillant en essayant d'accéder à vos données. je peux écrire
john' or ''='
Donc, cela va générer la commande SQL ci-dessous:
SELECT * FROM USERS
WHERE
name LIKE 'john' or ''='' AND num = 12345
Le deuxième avantage de la liaison de paramètres est qu’elle permet des instructions préparées. Supposons que vous ayez besoin d'exécuter le même sql 1000 fois avec des paramètres différents.
Si vous générez des chaînes SQL avec des paramètres liés,
SELECT * FROM USERS WHERE name LIKE 'john' AND num = 12345;
SELECT * FROM USERS WHERE name LIKE 'foo' AND num = 67890;
le serveur de base de données devra analyser chaque commande SQL une par une, puis les exécuter.
Avec des requêtes SQL paramétrées,
SELECT * FROM USERS WHERE name LIKE ? AND num = ?
Le pilote SQL met en cache la requête. L'analyse est effectuée une seule fois, puis il lie différents paramètres à la commande same SQL.
Vous pouvez toujours utiliser le sql paramétré (boundSql) avec une autre bibliothèque ou Java.sql.Connection de Java. Ci-dessous un exemple:
Connection myConnection;
PreparedStatement preparedStatement = myConnection.prepareStatement(boundSql);
preparedStatement.setString(1, "john"); //First parameter starts with 1 not 0!
preparedStatement.setInt(2, 12345);
ResultSet results = preparedStatement.executeQuery();
SELECT(" * ");
FROM(" student ");
WHERE(" ten LIKE '%' #{ten} '%' ");
Vous pouvez l'utiliser et vous devez mettre un espace (_) entre '%' et # {}