zoukankan      html  css  js  c++  java
  • 高级映射,查询缓存和与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>
  • 相关阅读:
    hdu 2647 Reward
    hdu 2094 产生冠军
    hdu 3342 Legal or Not
    hdu 1285 确定比赛名次
    hdu 3006 The Number of set
    hdu 1429 胜利大逃亡(续)
    UVA 146 ID Codes
    UVA 131 The Psychic Poker Player
    洛谷 P2491消防 解题报告
    洛谷 P2587 [ZJOI2008]泡泡堂 解题报告
  • 原文地址:https://www.cnblogs.com/softzrp/p/7147980.html
Copyright © 2011-2022 走看看