输入映射parameterType:
有时候在查询的时候我们传入的不仅是用户的信息,可能还包含其他的一些信息,比如用户购买的商品等等,这时的输入参数就会包含多个类型,需要我们对输入的参数进行包装,同时返回的可能就不仅仅是单纯的用户表的一些信息,会包含其他的信息,这时就需要对用户类进行扩展。
下面从一个简单的示例进行入手,
我们需要通过用户的性别和姓氏来查询用户的信息。
首先需要建立一个用户的扩展类UserCustom继承用户类
public class UserCustom extends User{
}
然后需要建立一个包装类型性UserQueryVo对输入参数进行包装
public class UserQueryVo {
//这里包装所需要的查询条件
//用户查询条件
private UserCustom userCustom;
public UserCustom getUserCustom() {
return userCustom;
}
public void setUserCustom(UserCustom userCustom) {
this.userCustom = userCustom;
}
//可以包装其他的查询条件,订单、商品
}
在userMapper.xml写我们的查询语句。
<!-- 用户信息综合查询 -->
<select id="findUserList" parameterType="userQueryVo" resultType="userCustom">
select * from user where user.sex = #{userCustom.sex} and user.username like '%${userCustom.username}%'
</select>
这里的sex是userQueryVo的userCustom属性的sex属性,所以这样书写。
在UserMapper中新增一个接口。
/**
* @author:kevin
* @Description: 用户信息综合查询
* @Date:21:18 2018/3/28
*/
List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;
对其进行测试
@Test
public void testfindUserList() throws Exception{
SqlSession sqlSession = factory.openSession();
//通过反射拿到UserMapper的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
//查询所有性别为1并且性张的用户
userCustom.setSex("1");
userCustom.setUsername("张");
userQueryVo.setUserCustom(userCustom);
List<UserCustom> user = userMapper.findUserList(userQueryVo);
System.out.println(user);
}
控制台成功输出:
输出映射:
1.resultType:
只有查询出来的列名和pojo的属性名一样,该列才可以映射成功。
如果查询出来的列名和属性名全部不一致,则不会创建pojo对象,
只要查询出来的列名有一个跟pojo的属性名一致,就会创建pojo对象。
下面来做一个测试,将刚才的查询语句改成
select id,username,addr from user where user.sex = #{userCustom.sex} and user.username like '%${userCustom.username}%'
运行测试代码,
可以看出,因为查询列里面没有birthday和sex所以这两个属性查询出来为空,
再来将查询语句修改一下,将id和username取一个别名
select id bh,username xm,addr from user where user.sex = #{userCustom.sex} and user.username like '%${userCustom.username}%'
再次运行测试代码
发现除了addr以外所有的属性都变成了成员变量的初始值(对象为空,数字为0).
将addr取个别名再来试试
select id bh,username xm,addr dz from user where user.sex = #{userCustom.sex} and user.username like '%${userCustom.username}%'
这时我们可以看到,因为所有列都没有映射上,所以不会创建pojo对象,打印出来的结果是两个空的pojo对象。
返回简单类型,有时分页查询的时候需要我们传一个总数,这时就需要返回一个简单类型。
<!-- 用户信息综合查询总数 -->
<select id="findUserCount" parameterType="userQueryVo" resultType="int">
select count(*) from user where user.sex = #{userCustom.sex} and user.username like '%${userCustom.username}%'
</select>
/**
* @author:kevin
* @Description: 用户信息综合查询总数
* @Date:21:18 2018/3/28
*/
int findUserCount(UserQueryVo userQueryVo) throws Exception;
测试
运行后:结果为2.
2.resultMap
针对resultType出现的问题,可以用resultMap进行解决,它可以将定义的列名和属性名进行映射。
首先需要定义sql语句。
<!-- 使用resultMap进行输出映射
指定定义的resultMap的id,如果这个resultMap在其他的mapper文件,前面需要加namespace
-->
<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
select id bh,username xm,addr dz from user where id = #{value}
</select>
定义resultMap,它的id就是select标签中的id
<!-- 定义resultMap
type:resultMap最终映射的java对象类型,可以使用别名
id:resultMap的唯一标识
-->
<resultMap id="userResultMap" type="user">
<!-- id表示查询结果之中的唯一标识
column:查询出来的列名
property:type指定的pojo类型中的属性名
最终resultMap对column和property作一个映射关系
-->
<id column="bh" property="id"/>
<!--
result:对普通列的映射
column:查询出来的列名
property:type指定的pojo类型中的属性名
最终resultMap对column和property作一个映射关系
-->
<result column="xm" property="username"/>
<result column="dz" property="addr"/>
</resultMap>
增加一个方法:
/**
* @author:kevin
* @Description: 根据id查询用户(使用resultMap返回)
* @Date:21:18 2018/3/28
*/
User findUserByIdResultMap(int id) throws Exception;
测试:
@Test
public void testfindUserById() throws Exception{
SqlSession sqlSession = factory.openSession();
//通过反射拿到UserMapper的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserByIdResultMap(1);
System.out.println(user);
}
成功输出id为1的用户信息
User{id=1, username='kevin', birthday=null, sex='null', addr='成都'}
这里我对id,username和addr进行了映射,所以成功输出了这三列的值。