一对一查询

需求:

查询订单信息,关联查询创建订单的用户信息。

记住:用Mybatis开发的顺序就是

1.写sql语句

2.创建pojo类来完成映射

3.写Mapper.xml

4.写Mapper.java接口

---------------------------------------------------------------------------------------------------------------------------------------------------

我们知道Mybatis中mapper.xml中分为resultType和resultMap两种,这两种我们都讲:

一:先讲resultMap:

先给出案例结构:

cn.itcast.mybatis.po包下面的类(items,orderdetail,Orders,User)都是根据数据库的4张表创建的实体类。

1.我们先来分析一下怎么写sql语句:

写sql语句时要先根据需求确定查询的主表和查询的关联表:

根据“查询订单信息,关联查询创建订单的用户信息”  很明显,查询的主表是订单表,查询的关联是用户表。

关联查询使用内链接?还是外链接?由于orders表中有一个外键(user_id),通过外键关联查询用户表只能查询出一条记录,可以使用内链接。

sql如下:

SELECT

orders.*,

USER.username,

USER.sex,

USER.address

FROM

orders,

USER

WHERE orders.user_id = user.id

2.根据select(orders.*,USER.username,USER.sex,USER.address)语句 创建Pojo类

我们创建的pojo类要满足orders.*,USER.username,USER.sex,USER.address这些映射,很明显单纯依靠数据库的映射(Orders.java和User.java)不能满足,所以要新写一个类OrdersCustom.java。

如下:

package cn.itcast.mybatis.po;

import java.util.Date;

public class OrdersCustom  extends Orders{
    private String username;
    private String sex;
    private String address;
    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;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }

}

为什么这个类要继承Orders而不是继承User.java因为根据orders.*,USER.username,USER.sex,USER.address,很明显,要映射的数据是order表中的全部数据以及user

表中的username,sex,address这些数据,直接继承Order类的话就可以少定义一些属性,只要定义username,sex,address。就可以了。

3.写Mapper.xml和Mapper.java接口(放在同一个包下面,用接口的方式去加载)

OrderMapperCustom.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">
<!-- nanmespace:命名空间。 作用就是对sql进行分类话管理,理解Sal分离

注意:使用mapper代理方式,namespace有特殊重要的作用
-->

<mapper namespace="cn.itcast.mybatis.mapper.OrdersMapperCustom">

        <select id="findOrdersUser"  resultType="cn.itcast.mybatis.po.OrdersCustom">
        SELECT ORDERS.* ,
        user.`username`,
        user.`sex`,
        user.`address`
        FROM orderS,USER
         WHERE ORDERS.`user_id`=USER.`id`

    </select>

</mapper>

OrdersMapperCustom.java代码如下:

package cn.itcast.mybatis.mapper;

import java.util.List;

import cn.itcast.mybatis.po.OrdersCustom;

public interface OrdersMapperCustom {
    public List<OrdersCustom> findOrdersUser();

}

同时不要忘了在SqlMapConfig.xml。

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

    <!-- properties的配置必须写在typeAliases的上面 -->
    <properties resource="db.properties"></properties>

 <!-- 和spring整合后 environments配置将废除-->
    <environments default="development">
        <environment id="development">
        <!-- 使用jdbc事务管理-->
            <transactionManager type="JDBC" />
        <!-- 数据库连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
        </environment>
    </environments>

        <mappers>

           <!--  用mapper接口的方式加载-->
           <!--
           遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致
           且在一个目录中。
           当着这个规范的前提是:使用mapper代理方法。

            -->
            <mapper class="cn.itcast.mybatis.mapper.OrdersMapperCustom"/>

         </mappers>

</configuration>

4.编写测试代码Mybatis_mappertest.java:

package cn.itcast.mybatis.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
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 cn.itcast.mybatis.mapper.OrdersMapperCustom;
import cn.itcast.mybatis.mapper.userMapper;
import cn.itcast.mybatis.po.User;
import cn.itcast.mybatis.po.UserCustom;
import cn.itcast.mybatis.po.UserQueryVo;

