MyBatis 關聯查詢的實現:一對多


有2個實體:用戶、訂單,一個用戶可以擁有多個訂單,同時這多個訂單屬於一個用戶,即一對多。

 

user_tb:

 

 

order_tb:

在“多”的一方(order)添加“一”的一方(user)的主鍵(user_id)作為外鍵。

 

 


 

 

使用嵌套結果

(1)給2個實體都編寫pojo類,需要在“一”的一方寫個List來關聯“多”的一方

package com.chy.pojo;

public class Order {
    private Integer no;
    private Integer userId;
    private Integer goodsId;
    private Integer goodsAmount;

    public Integer getNo() {
        return no;
    }

    public void setNo(Integer no) {
        this.no = no;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public Integer getGoodsId() {
        return goodsId;
    }

    public void setGoodsId(Integer goodsId) {
        this.goodsId = goodsId;
    }

    public Integer getGoodsAmount() {
        return goodsAmount;
    }

    public void setGoodsAmount(Integer goodsAmount) {
        this.goodsAmount = goodsAmount;
    }

    @Override
    public String toString() {
        return "Order{" +
                "no=" + no +
                ", userId=" + userId +
                ", goodsId=" + goodsId +
                ", goodsAmount=" + goodsAmount +
                '}';
    }
}

 

package com.chy.pojo;

import java.util.List;

public class User {
    private Integer id;
    private String username;
    private String password;
    private String tel;
    private String address;
    private List<Order> orderList;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public List<Order> getOrderList() {
        return orderList;
    }

    public void setOrderList(List<Order> orderList) {
        this.orderList = orderList;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", tel='" + tel + '\'' +
                ", address='" + address + '\'' +
                ", orderList=" + orderList +
                '}';
    }
}

toString()只是為了方便測試、調試,后期可以去掉。

 

 

(2)給“一”的一方寫Mapper接口、xml映射文件

package com.chy.mapper;

import com.chy.pojo.User;

public interface UserMapper {
    public User queryUserById(Integer id);
}

 

<?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.chy.mapper.UserMapper">
    <select id="queryUserById" parameterType="integer" resultMap="userResultWithOrder">
        SELECT user_tb.*,order_tb.* FROM user_tb,order_tb WHERE user_tb.id=#{id} AND order_tb.user_id=user_tb.id
     </select>
    <resultMap id="userResultWithOrder" type="user">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <result property="tel" column="tel"/>
        <result property="address" column="address"/>
        <collection property="orderList" ofType="order">
            <id property="no" column="no"/>
       <result property="userId" column="user_id" /> <result property="goodsId" column="goods_id" /> <result property="goodsAmount" column="goods_amount" /> </collection>
</resultMap> </mapper>

因為關聯的是集合(List),所以用<collection>。

  • property指定表示關聯對象的成員變量名
  • ofType指定返回的數據類型,注意不是list。
  • 子元素<id>、<result>配置關聯對象的映射。

 

所謂關聯查詢,是查詢結果中同時包含雙方(2張表)的多個字段,

如果只查詢一張表的字段,比如說只查詢某個用戶的訂單,不查詢此用戶本身的信息,直接根據外鍵user_id查order_tb表,不需要查user_tb,不必使用關聯查詢,寫個OrderMapper接口、OrderMapper.xml就ok。

 

 

(3)使用

package com.chy.utils;

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 java.io.IOException;
import java.io.InputStream;

public class MyBatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

 

package com.chy.test;

import com.chy.mapper.UserMapper;
import com.chy.pojo.User;
import com.chy.utils.MyBatisUtils;
import org.apache.ibatis.session.*;

public class Test {
    public static void main(String[] args) {
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.queryUserById(1);
        System.out.println(user);
        sqlSession.close();
    }
}

 

 


 

 

使用嵌套查詢

與嵌套結果大體相同,不同的只有第二步:

(二)給雙方都編寫Mapper接口、映射文件

package com.chy.mapper;

import com.chy.pojo.Order;

public interface OrderMapper {
    //根據orderId查詢訂單信息
    public Order queryOrderByUserId(Integer userId);
}
<?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.chy.mapper.OrderMapper">
    <select id="queryOrderByUserId" parameterType="integer" resultMap="orderMap">
        SELECT * FROM order_tb WHERE user_id=#{id}
    </select>
    <resultMap id="orderMap" type="order">
        <id property="no" column="no"/>
        <result property="userId" column="user_id"/>
        <result property="goodsId" column="goods_id"/>
        <result property="goodsAmount" column="goods_amount"/>
    </resultMap>
</mapper>

 

 

package com.chy.mapper;

import com.chy.pojo.User;

public interface UserMapper {
    public User queryUserById(Integer id);
}
<?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.chy.mapper.UserMapper">
    <select id="queryUserById" parameterType="integer" resultMap="userResultWithOrder">
        SELECT * FROM user_tb WHERE id=#{id}
     </select>
    <resultMap id="userResultWithOrder" type="user">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <result property="tel" column="tel"/>
        <result property="address" column="address"/>
        <collection property="orderList" column="id" ofType="order" select="com.chy.mapper.OrderMapper.queryOrderByUserId"/>
    </resultMap>
</mapper>

column指定向子查詢傳遞的參數是當前表的哪一列。

 

 


 

 

<resultMap>中的映射問題

我在<resultMap>中使用了子元素<id>、<result>配置了所有的表字段——pojo類屬性之間的映射,

 

其實只要表字段、pojo類屬性的名稱一致,就不必配置,比如

<resultMap id="userResultWithOrder" type="user">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <result property="tel" column="tel"/>
        <result property="address" column="address"/>
        <collection property="orderList" column="id" ofType="order" select="com.chy.mapper.OrderMapper.queryOrderByUserId"/>
    </resultMap>

紅色部分完全可以省略,因為默認的映射就是pojo類屬性、表字段名稱一致。

 

 

如果部分不一致,只需配置不一致的部分,比如只有用戶id的不一致:

<resultMap id="userResultWithOrder" type="user">
        <id property="id" column="user_id"/>
        <collection property="orderList" column="id" ofType="order" select="com.chy.mapper.OrderMapper.queryOrderByUserId"/>
    </resultMap>


免責聲明!

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



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