Mybatis 一对一和一对多查询

Mybatis 一对一和一对多查询

首先创建两个实体类(尽量实现全部的getter和setter方法,防止后续出错,此处使用Lombok)

@Data
public class Order {
    private Integer no;
    private Integer userId;
    private Integer goodsId;
    private Integer goodsAmount;
}
@Data
public class User {
    private Integer id;
    private String username;
    private String password;
    private String tel;
    private String address;
}

一对多

这里要在一的一方增加一个多的一方的List集合属性

@Data
public class User {
    private Integer id;
    private String username;
    private String password;
    private String tel;
    private String address;
    //多
    private List<Order> orderList;
}

接下来是Mapper.xml中配置,使用collection映射多的一方的结果

第一种联表查询方式

此种方式将的关联关系写在查询的sql中,在xml文件中写sql结尾不要写分号

<select id="queryUserById" parameterType="integer" resultMap="userResultWithOrder">
        SELECT user_tb.*,order_tb.* FROM user_tb,order_tb WHERE user_tb.id=#{id} AND order_tb.user_id=user_tb.id
     </select>
    <resultMap id="userResultWithOrder" type="user">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <result property="tel" column="tel"/>
        <result property="address" column="address"/>
    <!--多的一方的集合-->
        <collection property="orderList" ofType="order">
            <id property="no" column="no"/>
       <result property="userId" column="user_id" />
            <result property="goodsId" column="goods_id" />
            <result property="goodsAmount" column="goods_amount" />
        </collection>
    </resultMap>

第二种子查询方式

此种方式是将多的一方的结果通过单独的查询,将结果返回

<select id="queryUserById" parameterType="integer" resultMap="userResultWithOrder">
        SELECT * FROM user_tb WHERE id=#{id}
     </select>
    <resultMap id="userResultWithOrder" type="user">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <result property="tel" column="tel"/>
        <result property="address" column="address"/>
         <!--此处使用子查询方式,调用子查询返回多的一方结果。通过付`column`设置要关联的字段,传入到子查询中,此处的select属性值依与子查询的id对应-->
        <collection property="orderList" column="id" ofType="order" select="queryOrderByUserId"/>
    </resultMap>
     
      <!--子查询-->
     <select id="queryOrderByUserId" parameterType="integer" resultMap="orderMap">
        SELECT * FROM order_tb WHERE user_id=#{id}
    </select>
    <resultMap id="orderMap" type="order">
        <id property="no" column="no"/>
        <result property="userId" column="user_id"/>
        <result property="goodsId" column="goods_id"/>
        <result property="goodsAmount" column="goods_amount"/>
    </resultMap>

一对一

一对一也有两种方式,使用association映射结果

@Data
public class User {
    private Integer id;
    private String username;
    private String password;
    private String tel;
    private String address;
    //一
    private Order order;
}

第一种联表查询方式

<select id="queryUserById" parameterType="integer" resultMap="userResultWithOrder">
        SELECT user_tb.*,order_tb.* FROM user_tb,order_tb WHERE user_tb.id=#{id} AND order_tb.user_id=user_tb.id
     </select>
    <resultMap id="userResultWithOrder" type="user">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <result property="tel" column="tel"/>
        <result property="address" column="address"/>
    <!--这里用到的是javaType,与一对多使用ofType不同-->
        <association  property="order" javaType="order">
            <id property="no" column="no"/>
       <result property="userId" column="user_id" />
            <result property="goodsId" column="goods_id" />
            <result property="goodsAmount" column="goods_amount" />
        </collection>
    </resultMap>

第二种子查询方式

<select id="queryUserById" parameterType="integer" resultMap="userResultWithOrder">
        SELECT * FROM user_tb WHERE id=#{id}
     </select>
    <resultMap id="userResultWithOrder" type="user">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <result property="tel" column="tel"/>
        <result property="address" column="address"/>
         <!--通过付`column`设置要关联的字段,传入到子查询中,此处的select属性值依与子查询的id对应-->
        <association property="orderList" column="id" javaType="order" select="queryOrderByUserId"/>
    </resultMap>
     
      <!--子查询,此处传入的参数,就是上面的column对应字段的值-->
     <select id="queryOrderByUserId" parameterType="integer" resultMap="orderMap">
        SELECT * FROM order_tb WHERE user_id=#{id}
    </select>
    <resultMap id="orderMap" type="order">
        <id property="no" column="no"/>
        <result property="userId" column="user_id"/>
        <result property="goodsId" column="goods_id"/>
        <result property="goodsAmount" column="goods_amount"/>
    </resultMap>

总结

  1. 在xml中的type可以使用别名,也可以使用全路径;

  2. select的id值必须与mapper接口中方法名一致,可以使用插件防止出错,例如:FreeMybatisPlugin,MybatisCodeHelper Pro

  3. 项目中进行一对多查询时可能也会涉及到扩展类,即不在原基础实体类修改,通过继承的方式,进行属性拓展。如下所示

    <resultMap id="Father" type="xxxx">
        <result property="name" column="NAME"/>
        <result property="volume" column="VOLUME"/>
    </resultMap>
    <!--通过Extends设置要继承的父类即可,属性值对应父类的resultMap的id值-->
    <resultMap id="extendDemo" type="XXXX" extends="Father">
        <result property="level1" column="LEVEL1"/>
        <result property="level2" column="LEVEL2"/>
    </resultMap>
    
    

    扩展

    批量写操作

    <insert id="insertUserRoleBatch">
        INSERT INTO t_user_role(user_id,role_id)
        VALUES
          <foreach collection="userRoles" index="index" item="userRole" separator=",">
            (#{userRole.userId},#{userRole.roleId})
          </foreach>
      </insert>
    

    collection:传入集合或数组的名称。

    index:遍历数组或集合的索引一般就写index。

    item:取出每一个元素的名称。

    separator:上一个元素与下一个元素之间填充的字符,如不需要则不添加此属性。

    批量查询

    此处进行了截取,主要应用的IN关键字部分,通过传入的集合进行拼接

    AND XXXX IN
             <foreach collection="clientTypes" index="index" item="clientTypeInt"
                      open="(" close=")" separator=",">
               #{clientTypeInt}
             </foreach>
    
    

    open:表示在每个元素前填充字符。

    close:表示在每个元素后填充字符。

    模糊查询

    locate(#{name,jdbcType=VARCHAR}, t.name)>0t.name数据库字段名,#{name,jdbcType=VARCHAR}传入的参数值。locate函数会帮我们实现模糊查询,类似于javaindexOf

    查询结果字符串拼接

    GROUP_CONCAT(tct.client_name SEPARATOR ‘,’) :连接字符串函数。

    tct.client_name :需要连接的字段名。

    SEPARATOR ',' :中间连接符。

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值