Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心。
MyBatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo的属性名称。传递pojo对象之前也已讲过,这里同样只给出案例:
开发中通过pojo传递查询条件,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件,这时可以使用包装对象传递输入参数。即一个pojo类的属性是另一个pojo类对象。
例如,新建vo如下:
public class QueryVo {
private String query;
private User user;
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
在UserMapper接口中定义方法:
/**
* 根据QueryVo提供的数据进行查询
* @param vo
* @return
*/
User getUserByQueryVo(QueryVo vo);
接下来我们就要在UserMapper.xml映射文件中编写sql语句了,即在UserMapper.xml映射文件中添加如下配置信息:
<select id="getUserByQueryVo" parameterType="com.oak.po.QueryVo">
select * from `user` where id=#{user.id} and name=#{user.name}
select>
例如:查看user表中的记录总数,首先在UserMapper接口中定义方法:
/**
* 得到总记录数
* @return
*/
Integer count();
在UserMapper.xml中配置:
<select id="count" resultType="int">
select count(id) from `user`
select>
输出简单类型必须查询出来的结果集只有一条记录,最终将第一个字段的值转换为输出类型。
输出pojo列表,我之前同样已讲过,这里只给出案例:
我们只要返回值类型定义为返回集合中一个元素的类型即可(集合的泛型)。
如果查找的字段名与返回值属性名不一致则无法完成映射!所以要保证select字段名与返回值类型属性一致!也就是返回的结果的列名和pojo中的属性要一致才可以自动映射
我们重新定义一个类型为角色role,每一个角色对应一个用户,首先在数据库中创建role表
CREATE TABLE `NewTable` (
`role_id` int(4) NOT NULL AUTO_INCREMENT ,
`role_name` varchar(7) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`user_id` int(4) NOT NULL ,
PRIMARY KEY (`role_id`)
)ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci;
在po包中新建Role:
public class Role {
private Integer roleId;
private String roleName;
private Integer userId;
//方法略
}
在UserMapper接口中定义方法:
/**
* 根据user_id查找role信息
* @param userId
* @return
*/
Role findRoleByUserId(int userId);
在UserMapper.xml中定义sql映射:
<select id="findRoleByUserId" parameterType="int"
resultType="com.oak.po.Role">
select * from `role` where user_id=#{id}
select>
注意:此处查找的是select * 也就是查找的是role表中的字段名role_id,role_name和user_id
测试:
@Test
public void testFindRoleByUserId(){
//第四步 得到sqlSession,与Spring整合后省略
SqlSession sqlSession=sqlSessionFactory.openSession();
//获得代理对象(与Spring整合后只需要通过Spring容器拿到UserMapper接口的代理对象就行了)
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
Role role=userMapper.findRoleByUserId(2);
System.out.println(role);
sqlSession.close();
}
查看结果:
你会发现查询有一条结果,但是封装到返回对象中时失败了。
所有这里一定要注意:返回的结果的列名和pojo中的属性要一致才可以自动映射。
这里我们可以使用别名的方式,把xml中的sql修改为:
<select id="findRoleByUserId" parameterType="int"
resultType="com.oak.po.Role">
select role_id roleId,role_name roleName,user_id userId from `role` where user_id=#{id}
select>
这种方式比较简单粗暴,其实要达到我们所预期的效果,还有另一种方式,那就是使用resultMap这个属性
resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。
resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
我们修改映射文件中的sql,不使用取别名的方式,把resultType替换为resultMap:
<select id="findRoleByUserId" parameterType="int" resultMap="role_list_map">
select role_id,role_name,user_id from `role` where user_id=#{id}
select>
然后定义resultMap,由于映射文件中sql查询列和Role属性不一致,因此需要定义resultMap:role_list_map将sql查询列和Role类属性对应起来:
<resultMap type="com.oak.po.Role" id="role_list_map">
<id property="roleId" column="role_id" />
<result property="roleName" column="role_name" />
<result property="userId" column="user_id" />
resultMap>
type:指resultMap要映射成的数据类型(返回结果映射的pojo,可以使用别名)。
< id />:此属性表示查询结果集的唯一标识,非常重要。如果是多个字段为复合唯一约束则定义多个< id />(复合主键时多个)。
< result />:普通列使用result标签映射。
property:表示POJO类的属性。
column:表示sql查询出来的字段名(列名)。
column和property放在一块儿表示将sql查询出来的字段映射到指定的pojo类属性上。
可以直接测试