初学MyBatis,配置Mapper.xml中的SQL语句时有一些关于占位符和字符串拼接的疑问,例如:
<!-- namespace表示命名空间 -->
<mapper namespace="cn.wyc.mapper.UserMapper">
<select id="findUserById" parameterType="Integer" resultType="cn.wyc.po.User">
<!-- #{}表示占位符,中间表示待接收的参数 -->
select * from user where id = #{id}
</select>
</mapper>
在上面的代码中,select语句中最后的#{}表示一个占位符,用来接收参数,但是经测试,括号中写任意字母甚至数字都可以成功查找出用户。以下贴出test代码
@Test
public void findUserByIdTest() throws Exception {
// 读取配置文件
String resource = "mybatis-config.xml";
InputStream inputstream = Resources.getResourceAsStream(resource);
// 根据配置文件构建sessionFactory
SqlSessionFactory sqlsessionfactory = new SqlSessionFactoryBuilder().build(inputstream);
// 通过SqlSessionFactory创建SqlSession
SqlSession sqlsession = sqlsessionfactory.openSession();
// 通过SqlSession执行映射文件中的SQL,并返回映射结果
User user = (User) sqlsession.selectOne("cn.wyc.mapper.UserMapper.findUserById", 1);
// 打印输出结果集
System.out.println(user);
// 关闭SqlSession
sqlsession.close();
}
可以看到,在调用该查询方法时只是传了个1作为id,好像#{}内填什么都不会影响最终结果
sqlsession.selectOne("cn.wyc.mapper.UserMapper.findUserById", 1);
于是在拼接字符串时的SQL语句这么写以便测试:
<insert id="addUser" parameterType="cn.wyc.po.User">
insert into user(username,password,email) values(#{a},#{b},#{c})
</insert>
却发现添加失败,必须写成以下形式
insert into user(username,password,email) values(#{username},#{password},#{email}
请问${}和#{}括号中的内容有什么限制?
后来了解到:如果将要填入#{}中的是表中的主键,那么括号中可以填任何内容。
如果填入#{}中的不是主键,那么则要和po类中的属性名一致。${}中只能填value
另外,在测试调用插入方法时的代码如下:
User user = new User();
user.setUsername("yxy");
user.setPassword("123");
user.setEmail("123@qq.com");
int rows = sqlsession.insert("cn.wyc.mapper.UserMapper.addUser", user);
mybatis是如何识别对象user中的username、password、email并将其解析对应到SQL语句中的?
mybatis底层会获取到表的结构,通过字段名和属性名来映射