【零基础入门MyBatis系列】第九篇——参数处理

在这里插入图片描述

一、单个简单类型参数

🌔 1、简单类型参数都包括哪些?

  • byte short int long float double char
  • Byte Short Integer Long Float Double Character
  • String
  • java.util.Date
  • java.sql.Date

🌔 2、准备工作 【创建操作的表和相关pojo类】

(1)设计表 t_car
在这里插入图片描述
(2)填写两条简单的数据
在这里插入图片描述
(3)在 idea 中创建一个新模块 mybatis-007-param 【文件结构如下】
在这里插入图片描述
(3)SqlSessionUtil 工具类 【其余Student类创建等就不展开赘述了,可以在前一个章节copy】

package com.powernode.mybatis.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;

/**
 * @author Bonbons
 * @version 1.0
 */
public class SqlSessionUtil {
    private SqlSessionUtil(){}

    //定义一个SqlSession
    private static final SqlSessionFactory sqlSessionFactory;
    //在类加载的时候初始化SqlSessionFactory
    static {
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //定义一个全局的ThreadLocal,可以保证一个SqlSession对应一个线程
    private static ThreadLocal<SqlSession> local = new ThreadLocal<>();

    //通过一个公有的方法为外部提供会话的对象 >> 确保同一个线程操作的是同一个连接对象
    public static SqlSession openSession(){
        //我们用local去获取会话
        SqlSession sqlSession = local.get();
        //如果当前没有开启的会话就去创建一个,如果get到了就用这个[确保我们操作的是同一个连接对象]
        if(sqlSession == null){
            sqlSession = sqlSessionFactory.openSession();
            //将SqlSession对象绑定到当前线程上
            local.set(sqlSession);
        }
        return sqlSession;
    }

    /**
     * 关闭SqlSession对象并从当前线程中解绑
     * @param sqlSession 会话对象
     */
    public static void close(SqlSession sqlSession){
        if(sqlSession != null){
            sqlSession.close();
            local.remove();
        }
    }
}

🌔 3、对于传递的参数为单个简单类型时,我们列举了几个案例

  • 根据 id、name、birth、sex 查询学生信息
  • 接口如下:
public interface StudentMapper {
    /**
     * 接口中的参数为单个简单类型时
     * 我们根据id、name、birth、sex查询
     */
    List<Student> selectById(Long id);
    List<Student> selectByName(String name);
    List<Student> selectByBrith(Date brith);
    List<Student> selectBySex(Character sex);
}
  • Mapper映射文件如下:
<?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.powernode.mybatis.mapper.StudentMapper">
<select id="selectById" resultType="Student">
        select * from t_student where id = #{id}
    </select>
    <!--使用了类型内置别名-->
    <select id="selectByName" resultType="Student" parameterType="string">
        select * from t_student where name = #{name}
    </select>
    <select id="selectByBrith" resultType="Student">
        select * from t_student where birth = #{birth}
    </select>

    <select id="selectBySex" resultType="Student">
        select * from t_student where sex = #{sex}
    </select>
</mapper>
  • 测试程序如下:
public class StudentMapperTest {
    @Test
    public void testSelectById(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        // 根据id查的数据只能有一条,所以不应该用List集合来接收查询结果
        List<Student> students = mapper.selectById(1L);
        students.stream().forEach(student -> System.out.println(student));
        sqlSession.close();
    }
    @Test
    public void testSelectByName(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> students = mapper.selectByName("张三");
        students.stream().forEach(student -> System.out.println(student));
        sqlSession.close();
    }
    @Test
    public void testSelectByBirth() throws ParseException {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date birth = sdf.parse("2022-11-01");
        List<Student> students = mapper.selectByBrith(birth);
        students.stream().forEach(student -> System.out.println(student));
        sqlSession.close();
    }
    @Test
    public void testSelectBySex() throws ParseException {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> students = mapper.selectBySex('女');
        students.stream().forEach(student -> System.out.println(student));
        sqlSession.close();
    }
}
  • 测试结果 >> 成功
  • 对于SQL语句可以指定 parameterType 的,如果不指定那么将有mybatis底层自动识别
  • 而且mybatis还内置了一些基础类的别名:

在这里插入图片描述
在这里插入图片描述


二、Map参数

1、Map 参数是什么意思?

