mybatis的一对一,一对多的关系映射配置及性能分析(延迟加载)

一对一关系映射

1)自动关联(偷懒的办法):可以自定义一个大而全的pojo类,然后自动映射其实是根据数据库总的字段名称和
	pojo中的属性名称对应.
2)手动关联: 需要指定数据库中表的字段名称和java的pojo类中的属性名称的对应关系.
	使用association标签

需求: 查询订单所属的客户

UserMapper.xml配置:

<resultMap type="Orders" id="OrdersOneToOneMap">
	<!--id:唯一性标识
    	column:表示sql查询出来的字段名。
    	property:代表字段映射的实体类的属性名
	-->
	
	<id column="id" property="id" />
	 <result column="user_id" property="userId"/>
	 <result column="number" property="number"/>
	 <result column="createtime" property="createtime"/>
	 <!--association:用于映射关联查询单个对象的信息
            property:要将关联查询的用户信息映射到Orders中那个属性
            association:表示进行关联查询单条记录
            javaType:表示关联查询的结果类型
         -->
	<association property="user" javaType="User">
		<id column="user_id" property="id"/>
		<result column="username" property="username"/>
		<result column="sex" property="sex"/>
		<result column="birthday" property="birthday"/>
		<result column="address" property="address"/>
	</association>
	 

</resultMap>
<!-- 查询订单对应的客户一对一关系 -->
<select id="findOrdersOneToOne" resultMap="OrdersOneToOneMap">
	SELECT
		o.*, u.username,
		u.birthday,
		u.sex,
		u.address
	FROM
		orders o,
		USER u
	WHERE
		o.user_id = u.id;

</select>
还有另外一种方法:

 <resultMap type="Orders" id="OrdersOneToOneMap">
   <id column="id" property="id" />
   <result column="user_id" property="userId"/>
   <result column="number" property="number"/>
   <result column="createtime" property="createtime"/>
   <!--column:指定传递给select的参数,如果是多个参数,用逗号隔开;select:指定的sql去查询--> 
   <association property="user" column="id" select="com.learn.chapter4.OrerMapper.seletOrderByuserId"/>
 </resultMap>
 <!-- 查询订单对应的客户一对一关系 -->
 <select id="findOrdersOneToOne"  resultMap="OrdersOneToOneMap">
 	SELECT
 	    u.username,
 		u.birthday,
 		u.sex,
 		u.address
 	FROM
 		USER u
 	WHERE
 		u.user_id = #{id};
 
 </select>
一对多的关系映射:

只能使用手动映射:指定表中字段名称和pojo中属性名称的对应关系
	使用collection标签

需求:查询一个用户对应多个订单;
    在user实体类中有List<Orders> ordersList;的集合

    <!--将查询到的信息映射到实体bean-->
	<resultMap type="User" id="UserOrdersMap">
	<!--id:唯一性标识
	column:表示sql查询出来的字段名。
	property:代表字段映射的实体类的属性名-->
	<id column="id" property="id"/>
	<result column="username" property="username"/>
	<result column="sex" property="sex"/>
	<result column="address" property="address"/>

	<!--使用resultMap的collection对关联查询的多条记录映射到一个list集合属性中。-->
	 <!-- 关联订单明细信息 
            一个用户关联查询出了多条订单明细,要使用collection映射
            collection:对关联查询到的多条记录映射到集合中
            property:将关联查询到的多条记录映射到orders类的那个属性
            ofType:指定映射的集合属性中pojo的类型
         -->
	<collection property="ordersList" ofType="Orders">
	<!--id:唯一性标识-->
		<id column="order_id" property="id"/>
		<result column="number" property="number"/>
		<result column="createtime" property="createtime"/>
	</collection>

</resultMap>

<!--resultMap需要定义,并且此处的resultMap的值与定义的resultMap的id一致--->
<select id="findUserOrders" resultMap="UserOrdersMap">
	SELECT
		u.*, o.id order_id,
		o.number,
		o.createtime,
		o.note
	FROM
		USER u,
		orders o
	WHERE
		o.user_id = u.id;

</select>


    在Usermapper.java 中添加接口方法:
        public List<User> findUserOrders();
    
    测试类
   
    //查询用户订单--一对多映射
	@Test
	public void testFindUserOrders(){
		SqlSession sqlSession = sqlSessionFactory.openSession();
		UserMapper mapper = sqlSession.getMapper(UserMapper.class);
		List<User> list = mapper.findUserOrders();
		for (User user : list) {
			System.out.println("用户===="+user);
			for (Orders orders : user.getOrdersList()) {
				System.out.println("订单===="+orders);
			}
			
		}
	}


延迟加载

级联的优势是能够快速的获取数据,比如学生和学生信息,这往往是常用的信息,这个级联是必要的.多层级联的时候,建议超过三层级联的时候,建议少用级联,因为这会导致sql特别复杂,不利于他人的理解和维护.另外一点就是,我们可能有时候并不需要获得所有的数据,这样的话,如果多层级联,可能就导致多执行几条SQL,导致性能下降.所以这时候可以考虑使用延迟加载.

延迟加载的意义在于:一开始并不取出级联数据,只有当使用它的时候,才发送sql到数据库查询.

在Mybatis中有2个全局延迟加载的参数:lazyLoadingEnabled和aggressiveLazyLoading.

lazyLoadingEnabled:是否开启延迟加载的功能;

aggressiveLazyLoading:是否采用层级加载策略;举例:假如我们有学生表,学生成绩表以及学生证表.而学生成绩表和学生证表在一个层级,当我们访问学生课程成绩的时候,默认情况下是系统采用层级加载策略,也就是说也会把学生证信息找出来,但这并不是我们需要的,这个时候aggressiveLazyLoading就可以用起来了.在配置文件中配置如下代码

<setting name="aggressiveLazyLoading" value="false"/>

当然,还有另外一种情况,局部需要即时加载,局部需要延迟加载.这个时候就使用到局部加载参数 fetchType;

我们可以在association和collection中配置属性fetchType,对应的属性值有lazy 和eager.默认是eager.一旦配置了全局变量后,又配置了局部变量,那么局部变量就会覆盖全局变量.如此.我们就可以灵活的配置,哪些需要即时加载,哪些要延迟加载.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值