一對一查詢和一對多查詢的SQL


數據庫表(如果沒有,自行創建)

 

這里主要關注user(用戶表)和orders(訂單表),兩張表之間的關系屬於一對多關系,即一個用戶可能對應多個訂單(在訂單表中添加uid外鍵,維持兩表關系)

user用戶表字段和結構

Field          Type          Collation        Null    Key     Default  Extra           Privileges                       Comment       
-------------  ------------  ---------------  ------  ------  -------  --------------  -------------------------------  --------------
id             int(11)       (NULL)           NO      PRI     (NULL)   auto_increment  select,insert,update,references                
user_name      varchar(32)   utf8_general_ci  NO              (NULL)                   select,insert,update,references  用戶名稱  
user_birthday  timestamp     (NULL)           YES             (NULL)                   select,insert,update,references  生日        
user_sex       char(1)       utf8_general_ci  YES             (NULL)                   select,insert,update,references  性別        
home_address   varchar(256)  utf8_general_ci  YES             (NULL)                   select,insert,update,references  地址 

orders訂單表字段和結構

Field      Type      Collation  Null    Key     Default  Extra           Privileges                       Comment  
---------  --------  ---------  ------  ------  -------  --------------  -------------------------------  ---------
id         int(11)   (NULL)     NO      PRI     (NULL)   auto_increment  select,insert,update,references           
uid        int(11)   (NULL)     YES     MUL     (NULL)                   select,insert,update,references           
ordertime  datetime  (NULL)     YES             (NULL)                   select,insert,update,references           
money      double    (NULL)     YES             (NULL)                   select,insert,update,references 

user用戶表對應的實體類

@Data
public class User implements Serializable {
    private static final long serialVersionUID = -6391149300294480283L;
    private Integer id;
    private String username;
    private Date birthday;
    private Character sex;
    private String homeAddress;
}

orders訂單表對應的實體類

@Data
public class Order implements Serializable {
    private static final long serialVersionUID = 4708094005499936459L;
    private Integer id;
    private Integer uid;//外鍵,指向用戶表
    private Date orderTime;
    private Double money;
}

一對一查詢SQL(多對一其實就是一對一)

需求:查詢所有的訂單列表信息,同時查詢出訂單所屬的用戶信息

分析:訂單對應用戶,即一對一的關系,我們使用左外連接(LEFT JOIN... 主表.主鍵=從表.從鍵).既然是查詢所有的訂單信息,所以訂單表是左表,那么用戶表就是右表

一對一查詢使用的標簽:<association>

Mapper.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="com.mybatisplus.mapper.Mapper">
  
    <resultMap id="orderMap" type="com.mybatisplus.pojo.Order">
        <id column="id" property="id"></id>
        <result column="ordertime" property="orderTime"></result>
        <result column="money" property="money"></result>
        <association property="user" javaType="com.mybatisplus.pojo.User">
            <id column="id" property="id"></id>
            <result column="user_name" property="username"></result>
            <result column="user_birthday" property="birthday"></result>
            <result column="user_sex" property="sex"></result>
            <result column="home_address" property="homeAddress"></result>
        </association>
    </resultMap>

    <select id="selectOrderWithUser" resultMap="orderMap">
        SELECT o.id , o.ordertime , o.money , u.user_name , u.user_sex from `orders` o left join `user` u on u.id = o.uid
    </select>
</mapper>

如果你的實體類也和我上面的一樣,那么你會發現<association property="user">中的user顯示的是紅色.這表示有錯誤.測試結果也不會返回正確的信息.

請注意:如果你的sql也是這么寫的,我們需要在order實體類中,添加User類型的變量,這樣才能將User和order關聯在一起.

