当前位置:   article > 正文

Mybatis多表关联查询(一对多关联查询)_mybatis一对多关联查询

mybatis一对多关联查询

1、Mybatis一级缓存与二级缓存

目的:提高查询效率,降低数据库查询压力,提升系统整体性能。

一级缓存:默认开启,Session级别,同一个会话内生效。

命中缓存的情况:statementid、SQL语句、结果集的范围、传递的参数相同。

同一个查询之前执行DML操作,清空缓存,session.clearCache()也会清空缓存。

二级缓存:需要配置,SQLSessionFactory级别,不同会话之间可以共享。

使用步骤:1、全局配置mybatis_config.xml文件中

<settting name="cacheEnabled" value="true" />

2、mapper.xml配置要使用二级缓存的查询

<cache />

3、使用查询返回的对象的类必须实现序列化接口。

MemCached、OSCache、EHCache。

2、Mybatis一对一关联查询

<association>标签是处理单一的关联对象(处理单一属性的关联关系)。

property :指定关联对象的属性

javaType :关联对象的类型(可以省略)

select :执行一个新的查询

column:在新的查询中用哪个列的值作为查询条件

2.1 RolesMapper.java

提供一个根据用户主键userid去查询用户角色的方法,如下:

  1. public interface RolesMapper {
  2. /**
  3. * 根据用户id查询此用户对应的角色信息
  4. * @param id
  5. * @return
  6. */
  7. Roles findRolesByUserId(int id);
  8. }

2.2 RolesMapper.xml配置

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTDMapper3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.dyh.dao.RolesMapper">
  6. <!--<resultMap id="rolesMap" type="com.dyh.pojo.Roles">
  7. <id property="roleid" column="roleid" />
  8. <result property="roleName" column="rolename" />
  9. </resultMap>-->
  10. <!--<select id="findRolesByUserId" resultMap="rolesMap" parameterType="int">-->
  11. <select id="findRolesByUserId" resultType="roles" parameterType="int">
  12. select roleid,rolename from roles where user_id=#{userid}
  13. </select>
  14. </mapper>

2.3 JUnit单元测试RolesMapperTest

  1. package com.dyh.test;
  2. import com.dyh.dao.RolesMapper;
  3. import com.dyh.pojo.Roles;
  4. import com.dyh.util.MybatisUtil;
  5. import org.apache.ibatis.session.SqlSession;
  6. import org.junit.After;
  7. import org.junit.Before;
  8. import org.junit.Test;
  9. import static org.junit.Assert.*;
  10. public class RolesMapperTest {
  11. SqlSession session;
  12. RolesMapper mapper;
  13. @Before
  14. public void setUp() throws Exception {
  15. session = MybatisUtil.getConnection();
  16. mapper = session.getMapper(RolesMapper.class);
  17. }
  18. @Test
  19. public void testFindRolesByUserId(){
  20. Roles roles = mapper.findRolesByUserId(1);
  21. System.out.println(roles);
  22. }
  23. @After
  24. public void tearDown() throws Exception {
  25. MybatisUtil.closeConnection();
  26. }
  27. }

2.4 UserMapper.java

增加如下方法:

  1. public interface UsersMapper {
  2. List<Users> queryUsersAndRoles();
  3. // 增加如下方法
  4. List<Users> queryUsersAndRolesBySelect();
  5. }

2.5 UserMapper.xml

增加如下内容:

  1. <resultMap id="usersAndRolesMap2" type="users">
  2. <id property="userid" column="userid" />
  3. <result property="username" column="username" />
  4. <result property="usersex" column="usersex" />
  5. <!-- 配置一对一的关联关系 -->
  6. <!-- column="userid" 是users表中的主键,使用这个值取查询roles表 -->
  7. <association property="roles" javaType="roles"
  8. select="com.dyh.dao.RolesMapper.findRolesByUserId" column="userid">
  9. <id property="roleid" column="roleid" />
  10. <result property="roleName" column="rolename" />
  11. </association>
  12. </resultMap>
  13. <sql id="deptColumns">
  14. deptno,dname,loc as city
  15. </sql>
  16. <select id="queryUsersAndRolesBySelect" resultMap="usersAndRolesMap2">
  17. SELECT u.userid,u.username,u.usersex
  18. FROM users u
  19. </select>

