我想仅使用MyBatis3来生成SQL字符串 (使用xml映射)但SQL i获取无效。
示例,我获取了sql字符串:
SELECT * FROM USER WHERE NAME = john
在这个sql中没有提供' 字符串字符串值 john
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>
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);
结果是
SELECT * FROM USERS
WHERE
name LIKE john AND num = 12345
在此SQL中,字符串 john 不会被&#39; 字符包围 所以它不是一个有效的SQL(我的目的只是使用myBatis生成有效的SQL字符串)。 我想要:
SELECT * FROM USERS
WHERE
name LIKE 'john' AND num = 12345
感谢
答案 0 :(得分:8)
您应该使用#{name} 而不是 $ {name} 。
以下示例将生成有效的SQL
<mapper namespace="sql1">
<select id="select1" parameterType="map" resultType="String" >
SELECT * FROM USERS
WHERE
name LIKE #{name} AND num = #{number}
</select>
</mapper>
如果您使用$ character,MyBatis会直接复制并粘贴字符串参数。另一方面,如果使用#character,则使用参数绑定。
然后,您应该使用selectMap,selectList或selectOne,
执行您的sqlList<String> resultSet = sessionFactory.openSession().selectList("sql1.select1", pars);
此调用将自动将参数绑定到语句并执行它。
警告:强>
<select id="select1" parameterType="map" resultType="String" >
SELECT * FROM USERS
WHERE
name LIKE #{name} AND num = #{number}
</select>
可能无法执行,因为MyBatis无法将多个列( SELECT * )映射到单个字符串( resultType =“String”),会显示对查询的两个可能更正下面:
<!--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>
对于解决方案二,您应该使用以下java代码执行mybatis查询:
List<Map<?, ?>> resultSet = sessionFactory.openSession().selectList("sql1.select1", pars);
参数绑定在驱动程序级别完成,因此您不会获得像这样的SQL字符串
SELECT * FROM USERS
WHERE
name LIKE 'john' AND num = 12345
相反,您将获得准备参数绑定的SQL查询模板,
SELECT * FROM USERS
WHERE
name LIKE ? AND num = ?
将参数添加到sql字符串中允许 sql注入。安全的方法是使用SQL Driver提供的参数绑定方法,MyBatis总是使用参数绑定。
假设您手动将sql命令创建为字符串,并假设我是一名试图访问您数据的appleius用户。我可以写
john' or ''='
所以这将生成下面的sql命令:
SELECT * FROM USERS
WHERE
name LIKE 'john' or ''='' AND num = 12345
参数绑定的第二个好处是它允许预准备语句。假设您需要使用不同的参数执行相同的sql 1000次。
如果生成带参数绑定的sql字符串,
SELECT * FROM USERS WHERE name LIKE 'john' AND num = 12345;
SELECT * FROM USERS WHERE name LIKE 'foo' AND num = 67890;
数据库服务器需要逐个解析每个sql命令,然后执行它们。
使用参数化的sql查询,
SELECT * FROM USERS WHERE name LIKE ? AND num = ?
SQL驱动程序缓存查询,因此只进行一次解析,然后将不同的参数绑定到相同的SQL命令。
您仍然可以将参数化sql(boundSql)与另一个库或Java的java.sql.Connection一起使用。以下是一个例子:
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();
答案 1 :(得分:0)
SELECT(" * ");
FROM(" student ");
WHERE(" ten LIKE '%' #{ten} '%' ");
您可以使用它,并且必须在'%'和#{}之间放置一个空格(_)