@Data
public class Order implements Serializable {
    private static final long serialVersionUID = 4708094005499936459L;
    private Integer id;
    private Integer uid;//外鍵,指向用戶表
    private Date orderTime;
    private Double money;
    private User user; 

修改Order實體類后,發現<association property="user">中的user顯示正常,再次測試成功!

一對多查詢SQL

需求:查詢所有的用戶,同時查詢出每個用戶所屬的所有訂單信息

分析:用戶對應訂單,即一對多的關系,查詢所有的用戶,即用戶表在左,訂單表在右

一對多查詢使用的標簽:<collection>

Mapper.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="com.mybatisplus.mapper.Mapper">
   
    <resultMap id="userMap" type="com.mybatisplus.pojo.User">
        <id column="id" property="id"></id>
        <result column="user_name" property="username"></result>
        <result column="user_birthday" property="birthday"></result>
        <result column="user_sex" property="sex"></result>
        <result column="home_address" property="homeAddress"></result>
        <collection property="orderList" ofType="com.mybatisplus.pojo.Order">
            <id column="id" property="id"></id>
            <result column="ordertime" property="orderTime"></result>
            <result column="money" property="money"></result>
        </collection>
    </resultMap>
  
    <select id="selectUserWithOrder" resultMap="userMap">
        SELECT u.user_name , u.user_birthday , u.user_sex , u.home_address , o.ordertime , o.money FROM `user` u LEFT JOIN `orders` o ON U.id = o.uid
    </select>
</mapper>

同樣的,如果你的User實體類也是和我上面定義的一樣,會發現<collection property="orderList">中的orderList顯示紅色,原因便是在User實體類中沒有定義該屬性

我們需要在User類中添加集合屬性,集合中的對象就是Order

@Data
public class User implements Serializable {
    private static final long serialVersionUID = -6391149300294480283L;
    private Integer id;
    private String username;
    private Date birthday;
    private Character sex;
    private String homeAddress;
    private List<Order> orderList;
}

修改后xml中不再報錯,查詢結果也成功返回.

總結:

一對一查詢使用的標簽:<association>

一對多查詢使用的標簽:<collection>

 追加():

對於三張表或三張表以上的多表查詢,sql語法分析主要分為兩點:

1.看你要查詢的數據都有哪些?

如果你所要查找的數據只存在於一張表中,那么只需要在mapper.xml中直接編寫sql語句即可,不需要將某個實體類引入到另一個實體類中作為其屬性,更不需要使用<association>或者<collection>關聯標簽

2.縷清sql語法所涉及的所有表之間的表關系

舉個例子:根據學生姓名查詢對應的班主任姓名,同時查詢出班主任所教授的課程名稱

(表關系:課程表對班主任表是一對一的關系,班主任表對學生表是一對多的關系)

<?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="com.mybatisplus.mapper.StudentMapper">
    <resultMap id="courseResultMap" type="com.mybatisplus.pojo.Course">
        <id column="c_id" property="cid"></id>
        <result column="c_name" property="cName"></result>
        <association property="teacher" javaType="com.mybatisplus.pojo.Teacher">
            <id column="t_id" property="tid"></id>
            <result column="t_name" property="tName"></result>
            <collection property="studentList" ofType="com.mybatisplus.pojo.Student">
                <id column="s_id" property="sid"></id>
                <result column="s_name" property="sName"></result>
                <result column="s_birth" property="sBirth"></result>
                <result column="s_sex" property="sSex"></result>
            </collection>
        </association>
    </resultMap>
    <select id="selectCourseAndTeacherByStudent" resultMap="courseResultMap">
    SELECT t.`t_name` , c.c_name FROM `course` c LEFT JOIN `teacher` t ON c.t_id = t.`t_id` LEFT JOIN `student` st ON t.`t_id` = st.`t_id` WHERE st.`s_name`=#{sName}
    </select>
</mapper>

考慮到最終要查詢到的數據是課程名稱和班主任姓名,我們需要在課程實體類中引入班主任屬性,因為是一對一的關系,所以使用<association>標簽;在班主任實體類中引入集合屬性(集合對象為學生),因為是一對多關系,所以使用<collection>標簽.

也就是說,<association>和<collection>標簽是可以互相嵌套使用的.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM