Mybatis第五篇:查询详解

  分为单表查询、一对一关联查询、一对多查询。

一、单表查询

  单表查询的字段映射方式有三种:一般使用别名和在xml文件中配置resultMap进行映射。还有一种是使用自动映射。需要在Mybatis的全局配置文件件中增加配置开启自动映射的配置。配置驼峰命名规则自动映射可能会导致一些bug,不建议使用。

<settings>
    <!-- 是否开启自动驼峰命名规则映射,及从xx_yy映射到xxYy -->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

  1、直接使用别名进行查询。

  bean对象:

@Data
@Builder
public class TOrder implements Serializable {
    private Integer id;

    private Integer userId;

    private Long createTime;

    private Long upTime;

    private static final long serialVersionUID = 1L;

}

  sql语句:返回结果为resultType配置上具体的实体类。

<select id="selectById" parameterType="java.lang.Integer" resultType="entity.TOrder">
select
t.id, t.user_id userId, t.create_time createTime, t.up_time upTime
from t_order t
where id = #{id,jdbcType=INTEGER}
</select>

  2、在xml文件中配置resultMap进行映射。

  xml文件中配置resultMap标签:

<resultMap id="BaseResultMap" type="entity.TOrder">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="user_id" jdbcType="INTEGER" property="userId" />
    <result column="create_time" jdbcType="BIGINT" property="createTime" />
    <result column="up_time" jdbcType="BIGINT" property="upTime" />
  </resultMap>

  sql语句:返回结果为resultMap,配置上具体resultMap的Id值。

<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from t_order
    where id = #{id,jdbcType=INTEGER}
  </select>

 二、一对一关联查询(一对一关联查询存在4种方式)

  实现目标:订单查询时,查出该订单相关的用户信息

  更改TOrde 的实体类属性,增加Tuser属性。

@Data
@Builder
public class TOrder implements Serializable {
    private Integer id;

    private Integer userId;

    private Long createTime;

    private Long upTime;

    //用户信息()
    private TUser tUser;    

  private static final long serialVersionUID = 1L; }

  TUser的实体类:

@Data
@Builder
public class TUser implements Serializable {
    private Integer id;

    private String name;

    private static final long serialVersionUID = 1L;

}

  xml文件配置:

  1、resultMap直接配置级联实体类的字段:

<resultMap id="BaseResultMap2" type="entity.TOrder">
<id column="id" property="id" />
<result column="user_id" property="userId" />
<result column="create_time" property="createTime" />
<result column="up_time" property="upTime" />
<result column="user_id" property="tUser.id" />
<result column="name" property="tUser.name" />
</resultMap>

  sql语句:

<select id="selectOrderAndUserInfoById" parameterType="java.lang.Integer" resultMap="BaseResultMap2">
select
t.id, t.user_id, t.create_time, t.up_time, u.name
from
t_order t, t_user u
where
t.user_id = u.id
and t.id = #{id,jdbcType=INTEGER}
</select>

  test方法运行结果:

   测试案例运行时要注意lombok的@Builder注解的使用,1.18.8版本的lombok在实体类上加上@Builder,会使得查询之后的结果解析错误。慎用lombok。

Cause: java.lang.IllegalArgumentException: argument type mismatch

  实体类上去掉@Builder注解,正常解析查询结果:

   2、resultMap增加association标签配置

  resultMap结果集增加association标签配置

<resultMap id="BaseResultMap3" type="entity.TOrder">
    <id column="id"  property="id" />
    <result column="user_id" property="userId" />
    <result column="create_time"  property="createTime" />
    <result column="up_time"  property="upTime" />
    <association property="tUser" javaType="entity.TUser">
      <id column="user_id" property="id"/>
      <result column="name" property="name"/>
    </association>
  </resultMap>

  关键部分association内容配置,property:实体类的级联属性,javaType:属性的全类名称。

  子标签,column:sql查询出来的字段名,property:级联类的属性。

<association property="tUser" javaType="entity.TUser">
      <id column="user_id" property="id"/>
      <result column="name" property="name"/>
    </association>

  sql语句:

<select id="selectOrderAndUserInfoById" parameterType="java.lang.Integer" resultMap="BaseResultMap3">
    select
    t.id, t.user_id, t.create_time, t.up_time, u.name
    from
      t_order t, t_user u
    where
    t.user_id = u.id
    and t.id = #{id,jdbcType=INTEGER}
  </select>

  test方法运行结果:

   3、先按照订单id查询订单数据,然后在通过订单中user_id去用户表查询用户数据,通过两次查询,组合成目标结果(单个参数传递)。

  TUserDao的sql语句

<select id="selectById" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from t_user
    where id = #{id,jdbcType=INTEGER}
  </select>

  resultMap结果集配置:select为二次查询的sql,colimn的值为传递到select赋予SQL的参数,是第一次查出出来的字段。property为TOrder中级联的属性。

<resultMap id="BaseResultMap4" type="entity.TOrder">
    <id column="id"  property="id" />
    <result column="user_id" property="userId" />
    <result column="create_time"  property="createTime" />
    <result column="up_time"  property="upTime" />
    <association property="tUser" select="dao.TUserDao.selectById" javaType="entity.TUser" column="user_id"/>
  </resultMap>

  test方法

@Test
    public void test11(){
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        TOrderDao orderDao = sqlSession.getMapper(TOrderDao.class);
        TOrder order = orderDao.selectById(2);
        log.info("数据库查询结果为:{}", order);
        sqlSession.close();
    }

   执行结果

 

  4、二次查询多个参数传递。

  TUserDao.xml文件下下创建一个接收多个参数的sql

