MyBatis·基础篇(五) MyBatis映射配置文件参数的深入
1. parameterType 配置传入参数
SQL 语句传参时,使用标签的 parameterType 属性来设定。该属性的取值可以是基本类型,引用类型(例如:String 类型),还可以是实体类类型(POJO 类)。同时也可以使用实体类的包装类。
- 基本类型传参
- 引用类型传参
- 实体类类型传参
- 实体类的包装对象类型传参
本篇文章重点讲解 实体类的包装类类型传参
1.1 什么是实体类包装对象
开发中通过 pojo 传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。
通俗来讲包装类就是 Pojo 类中包含 pojo
1.2 案例演示:使用包装类传参
需求:根据用户名查询用户信息,查询条件放到 QueryVo 的 user 属性中
编写 QueryVO
/**
* @author: LzCc
* @blog: https://blog.youkuaiyun.com/qq_41744145
* @description: QueryVo,封装了查询用户信息的条件
*/
public class QueryVo implements Serializable {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
编写 Mapper 接口
/**
* @author: LzCc
* @blog: https://blog.youkuaiyun.com/qq_41744145
* @description: User持久层接口
*/
public interface UserMapper {
/**
* 根据 QueryVo 中的条件查询用户
* @param vo
* @return
*/
List<User> findByVo(QueryVo vo);
}
持久层接口的映射文件
<!-- 根据用户名称模糊查询,参数变成一个 QueryVo 对象了 -->
<select id="findByVo" resultType="top.lzchao.domain.User" parameterType="top.lzchao.domain.QueryVo">
select * from user where username like #{user.username};
</select>
使用包装对象参数时,用 包装类属性名.实体类属性名
测试包装类作为参数
@Test
public void testFindByQueryVo() {
QueryVo vo = new QueryVo();
User user = new User();
user.setUserName("%杰伦%");
vo.setUser(user);
List<User> users = userDao.findByVo(vo);
for(User u : users) {
System.out.println(u);
}
}
2. resultType 配置结果类型
resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型。我们在前面的 CRUD 案例中已经对此属性进行过应用了。
- 基本类型
- 实体类类型
如果使用的实体类中的属性名称必须和查询语句中的列名保持一致,否则无法实现封装
2.1 基本类型示例
编写 Mapper 接口
/**
* 查询总记录条数
* @return
*/
int findTotal();
编写映射配置文件
<!-- 查询总记录条数 -->
<select id="findTotal" resultType="int">
select count(*) from user;
</select>
2.1 实体类类型实例
编写 Mapper 接口
/**
* 查询所有用户
* @return
*/
List<User> findAll();
编写映射配置文件
<!-- 配置查询所有操作 -->
<select id="findAll" resultType="top.lzchao.domain.User">
select * from user
</select>
2.3 特殊情况:实体类中的属性名称和查询语句中的列名不一致
演示特殊情况:
修改实体类对象,使之与查询语句的列名不一致
private Integer userId; // id
private String userName; // username
private Date userBirthday; // birthday
private String userSex; // sex
private String userAddress; //address
再次运行测试类,调用查询所有的方法,结果除了名称 username 属性以外其他属性值都没能封装上,都为 null
原因:MySQL 在 Windows 系统中不区分大小写
解决特殊情况:
修改映射配置,使用别名查询
<!-- 配置查询所有操作 -->
<select id="findAll" resultType="top.lzchao.domain.User">
select id as userId, username as userName, birthday as userBirthday,
sex as userSex, address as userAddress from user
</select>
测试结果正常!
3. resultMap 配置结果类型
resultMap 标签可以建立查询的列名和实体类的属性名称不一致时建立对应关系。从而实现封装。
在 select 标签中使用 resultMap 属性指定引用即可。
3.1 在映射文件中定义 resultMap
<!--
建立 User 实体和数据库表的对应关系:
type 属性:指定实体类的全限定类名
id 属性:给定一个唯一标识,是给查询 select 标签引用用的。
-->
<resultMap type="top.lzchao.domain.User" id="userMap">
<id column="id" property="userId"/>
<result column="username" property="userName"/>
<result column="sex" property="userSex"/>
<result column="address" property="userAddress"/>
<result column="birthday" property="userBirthday"/>
</resultMap>
id 标签:用于指定主键字段
result 标签:用于指定非主键字段
column 属性:用于指定数据库列名
property 属性:用于指定实体类属性名称
3.2 修改映射配置文件
<!-- 配置查询所有操作 -->
<select id="findAll" resultMap="userMap">
select * from user
</select>
- resultType --> resultMap
- 实体类 --> 编写好的 resultMap 的 id
3.3 测试结果
所有值通过 resultMap 都成功映射封装到对象中去了
resultMap 也可以实现将查询结果映射为复杂类型的 pojo 对象,比如在查询结果映射对象中包括 pojo 和 list 实现一对一查询和一对多查询。