在实际的开发我们对数据库进行crud操作时,需要传递的参数往往不是一个,并且传递的参数类型也不仅仅是一些基本数据类型。因此我们讲述一下Mapper接口中传递参数的集中形式。
文章目录
- 一、传递一个参数
- 二、传递多个参数
- 1.使用参数下标
- 2.使用注解
- 三、传递一个对象
- 四、传递一个Map
- 五、传递一个Collection
- 总结
一、传递一个参数
传递一个参数就是Mapper接口中的方法只有一个普通类型的参数
接口:
public interface PersonMapper {
//根据员工编号获取员工信息和员工部门
public Person getPersonById(Integer id);
}
接口对应的映射文件
<mapper namespqce="com.offcn.mapper.PersonMapper">
<select id="getPersonById" resultType="Person">
select * from person where id=#{id}
</select>
<mapper>
测试类:
@Test
public void getPersonByTd() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Person person = mapper.getPersonById(3);
System.out.println(person);
MyBatisUtils.closeSqlSession(sqlSession);
}
生成的sql语句
select * from person where id= ?
当传递一个参数时,#{}就是一个占位符
从生成的sql语句我们可以看出其实就是PrepareStatement中的占位符?需要注意一点就是我们传递的一个参数,它的类型一定是基本数据类型或者对应的引用数据类型。
二、传递多个参数
底层的原理:
MyBatis一次传递多个参数时,底层是怎么实现的呢?其实它会自动的将参数封装进一个map集合中,而map中的key值就是参数的参数名,java会通过反射技术获取参数名,但是要注意的是此时获取的参数名不是形参的参数名,它是通过arg+参数下标来一一对应我们接口中方法的参数名。
看一下提示信息:
这里我们加入传递的是两个参数,那么第一个参数对应的就是arg0第二个参数对应的就是arg1在实际的编译中它会自动找到对应的真实的参数名。
1.使用参数下标
1.接口的编写(以两个参数为例)
public interface PersonMapper{
//定义一个方法传递两个参数
public List<Person> getPersonsBymany(Integer id,Integer age);
}
2.对应的xml映射文件(查询id大于?,并年龄大于?的Person)
<mapper namespace="com.offcn.mapper.PersonMapper">
<select id="getPersonsByMany" resultType="Person">
//arg+参数下标的形式。参数下标从零开始
select * from person where id > #{arg0} and age> #{arg1}
</select>
</mapper>
根据上述提示信息发现后边还有两个参数param1,param2
其中的param1…就是为了解决不同编码问题带来的参数变化的问题我们可以使用param1和param2来依次对应的方法中的参数注意这里的下标是从1开始的,也就是param1……n(来依次指代传递的参数)
上边的映射文件也可以这样写:
<mapper namespace="com.offcn.mapper.PersonMapper">
<select id="getPersonsByMany" resultType="Person">
//arg+参数下标的形式。参数下标从零开始
select * from person where id > #{param1} and age> #{param2}
</select>
</mapper>
3.测试类
@Test
public void getPersonsByMany(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
List<Person> personList = mapper.getPersonsByMany(2, 23);
for (Person person : personList) {
System.out.println(person);
}
MyBatisUtils.closeSqlSession(sqlSession);
}
}
我们很少使用这用方式,因为这种方式对参数的顺序依赖性非常强,一旦顺序对应不错,gg
2.使用注解
我们在使用上述方法的时候参数顺序依赖性非常的强因此很容易造成错误,因此我们使用@param指定参数名
1.Mapper接口
public interface PersonMapper{
//使用注解的形式来指定参数名
public List<Person> getPersonsByMany(@Param("id") Integer id, @Param("age") Integer age);
}
2.映射文件
<mapper namespace="com.offcn.mapper.PersonMapper">
<select id="getPersonsByMany" resultType="Person">
select * from person where id > #{id} and age> #{age}
</select>
</mapper>
#{参数名} 中的参数名要和@param(“参数名”)对应
测试类完全一致,不在书写
三、传递一个对象
上边的多参数进行传递是我们发现一个问题,如果传递的参数是10个或者更多那我们就需要在参数列表中写很多,这样书写十分的不方便,并且容易出错。那我们可以怎样进行传递呢?我们可以传递一个javabean对象
1.Mapper接口
public interface PersonMapper{
//传递一个javabean对象
public List<Person> getPersonsByMany(Person person);
}
2.对应的映射文件
<mapper namespace="com.offcn.mapper.PersonMapper">
<select id="getPersonsByMany" resultType="Person">
select * from person where id > #{id} and age> #{age}
</select>
</mapper>
注意:#{参数名}:{}中的参数名一定是传递进来对象的属性
3.测试类:
@Test
public void getPersonsByMany(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Person p = new Person();
p.setId(2);
p.setAge(23);
List<Person> personList = mapper.getPersonsByMany(p);
for (Person person : personList) {
System.out.println(person);
}
MyBatisUtils.closeSqlSession(sqlSession);
}
}
传递一个对象时我们可以明确知道要传递的参数,看起来比较清晰。使用较为方便,相比较传递一个Map要实用
四、传递一个Map
我们在传递一个对象的时候会发现一个问题,如果我们传递的参数较少,在使用对象进行传递的时候我们依旧要创建这个对象,而创建对象是需要在内存中开辟空间的,这样的话就比较耗费内存。因此我们可以使用map集合进行传递。但是Map集合进行传递时我们不知道参数的类型以及要传递的参数,因此使用起来一定要注意。
传递Map集合完成和上述一样的功能:
1.Mapper接口
public interface PersonMapper{
//传递一个Map集合来获取Person
public List<Person> getPersonByMap(Map<String,Object> map);
}
2.对应的映射文件
<mapper namespace="com.offcn.mapper.PersonMapper">
<select id="getPersonByMap" resultType="Person">
select * from person where id > #{id} and age> #{age}
</select>
</mapper>
注意:当传递一个Map时#{参数}中的参数要是Map集合中的key值:参数=>key
3.测试类
@Test
public void getPersonByMap(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Map<String,Object> map = new HashMap<>();
map.put("id",2);
map.put("age",23);
List<Person> personMap = mapper.getPersonByMap(map);
for (Person person : personMap) {
System.out.println(person);
}
MyBatisUtils.closeSqlSession(sqlSession);
}
Map集合在进行传递参数的时候,可以自定义传递的参数类型,比较灵活,并且节省内存空间。但是相比较传递一个javabean对象的话它就显的结构不是很清晰。建议还是使用javabean进行传参
五、传递一个Collection
当传递一个集合的时候MyBatis底层实际上还是会转换为一个Map集合,key值对应Collection中的下标,value对应参数的值。
1.Mapper接口
public interface PersonMapper{
//传递一个Collection
public List<Person> getPersonByList(List<Integer> list);
}
2.对应的映射文件
<mapper namespqce="com.offcn.mapper.PersonMapper">
<select id="getPersonByList" resultType="Person">
select * from person where id in (#{collection[0]},#{collection[1]},#{collection[2]})
</select>
</mapper>
3.测试类:
@Test
public void getPersonByList(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(4);
list.add(5);
List<Person> personMap = mapper.getPersonByList(list);
for (Person person : personMap) {
System.out.println(person);
}
MyBatisUtils.closeSqlSession(sqlSession);
}
}
传递一个集合的方式非常的不灵活,我们在实际的开发中也不会使用,后续文章我们介绍动态Sql。使用动态Sql会十分的灵活。
总结
本篇文章介绍了多参数进行传递的时候,我们应该如何进行传递和接收,这是最基本的东西。