  • 就是我们要在数据库表接口中的操作方法传递的参数 >> 是一个 Map 集合
  • 一般用于插入数据时候封装对象,集合的key就是传递参数占位符里面的内容

2、通过一个案例来说明如何使用?【只给出接口中的方法、mapper中的SQL语句、测试片段其余部分与上述案例相同】

(1)接口中的方法

/**
	* 通过map参数保存学生信息,单个参数非简单类型
	* @param map map对象
	* @return 影响数据条数
*/
int insertStudentByMap(Map<String, Object> map);

(2)mapper 中的 SQL 语句

<insert id="insertStudentByMap">
	<!--占位符中传递的是map的key-->
	insert into t_student (id, name, age, sex, birth, height)
	values (null, #{name}, #{age}, #{sex}, #{birth}, #{height})
</insert>

(3)测试片段

	@Test
    public void testInsertStudentByMap(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Map<String, Object> map = new HashMap<>();
        // 一个map对象代表一个学生信息, map 的key对应表中字段--value对应属性值
        map.put("name", "李元霸");
        map.put("age", 20);
        map.put("height", 1.81);
        map.put("sex", '男');
        map.put("birth", new Date());

        int count = mapper.insertStudentByMap(map);

        sqlSession.commit();
        sqlSession.close();
    }

(4)运行结果如下:
在这里插入图片描述

三、实体类参数

1、这是我们比较常用的方式,用一个普通java类来封装我们的数据库表中的字段

2、我们现在要通过实体类参数插入一条数据
(1)创建Student类

package com.powernode.mybatis.pojo;

import java.util.Date;

/**
 * @author Bonbons
 * @version 1.0
 */
public class Student {
    private Long id;
    private String name;
    private Integer age;
    private Double height;
    private Date birth;
    private Character sex;

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                ", brith=" + birth +
                ", sex=" + sex +
                '}';
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Double getHeight() {
        return height;
    }

    public void setHeight(Double height) {
        this.height = height;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date brith) {
        this.birth = birth;
    }

    public Character getSex() {
        return sex;
    }

    public void setSex(Character sex) {
        this.sex = sex;
    }

    public Student() {
    }

    public Student(Long id, String name, Integer age, Double height, Date brith, Character sex) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.height = height;
        this.birth = brith;
        this.sex = sex;
    }
}

(2)接口中的方法

/**
* 通过POJO类对象传递参数信息
* @param student 学生类的对象
* @return 影响数据条数
*/
int insertStudentByPOJO(Student student);

(3)映射文件中的 SQL 语句

  • 此处占位符内的字段是获取对应属性值的 get方法去掉get和将首字母转化为小写后的参数
<insert id="insertStudentByPOJO" parameterType="student">
        insert into t_student (id, name, age, sex, birth, height)
        values (null, #{name}, #{age}, #{sex}, #{birth}, #{height})
</insert>

(4)相应的测试片段

	@Test
    public void testInsertStudentByPOJO(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Student student = new Student(null, "李白", 30, 1.82, new Date(), '女');

        int count = mapper.insertStudentByPOJO(student);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }

(5)测试结果如下
在这里插入图片描述


四、多参数

🌔 1、以上的案例都是参数只有一个时,那么如果我们的方法需要传递多个参数应该如何处理呢?

  • mybatis 为我们提供了两种默认的参数传递机制
  • 假如传递的为两个参数,此处以根据姓名性别查询学生数据
  • 那么在接口中的方法应该是这样的:
/**
* 根据名字和性别查询学生信息
* @param name 名字
* @param sex 性别
* @return 返回查询结果
*/
List<Student> selectByNameAndSex(String name, Character sex);
  • 重点来了,在Mapper的映射文件的SQL语句中,我们应该怎么写呢?【占位符中应该填什么参数】
<select id="selectByNameAndSex" resultType="student">
	select * from t_student where name = #{} and sex = #{}
</select>

🌔 2、mybatis为我们提供了两种默认的参数?

  • 第一种:使用参数 argNN对应我们第 i - 1 个参数】
  • 第二种:使用参数paramNN对应我们的第i个参数】

所以上面的SQL语句可以写成一下两种形式:【此处是为了方便看将两条ID相同的SQL语句写到一块去了】

<select id="selectByNameAndSex" resultType="student">
	select * from t_student where name = #{arg0} and sex = #{arg1}
</select>
<select id="selectByNameAndSex" resultType="student">
	select * from t_student where name = #{param1} and sex = #{param2}
</select>
  • 在测试文件中,我们正常调用即可
public void testSelectByNameAndSex(){
	SqlSession sqlSession = SqlSessionUtil.openSession();
	StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
	List<Student> students = mapper.selectByNameAndSex("李白", '女');
	students.stream().forEach(student -> System.out.println(student));
	sqlSession.commit();
	sqlSession.close();
}

🌔 3、我们还可以采用 @Param 注解的方式指定使用什么参数名

  • 在我们制定接口方法的时候,我们可以通过 @Param 注解指明使用什么参数名 【可以参考下面的方法】
/**
* 通过注解来为多个参数指明参数名,底层实现不再使用默认的arg、param了
* map.put("name", name)
* @param name
* @param sex
* @return
*/
List<Student> selectByNameAndSex2(@Param("name") String name, @Param("sex") Character sex);
  • 就是在参数类型前面添加 @Param(参数名)
  • 在我们写SQL语句的时候就可以使用我们制定的参数名了
<select id="selectByNameAndSex2" resultType="student">
	select * from t_student where name = #{name} and sex = #{sex}
</select>
  • 此时仍然可以使用 param1、param2 … 作为参数名传递参数,但是不能使用 arg0、arg1、… 的方式了

  • 测试方法中的代码块不变:

public void testSelectByNameAndSex2(){
	SqlSession sqlSession = SqlSessionUtil.openSession();
	StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
	List<Student> students = mapper.selectByNameAndSex2("李白", '女');
	students.stream().forEach(student -> System.out.println(student));
	sqlSession.commit();
	sqlSession.close();
}

🌔 4、可以根据一下内容简单了解一下Param注解的原理:
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bow.贾斯汀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值