public class Mybatis_mappertest {

    private SqlSessionFactory sqlSessionFactory;
    @Before
    public void setup() throws IOException
    {   String resource="SqlMapConfig.xml";
        InputStream inputStream= Resources.getResourceAsStream(resource);
        //主要是生成SqlsessionFactory。
        this.sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testMaper()
    {
        SqlSession sqlSession=null;

        sqlSession=sqlSessionFactory.openSession();
        //生成代理类
        OrdersMapperCustom orderMapper=sqlSession.getMapper(OrdersMapperCustom.class);

        orderMapper.findOrdersUser();

    }

}

运行结果:一切正常。

二:再讲resultMap(重点):

resultMap映射的思想:

使用resultMap将查询结果中的订单信息映射到Orders对象中,在orders类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中。也就是说查出来的user信息都要映射在orders中新开的一个user属性中。

还是按照第一sql语句,第二pojo类,第三mapper.xml,mapper.java接口这种顺序来写。

1.sql语句:和之前的resulrType的sql语句一样:

SELECT

orders.*,

USER.username,

USER.sex,

USER.address

FROM

orders,

USER

WHERE orders.user_id = user.id

2.写pojo类:在原来的Orders.java中新增一个User属性:

User类:

package cn.itcast.mybatis.po;

import java.util.Date;
//对应数据库中的user表
public class User {
private int id;//对应数据库中主键
private String username;//对应数据库中用户的名称
private Date birthday;//对应数据库中的生日
private String sex;//性别
private String address;//地址
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getUsername() {
    return username;
}
public void setUsername(String username) {
    this.username = username;
}
public Date getBirthday() {
    return birthday;
}
public void setBirthday(Date birthday) {
    this.birthday = birthday;
}
public String getSex() {
    return sex;
}
public void setSex(String sex) {
    this.sex = sex;
}
public String getAddress() {
    return address;
}
public void setAddress(String address) {
    this.address = address;
}

}

Orders.java类:

package cn.itcast.mybatis.po;

import java.util.Date;

public class Orders {
private Integer id;
private Integer user_id;
private String number;
private Date createtime;
private String note;
//新增了一个User属性,为了保存查询得到的关联的User表的信息
private User user;
public User getUser() {
    return user;
}
public void setUser(User user) {
    this.user = user;
}
public Integer getId() {
    return id;
}
public void setId(Integer id) {
    this.id = id;
}
public Integer getUser_id() {
    return user_id;
}
public void setUser_id(Integer user_id) {
    this.user_id = user_id;
}
public String getNumber() {
    return number;
}
public void setNumber(String number) {
    this.number = number;
}
public Date getCreatetime() {
    return createtime;
}
public void setCreatetime(Date createtime) {
    this.createtime = createtime;
}
public String getNote() {
    return note;
}
public void setNote(String note) {
    this.note = note;
}

}

3.写mapper.xml和mapper.java接口

OrdersMapperCustom.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">
<!-- nanmespace:命名空间。 作用就是对sql进行分类话管理,理解Sal分离

注意:使用mapper代理方式,namespace有特殊重要的作用
-->

<mapper namespace="cn.itcast.mybatis.mapper.OrdersMapperCustom">

        <!-- 配置映射的订单信息 -->
        <!-- id:指定查询列中的唯 一标识,订单信息的中的唯 一标识,如果有多个列组成唯一标识,配置多个id
          就是说id要能唯一的标识出数据库中的Order表。
            column:订单信息的唯 一标识 列
            property:订单信息的唯 一标识 列所映射到Orders中哪个属性

          -->

<resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap">
   <!-- 这一行的作用是要能唯一的识别出order表的,那么很明显是主键id -->
    <id column="id" property="id"/>

    <!-- 以下的几行result column就是表中的字段   property就是对应到相应pojo类中的属性-->
    <result column="user_id" property="user_id"/>
    <result column="number" property="number"/>
    <result column="createtime" property="createtime"/>
    <result column="note"  property="note"/>

