输入映射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进行了映射,所以成功输出了这三列的值。