参考自《mybatis parametertype 多个参数》
参考自《mybatis学习笔记(7)-输出映射》
方案1
public List getXXBeanList(@param("id")String id);
<select id="getXXXBeanList" parameterType="java.lang.String" resultType="XXBean">
select t.* from tableName t where t.id= #{id}
select>
其中方法名和ID一致,#{}中的参数名与方法中的参数名一致, 这里采用的是@Param这个参数,实际上@Param这个最后会被Mabatis封装为map类型的。
select 后的字段列表要和bean中的属性名一致, 如果不一致的可以用 as 来补充。
方案2
//在实际需求中,我们经常需要结合多个条件综合查询,而这些条件并不在同一个POJO类中,
//所以需要对POJO类进行包装,生成另外一个类作为参数类型
public class UserQueryVO {
// 用户信息
private User user;
// 订单信息
private Order order;
//...
}
public List getUserList(UserQueryVO vo);
<select id="getUserList" parameterType="com.zyj.mybatis.po.UserQueryVO" resultType="com.zyj.mybatis.po.User">
select * from user where username like '%${user.username}%' and sex = #{user.sex}
select>
方案1
public List getXXXBeanList(String xxId, String xxCode);
<select id="getXXXBeanList" resultType="XXBean">不需要写parameterType参数
select t.* from tableName where id = #{0} and name = #{1}
select>
由于是多参数那么就不能使用parameterType, 改用#{index}是第几个就用第几个的索引,索引从0开始
方案2
public List getXXXBeanList(@Param("id")String id, @Param("code")String code);
<select id="getXXXBeanList" resultType="XXBean">
select t.* from tableName where id = #{id} and name = #{code}
select>
由于是多参数那么就不能使用parameterType, 这里用@Param来指定哪一个
public List getXXXBeanList(HashMap map);
其中hashmap是mybatis自己配置好的直接使用就行。map中key的名字是那个就在#{}使用那个
public List getXXXBeanList(List list);
foreach 最后的效果是select 字段... from XXX where id in ('1','2','3','4')
注意:如果parameterType是List或者Array的话,那么foreach语句中,collection属性值需要固定为list或者array。
将参数放入Map,再取出Map中的List遍历。如下:
List list_3 = new ArrayList();
Map map2 = new HashMap();
list.add("1");
list.add("2");
map.put("list", list); //网址id
map.put("siteTag", "0");//网址类型
public List getSysInfo(Map map2) {
return getSqlSession().selectList("sysweb.getSysInfo", map2);
}
输出映射有两种方式
1. resultType
2. resultMap
1.使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
2.如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。
3.只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。
mapper.xml
<select id="findUserCount" parameterType="com.iot.mybatis.po.UserQueryVo" resultType="int">
SELECT count(*) FROM user WHERE user.sex=#{userCustom.sex} AND user.username LIKE '%${userCustom.username}%'
select>
mapper.java
//用户信息综合查询总数
@Test
public void testFindUserCount() throws Exception {
//......
//创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//创建包装对象,设置查询条件
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
userCustom.setSex("1");
userCustom.setUsername("小");
userQueryVo.setUserCustom(userCustom);
//调用userMapper的方法
int count = userMapper.findUserCount(userQueryVo);
//......
}
小结
查询出来的结果集只有一行且一列,可以使用简单类型进行输出映射。
不管是输出的pojo单个对象还是一个列表(list中包括pojo),在mapper.xml中resultType指定的类型是一样的。
在mapper.java指定的方法返回值类型不一样:
输出单个pojo对象,方法返回值是单个对象类型
//根据id查询用户信息
public User findUserById(int id) throws Exception;
输出pojo对象list,方法返回值是List
//根据用户名列查询用户列表
public List findUserByName(String name) throws Exception;
生成的动态代理对象中是根据mapper方法的返回值类型确定是调用selectOne(返回单个对象调用)还是selectList (返回集合对象调用 ).
mybatis中使用resultMap完成高级输出结果映射。(一对多,多对多)
resultMap使用方法
如果查询出来的列名和pojo的属性名不一致,则需要通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。
1.定义resultMap
2.使用resultMap作为statement的输出映射类型
定义reusltMap
<resultMap type="user" id="userResultMap">
<id column="id_" property="id"/>
<result column="username_" property="username"/>
resultMap>
使用resultMap作为statement的输出映射类型
<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
SELECT id id_,username username_ FROM USER WHERE id=#{value}
select>
mapper.java
//根据id查询用户信息,使用resultMap输出
public User findUserByIdResultMap(int id) throws Exception;
测试代码
@Test
public void testFindUserByIdResultMap() throws Exception {
//......
//创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用userMapper的方法
User user = userMapper.findUserByIdResultMap(1);
//.......
}
小结
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。
场景:一个订单对应一个用户,同时一个订单对应多个订单明细
需求:查询订单列表,关联查询用户信息
sql语句:
SELECT orders.*, user.`username`, user.`sex` FROM orders, USER WHERE orders.`user_id` = user.`id`
由于订单pojo类orders中没有含有用户表user字段,所以这里可以包装订单类orders
public class OrdersExt extends Orders {
private String username;
private String sex;
//省略getter和setter方法
}
// mapper接口
public interface OrdersMapper {
public List<OrdersExt> findOrdersAndUserByRstType();
}
// mapper映射文件
<mapper namespace="com.zyj.mybatis.mapper.OrdersMapper">
<select id="findOrdersAndUserByRstType" resultType="com.zyj.mybatis.dto.OrdersExt">
SELECT orders.*, user.`username`, user.`sex` FROM orders, USER WHERE orders.`user_id` = user.`id`
</select>
</mapper>
// 测试代码
@Test
public void testFindOrdersAndUserByRstType() {
//......
List<OrdersExt> list = ordersMapper.findOrdersAndUserByRstType();
//......
}
小结:
1、一对一关联查询时,可以定义专门的扩展po类作为输出结果类型。
2、该扩展po类中定义了sql查询结果集所有的字段对应的属性。
3、此方法较为简单,企业中使用普遍。
与方式一类似,扩展pojo类,与用户类User产生关联关系,并修改mapper映射文件
public class OrdersExt extends Orders {
private User user;
//省略getter和setter方法
}
// mapper接口
public interface OrdersMapper {
public List<OrdersExt> findOrdersAndUserByRstMap();
}
// mapper映射文件
<resultMap type="com.zyj.mybatis.dto.OrdersExt" id="OrdersAndUserRstMap">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<association property="user" javaType="com.zyj.mybatis.po.User">
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
association>
resultMap>
<select id="findOrdersAndUserByRstMap" resultMap="OrdersAndUserRstMap">
SELECT
orders.*,
user.`username`,
user.`sex`
FROM
orders,
USER
WHERE orders.`user_id` = user.`id`
select>
// 测试代码
@Test
public void testFindOrdersAndUserByRstType() {
//......
List<OrdersExt> list = mapper.findOrdersAndUserByRstMap();
//......
}
小结:
使用resultMap进行结果映射时,具体是使用association完成关联查询的映射,将关联查询信息映射到pojo对象中。
需求:查询订单列表,关联查询用户信息,而且同时附带相应的订单明细
sql语句:
SELECT
orders.id,
orders.`number`,
orders.`createtime`,
user.`username`,
user.`sex`,
orderdetail.`id` detailId,
orderdetail.`items_num`
FROM
orders,
USER,
orderdetail
WHERE orders.`user_id` = user.`id`
AND orders.`id` = orderdetail.`orders_id`
public class OrdersExt extends Orders {
private User user;
private List details;
//省略getter和setter方法
}
// mapper接口
public interface OrdersMapper {
public List<OrdersExt> findOrdersAndDetailByRstMap();
}
// mapper映射文件
<resultMap type="com.zyj.mybatis.dto.OrdersExt" id="OrdersAndDetailRstMap" extends="OrdersAndUserRstMap">
<collection property="details" ofType="com.zyj.mybatis.po.Orderdetail">
<id column="detailId" property="id"/>
<result column="items_num" property="itemsNum"/>
collection>
resultMap>
<select id="findOrdersAndDetailByRstMap" resultMap="OrdersAndDetailRstMap">
SELECT
orders.id,
orders.`number`,
orders.`createtime`,
user.`username`,
user.`sex`,
orderdetail.`id` detailId,
orderdetail.`items_num`
FROM
orders,
USER,
orderdetail
WHERE orders.`user_id` = user.`id`
AND orders.`id` = orderdetail.`orders_id`
select>
// 测试代码
@Test
public void testFindOrdersAndUserByRstType() {
//......
List<OrdersExt> list = mapper.findOrdersAndDetailByRstMap();
//......
}
需求:查询用户信息,关联查询该用户购买的商品信息
关系:一个用户对多个订单,一个订单对多个明细,一个明细对一个商品信息
SELECT
orders.id orders_id,
orders.`number`,
orders.`createtime`,
user.`id` user_id,
user.`username`,
user.`sex`,
orderdetail.`id` detail_id,
orderdetail.`items_num`,
items.`id` items_id,
items.`name`,
items.`price`
FROM
orders,
USER,
orderdetail,
items
WHERE orders.`user_id` = user.`id`
AND orders.`id` = orderdetail.`orders_id`
AND orderdetail.`items_id` = items.`id`
public class User {
//一个用户对多个订单
private List orders;
//...
}
public class Orders {
// 一个订单对多个明细
private List detail;
//...
}
public class Orderdetail {
//一条明细对一条商品信息
private Items items;
}
public interface UserMapper {
public List findUserAndDetailByRstMap();
}
<resultMap type="com.zyj.mybatis.po.User" id="UserAndDetailRstMap">
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<collection property="orders" ofType="com.zyj.mybatis.po.Orders">
<id column="orders_id" property="id"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<collection property="detail" ofType="com.zyj.mybatis.po.Orderdetail">
<id column="detail_id" property="id"/>
<result column="items_num" property="itemsNum"/>
<association property="items" javaType="com.zyj.mybatis.po.Items">
<id column="items_id" property="id"/>
<result column="name" property="name"/>
<result column="price" property="price"/>
association>
collection>
collection>
resultMap>
<select id="findUserAndDetailByRstMap" resultMap="UserAndDetailRstMap">
SELECT
orders.id orders_id,
orders.`number`,
orders.`createtime`,
user.`id` user_id,
user.`username`,
user.`sex`,
orderdetail.`id` detail_id,
orderdetail.`items_num`,
items.`id` items_id,
items.`name`,
items.`price`
FROM
orders,
USER,
orderdetail,
items
WHERE orders.`user_id` = user.`id`
AND orders.`id` = orderdetail.`orders_id`
AND orderdetail.`items_id` = items.`id`
select>
@Test
public void testFindUserAndDetailByRstMap() {
//......
List list = mapper.findUserAndDetailByRstMap();
//......
}
小结:
虽然resultMap和resultType都可以进行结果映射,但是使用resultType更加便捷,企业中建议使用resultType完成结果映射。
resultMap只有特殊场景才会用,比如延迟加载。