2.6 JUnit单元测试UsersMapperTest.java

  1. @Test
  2. public void testQueryUsersAndRoles2(){
  3. List<Users> list = mapper.queryUsersAndRolesBySelect();
  4. list.forEach(System.out::println);
  5. }

fb1437191c094c2bb300fd169daa57f3.png

2.7 延迟加载与立即加载

在association一对一关联标签和collection一对多关联标签中有个属性fetchType="lazy",属性值有lazy懒加载(延迟加载)、eager立即加载。如果不配置fetchType属性值,fetchType默认值是eager立即加载。

2.7.1 懒加载(延迟加载)lazy

测试类UsersMapperTest.java中修改代码如下:注意,不能直接打印users对象,因为其toString方法中获取了roles的属性值。

  1. @Test
  2. public void testQueryUsersAndRoles2(){
  3. List<Users> list = mapper.queryUsersAndRolesBySelect();
  4. //list.forEach(System.out::println);
  5. for (Users users:list) {
  6. System.out.println(users.getUsername());
  7. // 懒加载没有获取角色信息的时候,不会去查询角色表
  8. //System.out.println(users.getRoles());
  9. }
  10. }

UserMapper.xml配置修改如下:

30e6161e42d940fd94d5192f68948e5e.png

a6d885f3c4e04d388950db33fac49b14.png

c898779667bd48e2ac9c2363a85d1b2e.png

0d65e9c807db4032ace8d211262efd9d.png

8297bfe7b8924bf29c8a4df1b90e3151.png

4decbd13c87b491ca59491dcf2d03072.png

一、一对多关联查询

应用场景:完成用户与订单查询。 要求一个用户可以对应多个订单。

1、collection标签

<collection>标签是处理所关联对象是多个的(处理关联属性是集合时的关联关系)。

property :指定关联对象的属性

javaType :关联对象的类型(可省略。默认List 类型,如果集合是 Set 类型时需要配置并给定 Set 的全名 )

ofType:指定集合里存放的对象类型

select :执行一个新的查询

column:在新的查询中用哪个列的值作为查询条件

2、建表orders

  1. -- users表使用上次课建立好的表和数据
  2. CREATE TABLE `orders`(
  3. `orderid` INT(11) NOT NULL AUTO_INCREMENT,
  4. `orderprice` DOUBLE DEFAULT NULL,
  5. `user_id` INT(11) DEFAULT NULL,
  6. PRIMARY KEY(`orderid`),
  7. KEY `orders_fk`(`user_id`),
  8. CONSTRAINT `orders_fk` FOREIGN KEY(`user_id`) REFERENCES `users`(`userid`) ) ENGINE=INNODB DEFAULT CHARSET=utf8;
  9. INSERT INTO orders VALUES(DEFAULT, 80, 1),
  10. (DEFAULT, 90, 1),
  11. (DEFAULT, 100, 1),
  12. (DEFAULT, 92, 2),
  13. (DEFAULT, 102, 2);
  14. SELECT * FROM orders;
  15. -- 一对多查询,查询用户及其对应的订单信息
  16. SELECT u.userid,u.username,u.usersex,
  17. o.orderid,o.orderprice
  18. FROM users u,orders o
  19. WHERE u.userid=o.user_id

3、Orders实体类

  1. public class Orders {
  2. private Integer orderid;
  3. private Double orderprice;
  4. // get、set、toString、constructor方法自行补充
  5. }

4、修改Users实体类

一对多,说明一个users对象可以有多个订单,所以要在Users类中添加如下属性:

  1. private List<Orders> ordersList;
  2. public List<Orders> getOrdersList() {
  3. return ordersList;
  4. }
  5. public void setOrdersList(List<Orders> ordersList) {
  6. this.ordersList = ordersList;
  7. }
  8. @Override
  9. public String toString() {
  10. return "Users{" +
  11. "userid=" + userid +
  12. ", username='" + username + '\'' +
  13. ", usersex='" + usersex + '\'' +
  14. ", roles=" + roles +
  15. ",orderList=" + ordersList +
  16. '}';
  17. }

