嵌套查询的概念
-
嵌套查询就是将原来多表查询中的联合查询语句拆成单个表的查询,再使用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,将以上二步嵌套起来
一对一嵌套查询案例
需求:查询所有订单,与此同时还要查询出每个订单所属的用户信息
-
OrderMapper接口
/** * 一对一嵌套查询:查询所有订单,与此同时还要查询出每个订单所属的用户信息 * @return */ public List<Orders> findAllWithUser2();
-
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>
-
UserMapper接口
/** * 根据id查询用户 * @param id * @return */ public User findById(Integer id);
-
UserMapper.xml映射
<select id="findById" parameterType="int" resultType="user"> SELECT * FROM `user` where id = #{uid} </select>
-
测试代码
/** * 一对一嵌套查询:查询所有订单及关联的用户信息 * @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(); }
一对多嵌套查询
需求:查询所有用户,与此同时查询出该用户具有的订单
-
UserMapper接口
/** * 一对多嵌套查询:查询所有的用户,同时还要查询出每个用户所关联的订单信息 * @return */ public List<User> findAllWithOrder2();
-
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>
-
OrderMapper接口
/** * 一对多嵌套查询:根据uid查询对应订单 * @param uid * @return */ public List<Orders> findByUid(Integer uid);
-
OrderMapper.xml映射
<!-- 一对多嵌套查询 根据uid查询对应订单 --> <select id="findByUid" parameterType="int" resultType="com.code.entity.Orders"> SELECT * FROM orders where uid = #{uid} </select>
-
测试代码
/** * 一对多嵌套查询:查询所有用户及关联的订单信息 * @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};
-
UserMapper接口
/** * 多对多嵌套查询:查询所有的用户,同时还要查询出每个用户所关联的角色信息 * @return */ public List<User> findAllWithRole2();
-
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>
-
RoleMapper接口
/** * 根据用户id查询对应角色 * @param uid * @return */ public List<Role> findByUid(Integer uid);
-
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>
-
测试代码
/** * 多对多嵌套查询:查询所有用户及关联的角色信息 * @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语句,浪费数据库性能