输入映射
本文主要讲解mybatis的输入映射(parameterType)。
通过parameterType指定输入参数的类型,类型可以是
- 简单类型
- hashmap
- pojo的包装类型
简单类型
其中,简单类型即java的基本数据类型
例如:根据id查找用户表中该用户的基本信息,此处parameterType类型为int简单类型
<select id="findUserById" parameterType="int" resultType="com.will.entiy.User">
SELECT * FROM user WHERE id=#{value}
</select>
hashmap类型
假设我们想查询王姓的男生的信息。那么我们可以这么些SQL语句:
<!-- 自定义条件查询用户列表 -->
<select id="findUserByUsernameAndSex" parameterType="map"
resultType="com.will.entiy.User">
select * from user where username like '${name}%' and sex = '${sex}'
</select>
parameterType定义为map,我们定义的接口也是接受Map作为参数。
public List<User> findUserByUsernameAndSex(Map map);
使用:
@Test
public void findUserByUsernameAndSexTest() throws Exception{
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//生成代理对象userMapper
Map<String, Object> paramsMap = new HashMap<String , Object>();
paramsMap.put("name", "王");
paramsMap.put("sex", "man");
List<User> user = userMapper.findUserByUsernameAndSex(paramsMap);
System.out.println(user);
}
输出:
==> Preparing: select * from user where username like '王%' and sex = 'man'
==> Parameters:
<== Columns: id, username, sex, birthday, address
<== Row: 5, 王小军, man, 2018-07-04, 河南郑州
<== Total: 1
[User [id=5, username=王小军, sex=man, birthday=Wed Jul 04 00:00:00 CST 2018, address=河南郑州]]
pojo的包装类型
通常我们只需要传递简单的POJO对象就可以了,还是和前面同样的需求,这次我们可以这样定义select元素:
<!-- 自定义条件查询用户列表 -->
<select id="findUserWithPOJO" parameterType="com.will.entiy.User"
resultType="com.will.entiy.User">
select * from user where username like '${username}%' and sex = '${sex}'
</select>
可以看到,此处parameterType和resultType都为User的实体类。
测试:
@Test
public void findUserWithPOJOTest() throws Exception{
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//生成代理对象userMapper
User user = new User();
user.setUsername("王");
user.setSex("man");
List<User> users = userMapper.findUserWithPOJO(user);
System.out.println(users);
}
结果显而易见,和上面一样的结果:
[User [id=5, username=王小军, sex=man, birthday=Wed Jul 04 00:00:00 CST 2018, address=河南郑州]]
也会返回和上面一样的结果,这里Mybatis会把POJO里对应的属性值传到SQL里,然后返回结果,注意看传入参数就是POJO的完全限定名,和ResultType是一样的,其实可以通过别名减少名称的长度,我们只需要在mybatis-config.xml中的configuration中定义:
<typeAliases>
<typeAlias alias="user" type="com.will.entiy.User" />
</typeAliases>
就可以用commodity替换所有的全称了,但是不能有重名的,否则会出错。
有些负责的情况,我们需要定义POJO作为查询参数,比如上面的例子,你只需要两个输入参数,你也可以定制一个只包含这两个参数的POJO。
public class FindDefineUserAndGender {
private String username;
private String sex;
}
当然使用过程还是一样的,定义自己包装过的POJO通常用来解决传入查询条件很复杂的情况,比如设计到几张表联查的,这时候原先定义的POJO解决不了问题,就需要定义一些复合的POJO。
这里再多说一句,在输入参数中还有个经常被提到的问题,即#和$的区别
#和$的区别
Mybatis本身是基于JDBC封装的。所以#{para}是预编译处理(PreparedStatement),相当于原来的?,而$ {para} 是字符串替换。Mybatis在处理#时,会调用PreparedStatement的set系列方法来赋值;处理时,就是把${para}替换成变量的值。#方式能够很大程度防止sql注入,方式一般用于传入数据库对象,例如传入表名,一般能用#的就别用$.