zoukankan      html  css  js  c++  java
  • 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方法运行结果:

  • 相关阅读:
    Task 5.1 电梯调度程序需求调研报告
    Task 4 求数组的连续子数组的最大和(团队合作)
    class 3 求数组中的最大值(单元测试)
    《你的灯亮着吗》读书笔记3
    优惠购书
    校友聊NABCD
    环状二维数组(改进版)
    环状二维数组
    环状一维数组
    二维数组最大值
  • 原文地址:https://www.cnblogs.com/8593l/p/12719742.html
Copyright © 2011-2022 走看看