10 MyBatis参数
10.1 parameterType
- 简单数据类型
- POJO对象类型(JavaBean实体类)
- 就是普通的 Java 实体类,通常与数据库表结构一一对应
- 包含属性、getter/setter 方法,是数据的载体
- 例如 User 类对应 users 表,包含 id、name、age 等字段
package com.qcby.domain; import java.io.Serializable; import java.util.Date; import java.util.List; public class User implements Serializable { //可以不写,默认就是这个 private static final long serialVersionUID = 525400707336671154L; private Integer id; private String username; private Date birthday; private String sex; private String address; // 定义ids属性,用来存储所有的id private List<Integer> ids; public List<Integer> getIds() { return ids; } public void setIds(List<Integer> ids) { this.ids = ids; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + ", ids=" + ids + '}'; } }- POJO包装对象类型
- 是一个 "容器" 对象,里面可以包含多个 POJO 对象或其他数据类型
- 主要用于复杂查询场景,当需要传递多个不同类型的参数时使用
- 它本身不是直接对应数据库表的实体类,而是为了满足业务需求而创建的组合对象
package com.qcby.domain; import java.io.Serializable; public class QueryVo implements Serializable { // 自己属性 private String name; // user属性 private User user; // role属性 private Role role; public String getName() { return name; } public void setName(String name) { this.name = name; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Role getRole() { return role; } public void setRole(Role role) { this.role = role; } }// 测试包装类查询 public List<User> findByVo(QueryVo vo);<!--包装类测试查询--> <select id="findByVo" parameterType="com.qcby.domain.QueryVo" resultType="com.qcby.domain.User"> select * from user where username = #{user.username} </select>@Test public void testFindByVo(){ QueryVo vo = new QueryVo(); User user0 = new User(); user0.setUsername("熊大"); vo.setUser(user0); List<User> users = mapper.findByVo(vo); System.out.println(users); }10.2 resultType
- 返回简单数据类型
- 返回POJO数据类型
- 单独说 “POJO 类型” 时,泛指所有普通 Java 对象:既包括普通 POJO 实体类(与数据库表一一对应),也包括POJO 包装对象(组合多个对象或属性的业务类)。只要是 “普通 Java 对象”(有属性、getter/setter,无特殊继承或接口限制),都可以称为 POJO 类型。
- 例如,返回User对象类型。
- resultMap结果类型
- resultType可以指定pojo,将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。(具体规则,见6.2)
- 如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。(具体规则,见6.2)
- resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list的多对一查询和一对多查询。(具体见6)
<!--演示resultMap配置--> <select id="findUsers" resultMap="userMap"> select id _id,username _username,birthday _birthday,sex _sex,address _address from user </select> <!-- 配置resultMap,用来进行数据封装 id="唯一的名称,用来被引用的" type="进行封装数据的类型" --> <resultMap id="userMap" type="com.qcby.domain.User"> <!-- property="JavaBean中的属性" column="表中的字段" --> <result property="id" column="_id"/> <result property="username" column="_username" /> <result property="birthday" column="_birthday" /> <result property="sex" column="_sex" /> <result property="address" column="_address" /> </resultMap>public List<User> findUsers();@Test public void testFindUsers(){ List<User> users = mapper.findUsers(); System.out.println(users); }10.3 MyBatis 参数传递
MyBatis 对不同类型参数的处理机制不同。写sql语句是,有时候可以直接用参数名,有时候又必须用 @Param。
入参情况 | 描述 | SQL 占位符写法 | 示例 |
单个普通参数 | 方法只有一个参数,且为基本类型或 String 。 | #{任意名称} 或 #{param1} | findById(int id) → where id = #{id} |
多个普通参数 | 方法有多个参数,且为基本类型或 String 。 | 必须使用 @Param("别名") ,然后用 #{别名} | findByNameAndAge(@Param("name") String name, @Param("age") int age) → where username=#{name} and age=#{age} |
一个对象参数 | 方法只有一个参数,且为自定义实体类或 Map。 | #{对象的属性名} | findByUser(User user) → where username=#{username} and password=#{password} |
混合参数 | 方法参数包含对象和普通类型。 | 对象属性用 #{属性名} ,普通参数必须用 @Param | find(User u, @Param("roleId") int roleId) → where username=#{username} and role_id=#{roleId} |
集合 / 数组参数 | 参数是 List 、 Set 或数组,用于 IN 查询。 | 使用 #{list[0]} 或在 标签中用 #{item} | findByIds(List ids) → #{id} |
10.3.1 单个普通参数 (基本类型或 String)
当你的方法只有一个参数时,MyBatis 不会去关心这个参数的名字。你在 XML 或注解中可以用任何名字来接收它。
XML 示例:
<select id="findById" resultType="User" parameterType="int"> select * from user where id = #{id} -- 这里用 #{abc} 也可以 </select>10.3.2 多个普通参数
当方法有多个参数时,MyBatis 无法直接将它们与 SQL 中的占位符对应起来。此时,你必须使用 @Param 注解为每个参数指定一个别名。
XML 示例:
<select id="findByNameAndSex" resultType="User"> select * from user where username = #{username} and sex = #{sex} </select>对应的接口方法必须是:
List<User> findByNameAndSex(@Param("username") String username, @Param("sex") String sex);注意: 如果不使用 @Param,MyBatis 会抛出 Parameter '...' not found 的错误。你也可以使用默认的 #{param1}, #{param2}... 来访问,但这非常不直观,不推荐。
10.3.3 一个对象参数
当你的参数是一个 Java 对象时,MyBatis 会自动使用对象的 属性名 来匹配 SQL 中的占位符。
XML 示例:
<select id="findByUser1" resultType="com.lsl.entity.User" parameterType="com.lsl.entity.User"> select * from user where username = #{username} and password = #{password} </select>对应的接口方法:
List<User> findByUser1(User user);MyBatis 会调用 user.getUsername() 和 user.getPassword() 来获取值。
10.3.4 集合或数组参数
当需要进行 IN 查询时,通常会传入一个 List 或数组。这时需要使用 标签。
XML 示例:
<select id="findByIds" resultType="User"> select * from user <where> id in <foreach collection="list" item="id" open="(" separator="," close=")"> #{id} </foreach> </where> </select>对应的接口方法:
List<User> findByIds(List<Integer> ids);- 如果参数是 List,collection 属性默认值是 list。
- 如果参数是 Array,collection 属性默认值是 array。
- 为了代码清晰,强烈建议使用 @Param 自定义名称:
List<User> findByIds(@Param("idList") List<Integer> ids);然后 XML 中 collection="idList"。