【SSM】07-Mybatis深入理解参数

前言

在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();

    }

简单的讲,两种占位符从数据库操作对象上看,就是使用预编译对象和编译对象的区别。

上一篇:基于SSM水果商城,前端jsp,数据库MySQL


下一篇:Python requests发送multipart/form-data请求