MyBatis嵌套查询

嵌套查询的概念

  1. 嵌套查询就是将原来多表查询中的联合查询语句拆成单个表的查询,再使用mybatis的语法嵌套在一起。

    * 需求:查询一个订单,与此同时查询出该订单所属的用户
    1. 联合查询
    SELECT * FROM orders o LEFT JOIN USER u ON o.`uid`=u.`id`;
    2. 嵌套查询
    2.1 先查询订单
    SELECT * FROM orders
    2.2 再根据订单uid外键,查询用户
    SELECT * FROM `user` WHERE id = #{根据订单查询的uid}
    2.3 最后使用mybatis,将以上二步嵌套起来
    

一对一嵌套查询案例

需求:查询所有订单,与此同时还要查询出每个订单所属的用户信息

  1. OrderMapper接口

    /**
     * 一对一嵌套查询:查询所有订单,与此同时还要查询出每个订单所属的用户信息
     * @return
     */
    public List<Orders> findAllWithUser2();
    
  2. OrderMapper.xml映射

    <!--一对一嵌套查询:查询所有订单,与此同时还要查询出每个订单所属的用户信息-->
    <resultMap id="orderMap2" type="com.code.entity.Orders">
        <id property="id" column="id"/>
        <result property="ordertime" column="ordertime"/>
        <result property="total" column="total"/>
        <result property="uid" column="uid"/>
        <!--fetchType="lazy" : 延迟加载策略
              fetchType="eager": 立即加载策略
          -->
        <!--问题:1.怎么去执行第二条sql , 2.如何执行第二条sql的时候,把uid作为参数进行传递-->
        <association property="user" javaType="com.code.entity.User"
                     select="com.code.mapper.UserMapper.findById" column="uid" fetchType="eager"/>
    </resultMap>
    <!--一对一嵌套查询-->
    <select id="findAllWithUser2" resultMap="orderMap2">
        SELECT * FROM orders
    </select>
    
  3. UserMapper接口

    /**
     * 根据id查询用户
     * @param id
     * @return
     */
    public User findById(Integer id);
    
  4. UserMapper.xml映射

    <select id="findById" parameterType="int" resultType="user">
    	SELECT * FROM `user` where id = #{uid}
    </select>
    
  5. 测试代码

    /**
     * 一对一嵌套查询:查询所有订单及关联的用户信息
     * @throws IOException
     */
    @Test
    public void test4() throws IOException {
    
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    
        SqlSession sqlSession = sqlSessionFactory.openSession();
    
        OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
    
        List<Orders> allWithUser2 = mapper.findAllWithUser2();
    
        for (Orders orders : allWithUser2) {
            System.out.println(orders);
        }
    
        sqlSession.close();
    }
    

一对多嵌套查询

需求:查询所有用户,与此同时查询出该用户具有的订单

  1. UserMapper接口

    /**
     * 一对多嵌套查询:查询所有的用户,同时还要查询出每个用户所关联的订单信息
     * @return
     */
    public List<User> findAllWithOrder2();
    
  2. UserMapper.xml映射

    <!--一对多嵌套查询:查询所有的用户,同时还要查询出每个用户所关联的订单信息-->
    <resultMap id="userOrderMap" type="com.code.entity.User">
        <id property="id" column="id"/>
        <result property="username" column="username"></result>
        <result property="birthday" column="birthday"></result>
        <result property="sex" column="sex"></result>
        <result property="address" column="address"></result>
        <!--fetchType="lazy" : 延迟加载策略
            fetchType="eager": 立即加载策略
        -->
        <collection property="ordersList" ofType="com.code.entity.Orders" column="id"
                    select="com.code.mapper.OrderMapper.findByUid" ></collection>
    </resultMap>
    <select id="findAllWithOrder2" resultMap="userOrderMap">
        SELECT * FROM `user`
    </select>
    
  3. OrderMapper接口

    /**
     * 一对多嵌套查询:根据uid查询对应订单
     * @param uid
     * @return
     */
    public List<Orders> findByUid(Integer uid);
    
  4. OrderMapper.xml映射

    <!--  一对多嵌套查询 根据uid查询对应订单 -->
    <select id="findByUid" parameterType="int" resultType="com.code.entity.Orders">
        SELECT * FROM orders where uid = #{uid}
    </select>
     
    
  5. 测试代码

    /**
     * 一对多嵌套查询:查询所有用户及关联的订单信息
     * @throws IOException
     */
    @Test
    public void test5() throws IOException {
    
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    
        SqlSession sqlSession = sqlSessionFactory.openSession();
    
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
        List<User> allWithOrder2 = mapper.findAllWithOrder2();
    
        for (User user : allWithOrder2) {
            System.out.println(user);
    
            // 要用到该用户的订单信息
            // System.out.println(user.getOrdersList());
        }
    
        sqlSession.close();
    }
    

多对多嵌套查询

需求:查询用户 同时查询出该用户的所有角色

-- 先查询用户
SELECT * FROM `user`;
-- 再根据用户id主键,查询角色列表
SELECT * FROM role r INNER JOIN user_role ur ON r.`id` = ur.`rid`
WHERE ur.`uid` = #{用户id};
  1. UserMapper接口

    /**
     * 多对多嵌套查询:查询所有的用户,同时还要查询出每个用户所关联的角色信息
     * @return
     */
    public List<User> findAllWithRole2();
    
  2. UserMapper.xml映射

    <!--多对多嵌套查询:查询所有的用户,同时还要查询出每个用户所关联的角色信息-->
    <resultMap id="userRoleMap2" type="com.code.entity.User">
        <id property="id" column="id"/>
        <result property="username" column="username"></result>
        <result property="birthday" column="birthday"></result>
        <result property="sex" column="sex"></result>
        <result property="address" column="address"></result>
        <collection property="roleList" ofType="com.code.entity.Role" column="id" select="com.code.mapper.RoleMapper.findByUid"></collection>
    </resultMap>
    <select id="findAllWithRole2" resultMap="userRoleMap2">
        SELECT * FROM USER
    </select>
    
  3. RoleMapper接口

    /**
     * 根据用户id查询对应角色
     * @param uid
     * @return
     */
    public List<Role> findByUid(Integer uid);
    
  4. RoleMapper.xml映射

    <!--根据用户id查询对应角色-->
    <select id="findByUid" resultType="com.code.entity.Role" parameterType="int">
        SELECT * FROM sys_role r INNER JOIN sys_user_role ur ON ur.roleid = r.id
    		WHERE ur.userid = #{uid}
    </select>
    
  5. 测试代码

    /**
     * 多对多嵌套查询:查询所有用户及关联的角色信息
     * @throws IOException
     */
    @Test
    public void test6() throws IOException {
    
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    
        SqlSession sqlSession = sqlSessionFactory.openSession();
    
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
        List<User> allWithRole2 = mapper.findAllWithRole2();
    
        for (User user : allWithRole2) {
            System.out.println(user);
        }
    
        sqlSession.close();
    
    }
    
    一对一配置:使用<resultMap>+<association>做配置,通过column条件,执行select查询
    一对多配置:使用<resultMap>+<collection>做配置,通过column条件,执行select查询
    多对多配置:使用<resultMap>+<collection>做配置,通过column条件,执行select查询
    优点:简化多表查询操作
    缺点:执行多次sql语句,浪费数据库性能
    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值