<select id="selectById2" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from t_user
    where id = #{uid1} and id = #{uid2}
  </select>

  TUserDao接口层方法:

TUser selectById2(@Param("uid1") Integer id, @Param("uid2")Integer id2);

  TOrderDao.xml中增加resultMap的配置:同样是在association 标签里面配置,多个参数在colimn属性里面换成{},字段之间用逗号分隔。

<resultMap id="BaseResultMap5" type="entity.TOrder">
    <id column="id"  property="id" />
    <result column="user_id" property="userId" />
    <result column="create_time"  property="createTime" />
    <result column="up_time"  property="upTime" />
    <association property="tUser" select="dao.TUserDao.selectById2" javaType="entity.TUser" column="{uid1=user_id, uid2=user_id}"/>
  </resultMap>

  TOrderDao中增加sql语句:

<select id="selectById2" parameterType="java.lang.Integer" resultMap="BaseResultMap5">
    select
    t.id, t.user_id, t.create_time, t.up_time
    from t_order t
    where id = #{id,jdbcType=INTEGER}
  </select>

  test方法运行结果:

三、一对多查询的多种方式(使用collection标签)

  实体类代码:

public class TOrder implements Serializable {
    private static final long serialVersionUID = 6718825777769667204L;
    private Integer id;

    private Integer userId;

    private Long createTime;

    private Long upTime;

    //用户信息(一对一关联)
//    private UserModel userModel;
    private TUser tUser;
//    订单详情信息
    private List<TOrderDetail> orderDetailList;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public Long getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Long createTime) {
        this.createTime = createTime;
    }

    public Long getUpTime() {
        return upTime;
    }

    public void setUpTime(Long upTime) {
        this.upTime = upTime;
    }

    public TUser gettUser() {
        return tUser;
    }

    public void settUser(TUser tUser) {
        this.tUser = tUser;
    }

    public List<TOrderDetail> getOrderDetailList() {
        return orderDetailList;
    }

    public void setOrderDetailList(List<TOrderDetail> orderDetailList) {
        this.orderDetailList = orderDetailList;
    }

    public TOrder() {
    }

    @Override
    public String toString() {
        return "TOrder{" +
                "id=" + id +
                ", userId=" + userId +
                ", createTime=" + createTime +
                ", upTime=" + upTime +
                ", tUser=" + tUser +
                ", orderDetailList=" + orderDetailList +
                '}';
    }
}

  1、直接查询多条结果,使用collection标签根据关联id进行解析

  xml文件的resultMap标签

<resultMap id="BaseResultMap6" type="entity.TOrder">
    <id column="id"  property="id" />
    <result column="user_id" property="userId" />
    <result column="create_time"  property="createTime" />
    <result column="up_time"  property="upTime" />
    <association property="tUser" javaType="entity.TUser">
      <id column="user_id" property="id"/>
      <result column="name" property="name"/>
    </association>
    <collection property="orderDetailList" ofType="entity.TOrderDetail">
      <id column="orderDetailId" property="id"/>
      <result column="order_id" property="orderId"/>
      <result column="goods_id" property="goodsId"/>
      <result column="num" property="num"/>
      <result column="total_price" property="totalPrice"/>
    </collection>
  </resultMap>

  xml文件的sql语句,如果缺少标红的第二个user_id,mybatis进行结果集类型转换的时候会报错。增加了之后可以正常运行。

<select id="selectOrderAllInfoById" parameterType="java.lang.Integer" resultMap="BaseResultMap6">
    select
        t.id,
        t.user_id,
        t.create_time,
        t.up_time,
        t.user_id,
        u.name,
        d.id AS orderDetailId,
        d.order_id,
        d.goods_id,
        d.num,
        d.total_price
    from
        t_order t, t_user u, t_order_detail d
    where
        t.user_id = u.id
        AND d.order_id = t.id
        and t.id = #{id,jdbcType=INTEGER}
  </select>

  test方法执行结果:

   2、多次查询获取结果集

  xml文件的resultMap结果集更改:

<resultMap id="BaseResultMap7" type="entity.TOrder">
    <id column="id"  property="id" />
    <result column="user_id" property="userId" />
    <result column="create_time"  property="createTime" />
    <result column="up_time"  property="upTime" />
    <association property="tUser" javaType="entity.TUser" column="user_id" select="dao.TUserDao.selectById"/>
    <collection property="orderDetailList" ofType="entity.TOrderDetail" column="id" select="dao.TOrderDetailDao.selectByOrderid"/>
  </resultMap>

  TOrderDao的sql:

<select id="selectOrderAllInfoById2" parameterType="java.lang.Integer" resultMap="BaseResultMap7">
    select
      t.id,
      t.user_id,
      t.create_time,
      t.up_time
    from
      t_order t
    where
      t.id = #{id,jdbcType=INTEGER}
  </select>

  TUserDao的sql:

<select id="selectById" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from t_user
    where id = #{id,jdbcType=INTEGER}
  </select>

  TOrderDetailDao的sql:

<select id="selectByOrderid" parameterType="integer" resultMap="BaseResultMap">
    SELECT
      id,
      order_id,
      goods_id,
      num,
      total_price
    from t_order_detail
    WHERE order_id = #{orderId,jdbcType=INTEGER}
  </select>

  test方法运行结果:

原文地址:https://www.cnblogs.com/8593l/p/12719742.html