Mybatis(三)之输入输出映射

参考自《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来指定哪一个

三、Map封装多参数:

public List getXXXBeanList(HashMap map);  



其中hashmap是mybatis自己配置好的直接使用就行。map中key的名字是那个就在#{}使用那个

四、List封装in:

public List getXXXBeanList(List list);  

  

foreach 最后的效果是select 字段... from XXX where id in ('1','2','3','4') 

注意:如果parameterType是List或者Array的话,那么foreach语句中,collection属性值需要固定为list或者array。

五、selectList()只能传递一个参数,但实际所需参数既要包含String类型,又要包含List类型时的处理方法:

将参数放入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

resultType

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对象和pojo列表

不管是输出的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 (返回集合对象调用 ).

resultMap

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属性名之间作一个映射关系。


输出映射进阶之关联查询

场景:一个订单对应一个用户,同时一个订单对应多个订单明细

数据库

Mybatis(三)之输入输出映射_第1张图片

一对一(订单为主)

需求:查询订单列表,关联查询用户信息
sql语句:

SELECT orders.*, user.`username`, user.`sex` FROM orders, USER WHERE orders.`user_id` = user.`id`

方式一:resultType

由于订单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、此方法较为简单,企业中使用普遍。

方式二:resultMap

与方式一类似,扩展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` 

resultMap

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();
    //......
}

多对多(用户为主)

需求:查询用户信息,关联查询该用户购买的商品信息
关系:一个用户对多个订单,一个订单对多个明细,一个明细对一个商品信息

sql语句:

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`

修改pojo类

public class User {
    //一个用户对多个订单
    private List orders;
    //...
}
public class Orders {
    // 一个订单对多个明细
    private List detail;
    //...
}
public class Orderdetail { 
    //一条明细对一条商品信息
    private Items items;
} 

mapper接口

public interface UserMapper {
    public List findUserAndDetailByRstMap();
}

mapper映射文件


<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只有特殊场景才会用,比如延迟加载。

你可能感兴趣的:(【框架】Mybatis)