zoukankan      html  css  js  c++  java
  • Mybatis关联查询

    本节内容:

    • 商品订单数据模型
    • 一对一查询
    • 一对多查询

    一、商品订单数据模型

    二、一对一查询

    需求:查询所有订单信息,关联查询下单用户信息。

    【注意】:因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单。

    sql语句:

    SELECT
    	o.id,
    	o.user_id userId,
    	o.number,
    	o.createtime,
    	o.note,
    	u.username,
    	u.address
    FROM
    	`orders` o
    LEFT JOIN `user` u ON o.user_id = u.id
    

    1. 方法一:使用resultType

    使用resultType,改造订单pojo类,此pojo类中包括了订单信息和用户信息。这样返回对象的时候,mybatis自动把用户信息也注入进来了。

    (1)改造pojo类

    新建一个OrderUser类继承Order类,这样OrderUser类包括了Order类的所有字段,只需要定义用户的信息字段即可,如下:

    package com.wisedu.mybatis.pojo;
    
    /**
     * Created by jkzhao on 12/27/17.
     */
    public class OrderUser extends Orders {
        private String username;
        private String address;
    }

    (2)Mapper接口

    在OrderMapper.java添加方法如下:

    List<OrderUser> queryOrderUser();
    

    (3)OrderMapper.xml

        <!-- 查询订单,同时包含用户数据 -->
        <select id="queryOrderUser" resultType="orderUser">
            SELECT
            o.id,
            o.user_id
            userId,
            o.number,
            o.createtime,
            o.note,
            u.username,
            u.address
            FROM
            `orders` o
            LEFT JOIN `user` u ON o.user_id = u.id
        </select>

    (4)测试方法

        @Test
        public void fun2() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
    
            // 获取sqlSession,和spring整合后由spring管理
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            //SqlSEssion会帮我生成一个实现类  (需要我们给接口,它帮我们生成实现类,返回给我们的还是接口)
            OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
    
            List<OrderUser> list = orderMapper.queryOrderUser();
            for (OrderUser o: list){
                System.out.println(o);
            }
    
            // 和spring整合后由spring管理
            sqlSession.close();
    
        }

    测试时打个断点,截图如下:

    【小结】:定义专门的pojo类作为输出类型,其中定义了sql查询结果集所有的字段。此方法较为简单,企业中使用普遍。

    2. 方法二:使用resultMap

    使用resultMap,定义专门的resultMap用于映射一对一查询结果。

    (1) 改造pojo类

    在Orders类中加入User属性,user属性中用于存储关联查询的用户信息,因为订单关联查询用户是一对一关系,所以这里使用单个User对象存储关联查询的用户信息。

    改造Orders如下:

    public class Orders implements Serializable{
    	private static final long serialVersionUID = 1L;
    
    	private Integer id;
    
            private Integer userId;
    
            private String number;
    
            private Date createtime;
    
            private String note;
    
            //附加对象 用户对象
            private User user;
    

      

    (2)Mapper接口

    在UserMapper.java添加方法如下:

        //关联查询:一对一 (以订单为中心关联用户)
        List<Orders> queryOrders();

    (3)Mapper.xml

    这里resultMap指定orderUserResultMap,如下:

        <!-- ====================== 关联查询:一对一 =================== -->
        <resultMap type="orders" id="orderUserResultMap"><!-- 关联查询时,属性和列名一样的也得写出来-->
            <id property="id" column="id" />
            <result property="userId" column="user_id" />
            <result property="number" column="number" />
            <result property="createtime" column="createtime" />
            <result property="note" column="note" />
    
            <!-- association :配置一对一属性 -->
            <!-- property:order里面的User属性名 -->
            <!-- javaType:属性类型 -->
            <association property="user" javaType="user"> <!--user对象映射,想要拿到哪些属性值就要在下面写出来-->
                <!-- id:声明主键,表示user_id是关联查询对象的唯一标识-->
                <id property="id" column="user_id" />
                <result property="username" column="username" />
                <result property="address" column="address" />
            </association>
        </resultMap>

    (4)测试方法

            @Test
    	public void fun1() throws Exception {
    		//加载核心配置文件
    		String resource = "sqlMapConfig.xml";
    		InputStream in = Resources.getResourceAsStream(resource);
    		//创建SqlSessionFactory
    		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
    
                    // 获取sqlSession,和spring整合后由spring管理
    		SqlSession sqlSession = sqlSessionFactory.openSession();
    		
    		//SqlSEssion会帮我生成一个实现类  (需要我们给接口,它帮我们生成实现类,返回给我们的还是接口)
    		OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
    
    		List<Orders> order_list = orderMapper.queryOrders();
                    for (Orders order: order_list){
                        System.out.println(order);
                    }
    
                   // 和spring整合后由spring管理
                   sqlSession.close();
    
    	}

    执行测试方法,查看日志:

    DEBUG [main] - ==>  Preparing: SELECT o.id, o.user_id, o.number, o.createtime, o.note, u.username, u.address FROM `orders` o LEFT JOIN `user` u ON o.user_id = u.id 
    DEBUG [main] - ==> Parameters: 
    DEBUG [main] - <==      Total: 3
    Orders{id=3, userId=1, number='1000010', createtime=Wed Feb 04 13:22:35 CST 2015, note='null', user=User [id=1, username=王五, sex=null, birthday=null, address=null]}
    Orders{id=4, userId=1, number='1000011', createtime=Tue Feb 03 13:22:41 CST 2015, note='null', user=User [id=1, username=王五, sex=null, birthday=null, address=null]}
    Orders{id=5, userId=10, number='1000012', createtime=Thu Feb 12 16:13:23 CST 2015, note='null', user=User [id=10, username=张三, sex=null, birthday=null, address=北京市]}
    

    三、一对多查询

    案例:查询所有用户信息及用户关联的订单信息。

    用户信息和订单信息为一对多关系。

    sql语句:

    SELECT
    	u.id,
    	u.username,
    	u.birthday,
    	u.sex,
    	u.address,
    	o.id oid,
    	o.number,
    	o.createtime,
    	o.note
    FROM
    	`user` u
    LEFT JOIN `orders` o ON u.id = o.user_id
    

    1. 修改pojo类

    在User类中加入List<Order> orders属性,如下图:

    public class User implements Serializable {
    
    	private static final long serialVersionUID = 1L;
    	private Integer id;
    	private String username;// 用户姓名
    	private String sex;// 性别
    	private Date birthday;// 生日
    	private String address;// 地址
    
    	//附加对象 List<Orders>
    	private List<Orders> ordersList;
            ...
    

    2. Mapper接口

    在OrderMapper.java接口中添加方法,如下:(在UserMapper.java接口中定义该方法也可以)

        //一对多关联查询
        List<User> queryUserOrder();
    

    3. Mapper.xml文件

    在OrderMapper.xml中编写sql语句,如下:

        <!-- ====================== 关联查询:一对多 =================== -->
        <resultMap type="user" id="userOrderResultMap">
            <id property="id" column="id" />
            <result property="username" column="username" />
            <result property="birthday" column="birthday" />
            <result property="sex" column="sex" />
            <result property="address" column="address" />
    
            <!-- 配置一对多的关系 -->
            <collection property="ordersList" javaType="list" ofType="orders"> <!--ordersList是附加在User.java文件中的属性名。ofType指定list集合每一个元素的类型-->
                <!-- 配置主键,是关联Order的唯一标识 -->
                <id property="id" column="oid" />
                <result property="number" column="number" />
                <result property="createtime" column="createtime" />
                <result property="note" column="note" />
            </collection>
        </resultMap>
    
        <!-- 一对多关联,查询订单同时查询该用户下的订单 -->
        <select id="queryUserOrder" resultMap="userOrderResultMap">
            SELECT
            u.id,
            u.username,
            u.birthday,
            u.sex,
            u.address,
            o.id oid,
            o.number,
            o.createtime,
            o.note
            FROM
            `user` u
            LEFT JOIN `orders` o ON u.id = o.user_id
        </select>
    

    4. 测试方法

        @Test
        public void fun3() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
    
            // 获取sqlSession,和spring整合后由spring管理
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            //SqlSEssion会帮我生成一个实现类  (需要我们给接口,它帮我们生成实现类,返回给我们的还是接口)
            OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
    
            List<User> list = orderMapper.queryUserOrder();
            for (User u: list){
                System.out.println(u);
            }
    
            // 和spring整合后由spring管理
            sqlSession.close();
    
        }

    在 System.out.println(u); 处打个断点,debug运行该方法,结果如下:

  • 相关阅读:
    C++ 容器元素的存储和获取
    【C++沉思录】代理类
    mysql 编码测试
    理解字符编码
    linux mount
    mysql delimiter
    mysql 求时间段平均值
    mysql Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
    PostgreSQL体系架构与内存结构
    PostgreSQL中的The Oversized-Attribute Storage Technique(TOAST:超大属性存储技术)
  • 原文地址:https://www.cnblogs.com/zhaojiankai/p/8126568.html
Copyright © 2011-2022 走看看