        <!-- 配置映射的关联的用户信息 -->
        <!-- association:用于映射关联查询单个对象的信息
        property:要将关联查询的用户信息映射到Orders中哪个属性
         -->
    <!-- 下面的代码比较特殊,因为Order表是直接关联到user表,下面这么写的目的是把user表映射到Order类中
     <association property="user"这里的user指的是orders类中的user,对应的是cn.itcast.mybatis.po.User

     -->
    <association property="user" javaType="cn.itcast.mybatis.po.User">
       <!--
       <id column="user_id" property="id"/>这里的是user_id指的是order表中只有这个属性能表示唯一的user表
        -->
        <id column="user_id" property="id"/>

        <!-- 接下来的result  property什么的都是为了把user表中的字段能匹配到
        cn.itcast.mybatis.po.User这个类的属性中
        -->
           <result column="username" property="username"/>
          <result column="sex" property="sex"/>
          <result column="address" property="address"/>
        </association>

</resultMap>

        <select id="findOrdersUser"  resultType="cn.itcast.mybatis.po.OrdersCustom">
        SELECT ORDERS.* ,
        user.`username`,
        user.`sex`,
        user.`address`
        FROM orderS,USER
         WHERE ORDERS.`user_id`=USER.`id`

    </select>

      <select id="findOrdersUseResultMap"  resultMap="OrdersUserResultMap">
        SELECT ORDERS.* ,
        user.`username`,
        user.`sex`,
        user.`address`
        FROM orderS,USER
         WHERE ORDERS.`user_id`=USER.`id`

    </select>
</mapper>

OrdersMapperCustom.java接口

package cn.itcast.mybatis.mapper;

import java.util.List;

import cn.itcast.mybatis.po.Orders;
import cn.itcast.mybatis.po.OrdersCustom;

public interface OrdersMapperCustom {
//这里的的函数名字要和OrdersMapperCustom.xml中的id一模一样
    public List<OrdersCustom> findOrdersUser();
    public List<Orders> findOrdersUseResultMap();

}

Junit测试代码:

package cn.itcast.mybatis.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
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 cn.itcast.mybatis.mapper.OrdersMapperCustom;
import cn.itcast.mybatis.mapper.userMapper;
import cn.itcast.mybatis.po.Orders;
import cn.itcast.mybatis.po.User;
import cn.itcast.mybatis.po.UserCustom;
import cn.itcast.mybatis.po.UserQueryVo;

public class Mybatis_mappertest {

