0%

Mybatis参数处理

  • Mybatis参数处理
    • 单个简单类型参数
    • Map参数
    • 实体类参数
    • 多参数
    • @Param注解(命名参数)

十、★★★Mybatis参数处理

10.1 ★单个简单类型参数

  • 简单类型包括:

    • byte short int long float double char
    • Byte Short Integer Long Float Double Character
    • String
    • java.util.Date
    • java.sql.Date
  • 需求:根据 id 查、根据 name 查、根据 birth 查、根据 sex 查。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package com.f.mybatis.mapper;

    import com.f.mybatis.pojo.Student;

    import java.util.Date;
    import java.util.List;

    /**
    * @author fzy
    * @date 2024/1/9 22:14
    */
    public interface StudentMapper {
    /**
    * 当接口中的方法的参数只有一个,并且参数的数据类型都是简单类型
    * 根据 `id` 查、根据 `name` 查、根据 `birth` 查、根据 `sex` 查
    */
    List<Student> selectById(Long id);

    List<Student> selectByName(String name);

    List<Student> selectByBirth(Date birth);

    List<Student> selectBySex(Character sex);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.f.mybatis.mapper.StudentMapper">
    <select id="selectById" resultType="Student">
    SELECT * FROM t_student WHERE id = #{id}
    </select>
    <select id="selectByName" resultType="Student">
    SELECT * FROM t_student WHERE name = #{name}
    </select>
    <select id="selectByBirth" resultType="Student">
    SELECT * FROM t_student WHERE birth = #{birth}
    </select>
    <select id="selectBySex" resultType="Student">
    SELECT * FROM t_student WHERE sex = #{sex}
    </select>
    </mapper>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    package com.f.mybatis.test;

    import com.f.mybatis.mapper.StudentMapper;
    import com.f.mybatis.pojo.Student;
    import com.f.mybatis.utils.SqlSessionUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;

    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;

    /**
    * @author fzy
    * @date 2024/1/9 22:18
    */
    public class StudentMapperTest {
    @Test
    public void testSelectById() {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    List<Student> students = mapper.selectById(1L);
    students.forEach(student -> {
    System.out.println(student);
    });
    SqlSessionUtil.close(sqlSession);
    }

    @Test
    public void testSelectByName() {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    List<Student> students = mapper.selectByName("李四");
    students.forEach(student -> {
    System.out.println(student);
    });
    SqlSessionUtil.close(sqlSession);
    }

    @Test
    public void testSelectByBirth() throws Exception {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    Date birth = new SimpleDateFormat("yyyy-MM-dd").parse("1980-10-01");
    List<Student> students = mapper.selectByBirth(birth);
    students.forEach(student -> {
    System.out.println(student);
    });
    SqlSessionUtil.close(sqlSession);
    }

    @Test
    public void testSelectBySex() {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    List<Student> students = mapper.selectBySex('男');
    students.forEach(student -> {
    System.out.println(student);
    });
    SqlSessionUtil.close(sqlSession);
    }
    }
    • 其实 SQL 映射文件中的配置比较完整的写法是:

      1
      2
      3
      <select id="selectByName" resultType="Student" parameterType="java.lang.String">
      select * from t_student where name = #{name, javaType=String, jdbcType=VARCHAR}
      </select>

      其中 sql 语句中的 javaTypejdbcType,以及 select 标签中的 parameterType 属性,都是用来帮助 mybatis 进行类型确定的。不过这些配置多数是可以省略的,因为 mybatis 它有强大的自动类型推断机制。

  • 注意:三步走:

    • 第一步:写 Mapper 接口中的方法。
    • 第二步:写 SqlMapper.xml 配置文件中的 SQL 语句。
    • 第三步:写测试类对 SQL 语句进行测试。

10.2 Map参数

  • 需求:根据 nameage 查询。

    还是三步走:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package com.f.mybatis.mapper;

    import com.f.mybatis.pojo.Student;

    import java.util.Date;
    import java.util.List;
    import java.util.Map;

    /**
    * @author fzy
    * @date 2024/1/9 22:14
    */
    public interface StudentMapper {
    /**
    * 当接口中的方法的参数只有一个,并且参数的类型是Map
    */
    List<Student> selectByNameAndSex(Map<String, Object> paramMap);
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.f.mybatis.mapper.StudentMapper">
    <select id="selectByNameAndSex" resultType="Student">
    SELECT * FROM t_student WHERE name = #{name} AND sex = #{sex}
    </select>
    </mapper>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @Test
    public void testSelectByNameAndSex() {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    Map<String, Object> paramMap = new HashMap<>();
    paramMap.put("name", "张三");
    paramMap.put("sex", '男');
    List<Student> students = mapper.selectByNameAndSex(paramMap);
    students.forEach(student -> {
    System.out.println(student);
    });
    SqlSessionUtil.close(sqlSession);
    }

    这种方式是手动封装 Map 集合,将每个条件以 keyvalue 的形式存放到集合中。然后在使用的时候通过 #{map集合的key} 来取值。

10.3 ★实体类参数

  • 需求:插入一条 Student 数据。

    依然三步走:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package com.f.mybatis.mapper;

    import com.f.mybatis.pojo.Student;

    import java.util.Date;
    import java.util.List;
    import java.util.Map;

    /**
    * @author fzy
    * @date 2024/1/9 22:14
    */
    public interface StudentMapper {
    /**
    * 当接口中的方法的参数只有一个,并且参数的类型是实体类POJO
    */
    int insert(Student student);
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.f.mybatis.mapper.StudentMapper">
    <insert id="insert">
    INSERT INTO t_student (id, name, age, height, birth, sex)
    VALUES (#{id}, #{name}, #{age}, #{height}, #{birth}, #{sex})
    </insert>
    </mapper>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    package com.f.mybatis.test;

    import com.f.mybatis.mapper.StudentMapper;
    import com.f.mybatis.pojo.Student;
    import com.f.mybatis.utils.SqlSessionUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;

    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;

    /**
    * @author fzy
    * @date 2024/1/9 22:18
    */
    public class StudentMapperTest {
    @Test
    public void testInsert() {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    Student student = new Student();
    student.setName("李清");
    student.setAge(23);
    student.setHeight(1.78);
    // 创建Date对象时,年需减去1900,月从0开始
    student.setBirth(new Date(2010 - 1900, 9, 10, 0, 0, 0));
    student.setSex('女');
    int count = mapper.insert(student);
    sqlSession.commit();
    SqlSessionUtil.close(sqlSession);
    }
    }

    这里需要注意的是:#{} 里面写的是属性名字。这个属性名为:set/get 方法名去掉 set/get 之后的名字。

10.4 多参数

  • 需求:通过 nameage 查询,并且传入参数为多参数。

    三步走:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    package com.f.mybatis.mapper;

    import com.f.mybatis.pojo.Student;

    import java.util.Date;
    import java.util.List;
    import java.util.Map;

    /**
    * @author fzy
    * @date 2024/1/9 22:14
    */
    public interface StudentMapper {
    /**
    * 接口中的方法的参数有多个
    * 这里根据name和age查询Student的信息
    * 如果是多个参数的话,mybatis框架底层是怎么做的呢
    * mybatis框架会自动创建一个Map集合,并且Map集合是以这种方式存储参数的:
    * map.put("arg0", name); map.put("param1", name);
    * map.put("arg1", age); map.put("param2", age);
    *
    * @param name
    * @param age
    * @return
    */
    List<Student> selectByNameAndAge(String name, Integer age);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.f.mybatis.mapper.StudentMapper">
    <select id="selectByNameAndAge" resultType="Student">
    # 传值时要使用 arg0、arg1 或者 param1、param2
    SELECT * FROM t_student WHERE name = #{arg0} AND age = #{arg1}
    </select>
    </mapper>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    package com.f.mybatis.test;

    import com.f.mybatis.mapper.StudentMapper;
    import com.f.mybatis.pojo.Student;
    import com.f.mybatis.utils.SqlSessionUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;

    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;

    /**
    * @author fzy
    * @date 2024/1/9 22:18
    */
    public class StudentMapperTest {
    @Test
    public void testSelectByNameAndAge() {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    List<Student> students = mapper.selectByNameAndAge("张三", 20);
    students.forEach(student -> {
    System.out.println(student);
    });
    SqlSessionUtil.close(sqlSession);
    }
    }

    当传入多参数时,实际上在 mybatis 底层会创建一个 map 集合,以 arg0param1 为第一个参数的 key,以参数值为 value,类似以下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    Map<String,Object> map = new HashMap<>();
    map.put("arg0", name);
    map.put("arg1", sex);
    map.put("param1", name);
    map.put("param2", sex);

    // 所以可以这样取值:#{arg0} #{arg1} #{param1} #{param2}
    // 其本质就是#{map集合的key}

    其本质就是 #{map集合的key},只不过这里的 key 变成了 arg0/param1arg1/param2……

  • 注意:使用 mybatis3.4.2 之前的版本时:在 SqlMapper.xml 中要用 #{0}#{1} 这种形式。

10.5 ★@Param注解(命名参数)

  • 可以不用 10.4 节中的 arg0arg1param1param2吗?这个 map 集合的 key 我们自定义可以吗?

    当然可以,使用 @Param 注解即可,这样可以增强可读性。

  • 需求:通过 nameage 查询,并且传入参数为多参数,并且使用 @Param 注解。

    三步走:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    package com.f.mybatis.mapper;

    import com.f.mybatis.pojo.Student;
    import org.apache.ibatis.annotations.Param;

    import java.util.Date;
    import java.util.List;
    import java.util.Map;

    /**
    * @author fzy
    * @date 2024/1/9 22:14
    */
    public interface StudentMapper {
    /**
    * Param注解
    * mybatis框架底层实现原理由
    * map.put("arg0", name);
    * map.put("arg1", age);
    * 转变为 map.put("name", name);
    * map.put("age", age);
    *
    * @param name
    * @param age
    * @return
    */
    List<Student> selectByNameAndAgeUsingParamAnnotation(@Param("name") String name, @Param("age") Integer age);
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.f.mybatis.mapper.StudentMapper">
    <select id="selectByNameAndAgeUsingParamAnnotation" resultType="Student">
    # 使用了@Param注解之后,arg0、arg1失效了,但是param1、param2还能用
    SELECT * FROM t_student WHERE name = #{name} AND age = #{age}
    </select>
    </mapper>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Test
    public void testSelectByNameAndAgeUsingParamAnnotation() {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    List<Student> students = mapper.selectByNameAndAge("张三", 20);
    students.forEach(student -> {
    System.out.println(student);
    });
    SqlSessionUtil.close(sqlSession);
    }

    其实,@Param("这里填写的就是map集合的key")

---------------The End---------------