前言
在sql语句中一些查询条件是需要用户自定义输入的,例如登陆时要求用户输入密码和用户名。这些参数通过前端传递到java函数的形参中后,Mybatis会将这些参数和mapper中的sql语句进行拼接。下面,一起看看Mybatis中传入参数问题。
1、Mapper文件的parameterType属性
parameter用来指定传入到mapper文件中sql语句的数据类型,可以是类型的全限定类名,也可以是别名。使用方式如下:
<select id="selectById" parameterType="integer">
select id,name,email,age from student where id=#{studentId}
</select>
parameterType中支持的常用别名和映射的类型
别名 | 映射 类型 |
_byte | byte |
_int | int |
_long | long |
_double | double |
int | Integer |
double | Double |
boolean | Boolean |
date | Date |
map | Map/HashMap |
2、一个简单参数的传入
接口中方法参数只有一个,但是要求必须是java的基本类型和String。此时mapper中占位符里面填写任意字符都可以接收到这个传入的参数值。如下:
接口方法
Student selectByID(Ineyger id);
mapper映射文件,注意这里的占位符和接口方法中形参名称不需要一致
<select id="selectById" parameterType="integer" resultType="student">
select id,name,email,age from student where id=#{studentId}
</select>
测试方法
@Test
public void testSelectById(){
//1.获取SqlSession
SqlSession session = MyBatisUtil.getSqlSession();
//2.获取dao的代理
StudentDao dao = session.getMapper(StudentDao.class);
Student student = dao.selectById(1005);
System.out.println("student = " + student);
//3.关闭SqlSession对象
session.close();
}
3、多个简单参数的传入
当sql中需要传递的参数两个或者两个以上时,可以在接口方法的参数前使用@param注解添加别名,然后mapper文件中使用注解的别名即可获取到传入的参数。
接口方法:
使用@Param命名参数, 注解是mybatis提供的
位置:在形参定义的前面
属性:value 自定义的参数名称
List<Student> selectByNameOrAge(@Param("myname") String name,
@Param("myage") Integer age);
mapper文件,使用#{命名的参数}, 这里就是 #{myage} #{myname}
<select id="selectByNameOrAge" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student where name=#{myname} or age=#{myage}
</select>
测试方法
@Test
public void testSelectByNameOrAge(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Student> students = dao.selectByNameOrAge("李四", 26);
students.forEach( stu-> System.out.println("stu="+stu));
sqlSession.close();
}
4、多个参数传递的第二种方法,使用对象
上述@param多个参数的传递有一个缺点,就是当需要传递的参数比较多的时候,接口方法中就会显得特别臃肿。为此,Mybatis中支持使用对象传递多个参数,对象的属性名称就是sql中需要传递的参数。
dao接口方法, 一个java对象作为参数( 对象有属性, 每个属性有set,get方法)
List<Student> selectByObject(Student student);
mapper文件中
简单的语法: #{属性名} , mybatis调用此属性的getXXX()方法获取属性值
<select id="selectByObject" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student where name=#{name} or age=#{age}
</select>
测试方法
@Test
public void testSelectBObject(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setName("李思思");
student.setAge(22);
student.setEmail("小乔");
List<Student> students = dao.selectByObject(student);
students.forEach( stu-> System.out.println("stu="+stu));
sqlSession.close();
}
多个参数的传递除了上述的利用@param注解和使用对象以外,还可以使用按位置和Map集合的方式传递,这里不做详细介绍,想了解的可以点击这里。
5、#和$两者的区别
#:占位符
告诉mybatis使用实际的参数值代替。并使用PrepareStatement对象执行sql语句, #{…}代替sql语句的“?”。这样做更安全,更迅速,通常也是首选做法。
演示:
mapper文件
<select id="selectById" parameterType="integer" resultType="student">
select id,name,email,age from student where id=#{studentId}
</select>
Mybatis执行
String sql="select id,name,email,age from student where id=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1,1005);
解释
1)where id=? 就是where id=#{studentId}
2)ps.setInt(1,1005) , 1005会替换掉 #{studentId}
$:占位符
告诉mybatis使用$包含的“字符串”替换所在位置,这里和#使用使用实际的参数值代替是不一样的。Statement把sql语句和${}的内容连接起来。主要用在替换表名,列名,不同列排序等操作。
演示:
接口方法
List<Student> queryStudent(@Param("studentName") String name);
mapper文件
<select id="queryStudent" resultType="com.bjpowernode.domain.Student">
select * from student where name=${studentName}
</select>
测试方法
@Test
public void testQueryStudent(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Student> students = dao.queryStudent("'李四' or id > 0 ");
students.forEach( stu-> System.out.println("stu="+stu));
sqlSession.close();
}
简单的讲,两种占位符从数据库操作对象上看,就是使用预编译对象和编译对象的区别。