    private SqlSessionFactory sqlSessionFactory;
    @Before
    public void setup() throws IOException
    {   String resource="SqlMapConfig.xml";
        InputStream inputStream= Resources.getResourceAsStream(resource);
        //主要是生成SqlsessionFactory。
        this.sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testMaper()
    {
        SqlSession sqlSession=null;

        sqlSession=sqlSessionFactory.openSession();
        //生成代理类
        OrdersMapperCustom orderMapper=sqlSession.getMapper(OrdersMapperCustom.class);
    //创建包装对象,设置查询条件
        //orderMapper.findOrdersUser();

       @SuppressWarnings("unused")
    List<Orders>list=orderMapper.findOrdersUseResultMap();

    }

}

运行结果:一切正常。

resultType和resultMap实现一对一查询小结

实现一对一查询:

resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。

如果没有查询结果的特殊要求建议使用resultType。

resultMap:需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中。

resultMap可以实现延迟加载,resultType无法实现延迟加载。

时间: 2024-10-13 00:17:28

一对一查询的相关文章

【MyBatis学习08】高级映射之一对一查询

从这一篇博文开始,将总结一下mybatis中的几个高级映射,即一对一.一对多.多对多查询,这篇先总结一下mybatis中的一对一查询. 为了模拟这些需求,事先要建立几个表,不同的表之间将对应上面提到的不同的映射,为此,我建立4个表,如下: DROP TABLE IF EXISTS `items`; DROP TABLE IF EXISTS `orders`; DROP TABLE IF EXISTS `user`; DROP TABLE IF EXISTS `orderdetail`; /*it

mybatis0202 一对一查询 resultType实现

一对一查询 查询订单信息和用户信息 创建po类 基础的单表的 po(数据库类)类:Items.java, Orderdetail.java, Orders.java, User.java 一对一查询映射的pojo(工具类,用于sql语句接收返回的对象) 创建pojo包括 订单信息和用户信息,resultType才可以完成映射. 创建OrderCustom作为自定义pojo,继承sql查询列多的po类. 接口:OrdersMapperCustom.java package cn.itcast.my

20Mybatis_订单商品数据模型_一对一查询——resultType和resultMap两种方式以及两种方式的总结

上一篇文章分析了数据模型,这篇文章就给出一个需求,这个需求是一对一查询,并完成这个需求. -------------------------------------------------------------------------------------------------------------------------------------------- 需求: 查询订单信息,关联查询创建订单的用户信息. 记住:用Mybatis开发的顺序就是 1.写sql语句 2.创建pojo类来

一对一查询(2)

需求: 查询订单信息,关联查询创建订单的用户信息. 记住:用Mybatis开发的顺序就是 1.写sql语句 2.创建pojo类来完成映射 3.写Mapper.xml 4.写Mapper.java接口 --------------------------------------------------------------------------------------------------------------------------------------------------- 我们

mybatis学习笔记(10)-一对一查询

mybatis学习笔记(10)-一对一查询 mybatis学习笔记10-一对一查询 resultType实现 resultMap实现 resultType和resultMap实现一对一查询小结 本文使用两种方式(resultType和resultMap)实现一对一查询,查询订单信息,关联查询创建订单的用户信息 resultType实现 sql语句 确定查询的主表:订单表 确定查询的关联表:用户表 关联查询使用内连接?还是外连接? 因为orders表中有一个外键(user_id),通过外键关联查询

MyBatis Review——使用resultType和resultMap实现一对一查询

例如: 查询订单信息,关联查询创建订单的用户信息. 查询语句: SELECT orders.*, USER .username ,USER .sex, USER .address FROM orders, USER WHERE orders.user_id = USER .id 查询结果: 1,使用resultType接受输出结果 用户信息: 订单信息: 用于接收结果的pojo: 为了将查询结果映射到pojo中,pojo必须包括所有查询列名.在原始orders对象不能接受所有查询字段的时候,定义

Mybatis实现一对一查询 对ResultType和ResultMap分析

实现一对一查询: ResultMap:使用ResultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加 列名对应的属性,即可完成映射. 如果没有查询结果的特殊要求建议使用ResultMap. ResultMap:需要单独定义ResultMap,实现有点麻烦,如果对查询结果又特殊要求,使用ResultMap 可以完成将关联查询映射pojo的属性中. (ResultMap可以实现延迟加载,而ResultMap无法实现延迟加载) 原文地址:https://www.cnblogs.c

第八节:mybatis关联查询之一对一查询

一对一也就是 A 表的一条记录对应 B 表的一条记录,下面的测试数据中,从employee 表来看,一个员工对应一个部门,是一对一关系,如果从部门角度来看,则是一对多的关系,一个部门对应多个员工,本节主要研究一对一的关系. 1,数据表建立 新建数据表department,有两个字段,插入两条数据如下: id dept_name 1 CIA 2 FSB 新建数据表employee,有三个字段,其中dept_id是外键,关联department表的主键id.插入数据如下: id last_name

DJango一对一查询,ORM 列类型及列参数

一对一查询 表的创建 # 通过 OneToOneField 创建一对一的关系 from django.db import models # Create your models here. class StaffInfo(models.Model): name = models.CharField(max_length=32, null=True) age = models.CharField(max_length=32, null=True) class Salary(models.Model