MyBatis获取参数
一、MyBatis获取参数的五种方式
1、单个字面量类型的参数
mapper接口中方法中的参数为单个字面量类型
简单来说,就是我们只需要传递一个参数,sql语句中需要通过该参数来进行操作
如:select * from t_user where id = 2
此时,我们的id就是单个字面量,2就是我们需要传递的参数。
- mapper接口方法
package mybatis.mapper;
import com.fulin.mybatis.pojo.User;
import java.util.List;
//相当于我们原来的dao
public interface UserMapper {
/**
* Mybatis面向接口编程的两个一致:
* 1. 映射文件的namespace要和mapper接口的全类名保持一致
* 2. 映射文件中SQL语句的id要和mapper接口中的方法名一致
* @return
*/
/**
* 通过id查询信息:
* 我们需要传递一个单字面量类型的参数
*/
User getUserById(String username);
}
- mapper.xml中实现(类似dao的接口实现类的功能)
<!--User getUserById(Integer id);-->
<select id="getUserById" resultType="User">
select * from t_user where id = #{id}
</select>
<!--User getUserById(Integer id);-->
<select id="getUserByUsername" resultType="User">
select * from t_user where username = '${username}'
</select>
注意:
- 我们使用${}的方式来接收参数时需要单引号,不然会报错,预编译中执行的sql语句应该就是select * from t_user where username = ‘fulin’
- #{}可以接收到参数值,{}里面的参数名可以任意取,但是我们尽量需要见名知义
- 测试代码
@Test
@Test
public void getAllUser(){
SqlSession sqlSession = getSqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUserByUsername("fulin");
System.out.println(user);
}
- 测试结果
2、多个字面量类型的参数
mapper接口方法中的参数有多个
如:select * from where id = 2 and username = ‘fulin’
此时我们mapper接口中的方法需要传递两个参数
- mapper接口方法
/**
* 通过username和password登录
*/
User checkLogin(String username, String password);
- mapper.xml中实现(类似dao的接口实现类的功能)
<!--User checkLogin(String username, String password);-->
<select id="checkLogin" resultType="User">
select * from t_user where username = #{username} and password = #{password}
</select>
使用该方法会出现错误:
org.apache.ibatis.exceptions.PersistenceException:
Error querying database. Cause: org.apache.ibatis.binding.BindingException: Parameter ‘username’ not found. Available parameters are [arg1, arg0, param1, param2]
Cause: org.apache.ibatis.binding.BindingException: Parameter ‘username’ not found. Available parameters are [arg1, arg0, param1, param2]
Mybatis检测到我们的参数有多个的时候,它会自动把参数放到Map集合中
如果想要获取正确的参数,需要以下方法:
- 测试代码
@Test
public void checkLoginTest(){
SqlSession sqlSession = getSqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.checkLogin("fulin", "513790");
System.out.println(user);
}
- 测试结果
3、手动把参数放在map集合中
如果mapper接口中的方法的参数有多个的时候,我们可以手动把参数放在map集合中存储
- mapper接口方法
/**
* 测试登录,我们将参数手动放在map集合中
*/
User checkLoginByMap(Map<String, Object> map);
- mapper.xml中实现(类似dao的接口实现类的功能)
<!--User checkLoginByMap(Map<String, Object> map);-->
<select id="checkLoginByMap" resultType="User">
select * from t_user where username = #{username} and password = #{password}
</select>
注意:#{}中的参数必须和我们传递的map集合中的键一样,如果不一样接收不了,读出来的值为null,传递的map集合我们看测试里面的代码。
- 测试代码
@Test
public void checkLoginByMapTest(){
SqlSession sqlSession = getSqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> map = new HashMap<>();
map.put("username", "fulin");
map.put("password", "513790");
User user = mapper.checkLoginByMap(map);
System.out.println(user);
}
- 测试结果
- 总结
第三种方式:我们可以自定义key来访问,技巧:mapper接口的方法参数是map集合,我们在测试程序的时候,存储数据的时候,可以指定存储的key的值
还有一种获取参数值的形式就是,前端通过表单把完整数据传给后端,我们可以获取数据,并且把数据存到对应的实体类中, 这个时候,当我们调用service方法,那么传输过来的数据应该就是实体类对象。实体类对象是属性名=值这样来存储数据,map集合是key=value的形式来存储数据,这两种方式存储数据其实是很像的
4、mapper接口方法的参数是实体类型的参数
- mapper接口方法
/**
* 添加功能
*/
void insertUser(User user);
- mapper.xml中实现(类似dao的接口实现类的功能)
<!--void insertUser(User user);-->
<insert id="insertUser">
insert into t_user values(#{id}, #{username}, #{password}, #{age}, #{sex}, #{email})
</insert>
- 测试代码
@Test
public void insertUser(){
SqlSession sqlSession = getSqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User(null, "库里", "123456", 35, "男", "kuli@qq.com");
mapper.insertUser(user);
}
- 测试结果
我们在设置数据库表的时候,字段id设置成自增的,如果我们这里sql语句,id的位置写null,那么最后显示的结果id是会自增的如果sql语句中我们id的位置写的是#{id},那么插入的id就是我们获取的参数的值,id就不会是自增的值
总结:
通过#{}或${}以属性的方式来访问属性值,真正的属性是get和set方法中的get和set去掉,剩余的部分首字母变成小写的结果就是属性名。再次强调${}的单引号问题,需要注意。如果我们#{}括号里面的值不是属性名那么就会报错
5、通过@Param注解命名参数(比较常用)
使用@Param注解来命名参数,此时Mybatis会把这些参数放在一个map集合中,以两种方式来进行存储
① 以@Param注解的值为键,参数为值
② 以param1,param2…作为键,以参数为值
我们只需要通过#{}和${} 以键的形式来访问值就可以了
- 测试
<!--username,@Param("password") String password);-->
<select id="checkLoginByParam" resultType="com.atguigu.mybatis.pojo.User">
select * from t_user where username=#{param1} and password= #{password};
</select>
注意点:这个时候,存储的key,value形式有两种,一种形式的key是我们职工时候通过注解来命名的参数的名字,还有一种就是以param1,param2……作为key,所以这两种形式都可以用来取数据,不可以用arg0,arg1的形式来获取数据,要和情况2区分开
二、总结
上面我们获取参数有五种情况,但是我们最常用的也就是两种,实体类对象和@Param注解的方式。通常我们只需要掌握这两种就行。--------- 经典白学
三、@Param源码分析
刚开始学习mybatis,很多还没有理解,先不要一头扎进源码中去,我们现在保证自己的mybatis使用熟练后,再开始慢慢探究源码。想要看源码解析的这里推荐一篇博文 MyBatis源码解读 - @Param注解,后续会再来学习的。