5、修改UsersMapper.java

  1. /**
  2. * 查询用户和其所下的订单
  3. * @return
  4. */
  5. List<Users> queryUsersAndOrders();

6、修改UsersMapper.xml

  1. <resultMap id="usersAndOrdersMap" type="com.dyh.pojo.Users">
  2. <id property="userid" column="userid" />
  3. <result property="username" column="username" />
  4. <result property="usersex" column="usersex" />
  5. <!-- 配置一对多的关联关系 -->
  6. <collection property="ordersList" ofType="com.dyh.pojo.Orders" >
  7. <id property="orderid" column="orderid" />
  8. <result property="orderprice" column="orderprice" />
  9. </collection>
  10. </resultMap>
  11. <sql id="deptColumns">
  12. deptno,dname,loc as city
  13. </sql>
  14. <select id="queryUsersAndOrders" resultMap="usersAndOrdersMap">
  15. SELECT u.userid,u.username,u.usersex,
  16. o.orderid,o.orderprice
  17. FROM users u,orders o
  18. WHERE u.userid=o.user_id
  19. </select>

7、测试UsersMapperTest.java

增加如下方法:

  1. @Test
  2. public void testQueryUsersAndOrders(){
  3. List<Users> list = mapper.queryUsersAndOrders();
  4. list.forEach(System.out::println);
  5. }

118c9094b11b49baaa16738d182b723e.png

二、一对多查询实现方式二

1、UsersMapper.java

中增加如下方法:

  1. /**
  2. * 查询用户和其所下的订单
  3. * @return
  4. */
  5. List<Users> queryUsersAndOrders2();

2、UserMapper.xml

中增加如下代码:

  1. <resultMap id="usersAndOrdersMap2" type="com.dyh.pojo.Users">
  2. <id property="userid" column="userid" />
  3. <result property="username" column="username" />
  4. <result property="usersex" column="usersex" />
  5. <!-- 配置一对多的关联关系 -->
  6. <collection property="ordersList" ofType="com.dyh.pojo.Orders"
  7. select="com.dyh.dao.OrdersMapper.findOrderListByUsersId" column="userid">
  8. <id property="orderid" column="orderid" />
  9. <result property="orderprice" column="orderprice" />
  10. </collection>
  11. </resultMap>
  12. <sql id="deptColumns">
  13. deptno,dname,loc as city
  14. </sql>
  15. <select id="queryUsersAndOrders2" resultMap="usersAndOrdersMap2">
  16. SELECT u.userid,u.username,u.usersex
  17. FROM users u
  18. </select>

需要增加com.dyh.OrdersMapper.findOrderListByUsersId的接口及实现。

3、OrdersMapper.java

  1. public interface OrdersMapper {
  2. /**
  3. * 根据用户id去查询用户的所有订单
  4. * @param userid 用户id
  5. * @return 订单集合
  6. */
  7. List<Orders> findOrderListByUsersId(int userid);
  8. }

4、OrdersMapper.xml

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTDMapper3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.dyh.dao.OrdersMapper">
  6. <select id="findOrderListByUsersId"
  7. resultType="com.dyh.pojo.Orders" parameterType="int">
  8. select orderid,orderprice from orders where user_id=#{userid}
  9. </select>
  10. </mapper>

5、JUnit单元测试UsersMapperTest.java

增加如下代码:

  1. @Test
  2. public void testQueryUsersAndOrders2(){
  3. List<Users> list = mapper.queryUsersAndOrders2();
  4. list.forEach(System.out::println);
  5. }

测试结果

c51e92c6d4674989949d69074142a2bc.png

一对一的实现方式二:<association select="" />

延迟加载与立即加载:<association fetchType="lazy|eager" />

一对多关联查询:<collection ofType="集合中的对象类型" />

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/830553
推荐阅读
相关标签
  

闽ICP备14008679号