高级映射,查询缓存和与spring整合

一、高级映射

-------一对一

这里以订单查询为例,其中有一个外键为user_id,通过这个关联用户表。这里要实现的功能是这个两个表关联查询,得到订单的信息和部分user的信息。order表结构如下图:

1.这里先介绍一对一的关联查询。原始的order.java不能映射全部字段,需要新创建pojo。所以创建一个OrderCustom的pojo。

package entity;

public class OrderCustom extends Order{
    private String username;
    private String sex;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    

}

 2.后面就是按步骤创建OrderMaper和其对应的配置文件

因为此处在sqlmapConfig中打算使用批量类加载的方式,所以要把maper类和对应的配置文件放在同一个包中

OrderCustomerMapper .java的代码如下:

package mapper;

import java.util.List;

import entity.Order;
import entity.OrderCustom;

public interface OrderCustomerMapper {
    public List<OrderCustom> findOrder() throws Exception;

}

OrderCustomerMapper .xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--mapper代理开发,namespace要与mapper接口的全名地址一样-->

<mapper namespace="mapper.OrderCustomerMapper">
<resultMap id="orderResultMap" type="entity.Order">

    <select id="findOrder"  resultType="OrderCustom">
        SELECT o.*,u.username,u.sex from users u,orders o
        WHERE u.id=o.user_id
    </select>
    

</mapper>

以上都做好了后可以用Junit测试了:

测试代码

package mapper;

import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import entity.Order;
import entity.OrderCustom;

public class OrderTest {
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void setUp() throws Exception {
        String resource="SqlMapConfig.xml";
        InputStream stream=Resources.getResourceAsStream(resource);
        sqlSessionFactory=new SqlSessionFactoryBuilder().build(stream);
    }

    @Test
    public void testFindOrder() throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        OrderCustomerMapper ordermapper=sqlSession.getMapper(OrderCustomerMapper.class);
        List<OrderCustom> orderCustom=ordermapper.findOrder();
        sqlSession.close();
        
    }

        
    }

}

以上是用的resultType方式返回的结果集,其实还有resultMap的方式返回结果集。下面介绍如何使用resultMap来实现。

1.resultMap是不需要再创建一个OrderCustom的pojo的,只需要在Order类中加一个User类定义的user属性即可,并加上这个属性的get set方法。

然后在OrderCustomerMapper .xml中添加resultMap标签映射,添加后的OrderCustomerMapper .xml如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--mapper代理开发,namespace要与mapper接口的全名地址一样-->

<mapper namespace="mapper.OrderCustomerMapper">
<resultMap id="orderResultMap" type="entity.Order">
<!-- 配置映射的订单信息 -->
    <id column="id" property="id"/>
    <result column="user_id" property="user_id"/>
    <result column="createTime" property="createTime"/>
    <result column="note" property="note"/>
    <!-- 配置映射的关联用户信息 -->
    
    <!-- 关联查询出的一个对象 -->
    
    <!-- property:将关联查询的用户信息映射到哪个属性中去 -->
    <association property="user" javaType="entity.users">
        <id column="user_id" property="id"/>
        <result column="username" property="username"/>
        <result column="sex" property="sex"/>
        
    </association>
     

</resultMap>

    <select id="findOrder"  resultType="OrderCustom">
        SELECT o.*,u.username,u.sex from users u,orders o
        WHERE u.id=o.user_id
    </select>
    <select id="findOrderResultMap"  resultMap="orderResultMap">
        SELECT o.*,u.username,u.sex from users u,orders o
        WHERE u.id=o.user_id
    </select>
    

</mapper>

2.在OrderCustomerMapper 中添加一个接口来测试这个用resultMap

public List<Order> findOrderResultMap() throws Exception;

3.测试

@Test
    public void testFindOrderResltMap() throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        OrderCustomerMapper ordermapper=sqlSession.getMapper(OrderCustomerMapper.class);
        List<Order> orderCustom=ordermapper.findOrderResultMap();
        sqlSession.close();
        
    }

以上就介绍完了两种方式的一对一查询关联的使用,可以看出resultType的方式使用起来更简单,一般使用这个。当有某种特殊的需求不得不使用resultMap时才用这个。

一对多的查询:

查询订单及订单明细的方法。

1.在mapper.xml中添加:

<select id="findOrderAndDetail"  resultMap="orderAndItemDetail">
        SELECT o.*,u.username,u.sex,od.id as odrderdetai_id,od.item_id,od.order_id from users u,orders o,orderdetail od
        WHERE u.id=o.user_id AND o.id=od.order_id
    </select>

<resultMap id="orderAndItemDetail" type="entity.Order" extends="orderResultMap">

    <!-- 因为一个订单对应多个订单详细,所以使用collection -->
     <collection property="orderDetail" ofType="entity.OrderDetail">
         <id column="odrderdetai_id" property="id"/>
         <result column="order_id" property="order_id"/>
         <result column="item_id" property="item_id"/>
     </collection>

</resultMap>

2.在mapper.java接口中添加方法:

public List<Order> findOrderAndDetail() throws Exception;

3.测试

@Test
    public void testFindOrderAndDetail() throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        OrderCustomerMapper ordermapper=sqlSession.getMapper(OrderCustomerMapper.class);
        List<Order> orderCustom=ordermapper.findOrderAndDetail();
        sqlSession.close();
        
    }

多对多的查询:

   多对多的映射方式与一对多的映射方式基本相同,它是一对多的一种情况。例如一个用户和商品类型就是多对多的,一个用户可以买多种商品,一个商品可以被多个用户购买。在User类中创建一个属性orderList<Order>,Oder表中加一个

orderDetailList<OrderItem>属性,OrderItem表中增加一个属性item,这是类间的关系。那么使用ResultMap的时候,要在collection中再套着collection。

二、延迟加载

1.什么是延迟加载

resultMap中的association和collection具有延迟加载的属性

先从单标查询,需要时再从关联表中查询,

2.使用association实现延迟加载

1)mapper.xml中需要两个statement:

a只查询订单信息:  select * from orders  在查询订单的statement中使用association去延迟加载下面的statement

在association中有select和column连个属性。

select:指定需要延迟加载的statement的ID(根据user_id查询user的statement),如果要找的statement不在本mapper中,需要在前面加上namespace

column:订单信息中关联用户信息查询的列,是user_id。

b关联查询用户信息:通过以上查询到的user_id去关联查询用户信息

3.延迟加载配置

mybatis默认是关闭延迟加载的,需要在SqlMapConfig.xml中setting中配置

<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLasyLoading" value="false">
</settings>
原文地址:https://www.cnblogs.com/softzrp/p/7147980.html