1. 程式人生 > >MyBatis學習(七)

MyBatis學習(七)

ppi before 多個 使用 day col util == and

本課程對應視頻教程:http://edu.51cto.com/sd/3ec2c

1、高級查詢

MyBatis作為一個ORM框架,也對sql的高級查詢做了支持,這裏以用戶,訂單,訂單詳情,商品為例講解

案例說明:此案例的業務關系是用戶、訂單、訂單詳情、商品之間的關系、其中

一個訂單只能屬於一個人

一個訂單可以有多個訂單詳情

一個訂單詳情中包含一個商品信息

他們的關系是:

訂單和人是一對一的關系

訂單和訂單詳情是一對多的關系

訂單和商品是多對多的關系

1.1、數據模型分析

技術分享圖片

1.2、需求分析

一對一查詢:查詢訂單,並且查詢出下單人信息

一對多查詢:查詢訂單,查詢出下單人信息並且查詢出訂單詳情

多對多查詢:查詢訂單,查詢出訂單人信息並且查詢出訂單詳情中的商品數據

1.3、一對一查詢

1.3.1、方式一

將查詢出來字段封裝到一個新的類中,讓這個類的屬性包含所有查詢出來的字段,

它的弊端在於,我的pojo類會急劇增加

先定義一個實體類

package cn.org.kingdom.pojo;
public class OrderUser extends User {
    private int oid;
    private int userId;
    private String orderNum;
    public int getOid() {
        return oid;
    }
    public void setOid(int oid) {
        this.oid = oid;
    }
    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getOrderNum() {
        return orderNum;
    }
    public void setOrderNum(String orderNum) {
        this.orderNum = orderNum;
    }
    @Override
    public String toString() {
        return "OrderUser [oid=" + oid + ", userId=" + userId + ", orderNum="
                + orderNum + ", userid=" + userid + ", userName=" + userName
                + ", pwd=" + pwd + ", age=" + age + ", sex=" + sex
                + ", birthday=" + birthday + "]";
    }
}

定義數據接口

public List<OrderUser> one2one(@Param("orderNum")String orderNum);

配置mapper.xml文件(OrderMapper.xml)

<select id="one2one" resultType="OrderUser">
        select tb_user.*,tb_order.* from tb_user,tb_order
        where tb_user.userid = tb_order.user_id and order_number=#{orderNum}
  </select>

測試類

package cn.org.kingdom.test;
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.After;
import org.junit.Before;
import org.junit.Test;
import cn.org.kingdom.mapper.OrderMapper;
import cn.org.kingdom.pojo.OrderUser;
import cn.org.kingdom.pojo.User;
public class MyBatisTest03 {
    SqlSessionFactory sqlSessionFactory = null ;
    SqlSession sqlSession = null ; 
    OrderMapper  orderMapper = null ;
    @Before
    public void setUp() throws Exception {
        //加載資源
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        sqlSession  = sqlSessionFactory.openSession();
        orderMapper = sqlSession.getMapper(OrderMapper.class);
    }

    @After
    public void tearDown() throws Exception {
        //關閉
        sqlSession.close();
    }
    @Test
    public void testone2one()throws Exception{
        List<OrderUser> list = orderMapper.one2one("20180810001");
        for (OrderUser u : list) {
            System.out.println(u);
        }
    }
}

生成的日誌

DEBUG - Opening JDBC Connection
DEBUG - Created connection 665964512.
DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@27b1cfe0]
DEBUG - ==>  Preparing: select tb_user.*,tb_order.* from tb_user,tb_order where tb_user.userid = tb_order.user_id and order_number=? 
DEBUG - ==> Parameters: 20180810001(String)
DEBUG - <==      Total: 1
OrderUser [oid=1, userId=0, orderNumber=20180810001, userid=2, userName=阿柯, pwd=123456, age=10, sex=女, birthday=Tue Aug 14 13:45:34 CST 2018]
DEBUG - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@27b1cfe0]
DEBUG - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@27b1cfe0]
DEBUG - Returned connection 665964512 to pool.

1.3.2、采用面向對象的思維

讓一個類持有另外一個類的屬性

定義一個Order類

package cn.org.kingdom.pojo;
import java.io.Serializable;
public class Order implements Serializable {
    private int oid;
    private int userId;
    private String orderNumber;
    private User user ;
    public int getOid() {
        return oid;
    }
    public void setOid(int oid) {
        this.oid = oid;
    }
    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getOrderNumber() {
        return orderNumber;
    }
    public void setOrderNumber(String orderNumber) {
        this.orderNumber = orderNumber;
    }
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    @Override
    public String toString() {
        return "Order [oid=" + oid + ", userId=" + userId + ", orderNumber="
                + orderNumber + ", user=" + user + "]";
    } 
}

mapper.xml文件

<resultMap type="Order" id="OrderResultMap" autoMapping="true">
        <id column="oid" property="oid"/>
        <!-- 
            關聯的對象屬性
            property:屬性名
            javaType:這個屬性屬於什麽類型
            autoMapping:自動映射
         -->
        <association property="user" javaType="User" autoMapping="true">
            <id column="userid" property="userid"/>
        </association>
  </resultMap>
  <select id="one2one2" resultMap="OrderResultMap">
        select tb_user.*,tb_order.* from tb_user,tb_order
        where tb_user.userid = tb_order.user_id and order_number=#{orderNum}
  </select>

測試類

@Test
    public void testone2one2()throws Exception{ 
        List<Order> list = orderMapper.one2one2("20180810001");
        for (Order u : list) {
            System.out.println(u);
        }
    }

日誌:

DEBUG - ==>  Preparing: select tb_user.*,tb_order.* from tb_user,tb_order where tb_user.userid = tb_order.user_id and order_number=? 
DEBUG - ==> Parameters: 20180810001(String)
DEBUG - <==      Total: 1
Order [oid=1, userId=2, orderNumber=20180810001, user=User [userid=2, userName=阿柯, pwd=123456, age=10, sex=女, birthday=Tue Aug 14 13:45:34 CST 2018]]
DEBUG - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@5bad7476]
DEBUG - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@5bad7476]
DEBUG - Returned connection 1538094198 to pool.

1.4、一對多查詢

一對多查詢:查詢訂單,查詢出下單人信息並且查詢出訂單詳情

sql

select tb_user.*,tb_order.*,tb_orderdetail.* 
from tb_user,tb_order,tb_orderdetail
where tb_user.userid = tb_order.user_id 
and tb_order.oid = tb_orderdetail.order_id
and order_number =‘20180810001‘

創建pojo類

package cn.org.kingdom.pojo;
import java.io.Serializable;
public class Detail  implements Serializable{
    private int detailId;
    private int orderId;
    private int productId;
    private double price;
    private String status;
    public Detail() {
        super();
    }
    public int getDetailId() {
        return detailId;
    }
    public void setDetailId(int detailId) {
        this.detailId = detailId;
    }
    public int getOrderId() {
        return orderId;
    }
    public void setOrderId(int orderId) {
        this.orderId = orderId;
    }
    public int getProductId() {
        return productId;
    }
    public void setProductId(int productId) {
        this.productId = productId;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public String getStatus() {
        return status;
    }
    public void setStatus(String status) {
        this.status = status;
    }
    @Override
    public String toString() {
        return "Detail [detailId=" + detailId + ", orderId=" + orderId
                + ", productId=" + productId + ", price=" + price + ", status="
                + status + "]";
    }
}

然後在Order中加入多的一方的引用

    private List<Detail> details ; 
    public List<Detail> getDetails() {
        return details;
    }
    public void setDetails(List<Detail> details) {
        this.details = details;
    }

mapper.xml文件

<resultMap type="Order" id="OrderResultMap2" autoMapping="true">
        <id column="oid" property="oid"/>
        <!-- 
            關聯的對象屬性
            property:屬性名
            javaType:這個屬性屬於什麽類型
            autoMapping:自動映射    
         -->
        <association property="user" javaType="User" autoMapping="true">
            <id column="userid" property="userid"/>
        </association>
        <!-- 
            配置多的一方使用collection這個節點
            property:集合的屬性名稱
            javaType:類型
            ofType:集合中元素的類型
         -->
        <collection property="details" javaType="list" ofType="Detail" autoMapping="true">
            <id column="detail_id" property="detailId"/>
        </collection>
  </resultMap>
  <select id = "one2many" resultMap="OrderResultMap2">
        select tb_user.*,tb_order.*,tb_orderdetail.* 
        from tb_user,tb_order,tb_orderdetail
        where tb_user.userid = tb_order.user_id 
        and tb_order.oid = tb_orderdetail.order_id
        and order_number =#{orderNum}
  </select>

測試類

public void testone2many()throws Exception{
        List<Order> list = orderMapper.one2many("20180810001");
        for (Order u : list) {
            System.out.println(u);
        }
}

日誌信息

DEBUG - Cache Hit Ratio [cn.org.kingdom.mapper.OrderMapper]: 0.0
DEBUG - Opening JDBC Connection
DEBUG - Created connection 15932635.
DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@f31cdb]
DEBUG - ==>  Preparing: select tb_user.*,tb_order.*,tb_orderdetail.* from tb_user,tb_order,tb_orderdetail where tb_user.userid = tb_order.user_id and tb_order.oid = tb_orderdetail.order_id and order_number =? 
DEBUG - ==> Parameters: 20180810001(String)
DEBUG - <==      Total: 2
Order [oid=1, userId=2, orderNumber=20180810001, user=User [userid=2, userName=阿柯, pwd=123456, age=10, sex=女, birthday=Tue Aug 14 13:45:34 CST 2018], details=[Detail [detailId=1, orderId=1, productId=1, price=8888.0, status=1], Detail [detailId=2, orderId=1, productId=2, price=188.0, status=1]]]
DEBUG - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@f31cdb]
DEBUG - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@f31cdb]
DEBUG - Returned connection 15932635 to pool.

1.5、多對多

多對多查詢:查詢訂單,查詢出訂單人信息並且查詢出訂單詳情中的商品數據

sql語句分析

select tb_user.*,tb_order.*,tb_orderdetail.*,tb_product.*
from tb_user,tb_order,tb_orderdetail,tb_product
where tb_user.userid = tb_order.user_id 
and tb_order.oid = tb_orderdetail.order_id
and tb_orderdetail.product_id = tb_product.pid
and order_number =‘20180810001‘

接口方法定義

public List<Order> many2many(@Param("orderNum")String orderNum);

創建一個pojo類(Product)

package cn.org.kingdom.pojo;
public class Product implements Serializable {
    private int pid;
    private String pname ; 
    private double price ; 
    private String proDetail;
    public int getPid() {
        return pid;
    }
    public void setPid(int pid) {
        this.pid = pid;
    }
    public String getPname() {
        return pname;
    }
    public void setPname(String pname) {
        this.pname = pname;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public String getProDetail() {
        return proDetail;
    }
    public void setProDetail(String proDetail) {
        this.proDetail = proDetail;
    }
    @Override
    public String toString() {
        return "Product [pid=" + pid + ", pname=" + pname + ", price=" + price
                + ", proDetail=" + proDetail + "]";
    }
}

在detail類中加入一個Product類的引用

private Product product;
public Product getProduct() {
    return product;
}
public void setProduct(Product product) {
    this.product = product;
}

mapper.xml文件

<resultMap type="Order" id="OrderResultMap3" autoMapping="true">
        <id column="oid" property="oid"/>
        <!-- 
            關聯的對象屬性
            property:屬性名
            javaType:這個屬性屬於什麽類型
            autoMapping:自動映射
         -->
        <association property="user" javaType="User" autoMapping="true">
            <id column="userid" property="userid"/>
        </association>
        <!-- 
            配置多的一方使用collection這個節點
            property:集合的屬性名稱
            javaType:類型
            ofType:集合中元素的類型
         -->
        <collection property="details" javaType="list" ofType="Detail" autoMapping="true">
            <id column="detail_id" property="detailId"/>
            <association property="product" javaType="Product" autoMapping="true">
                <id column="pid" property="pid"/>
            </association>
        </collection>
  </resultMap>
  <select id = "many2many" resultMap="OrderResultMap3">
        select tb_user.*,tb_order.*,tb_orderdetail.*,tb_product.*
        from tb_user,tb_order,tb_orderdetail,tb_product
        where tb_user.userid = tb_order.user_id 
        and tb_order.oid = tb_orderdetail.order_id
        and tb_orderdetail.product_id = tb_product.pid
        and order_number =#{orderNum}
  </select>

測試類

@Test
    public void testmany2many()throws Exception{
        List<Order> list = orderMapper.many2many("20180810001");
        for (Order u : list) {
            System.out.println(u);
        }
    }

日誌

DEBUG - Opening JDBC Connection
DEBUG - Created connection 462907404.
DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@1b97680c]
DEBUG - ==>  Preparing: select tb_user.*,tb_order.*,tb_orderdetail.*,tb_product.* from tb_user,tb_order,tb_orderdetail,tb_product where tb_user.userid = tb_order.user_id and tb_order.oid = tb_orderdetail.order_id and tb_orderdetail.product_id = tb_product.pid and order_number =? 
DEBUG - ==> Parameters: 20180810001(String)
DEBUG - <==      Total: 2
Order [oid=1, userId=2, orderNumber=20180810001, user=User [userid=2, userName=阿柯, pwd=123456, age=10, sex=女, birthday=Tue Aug 14 13:45:34 CST 2018], details=[Detail [detailId=1, orderId=1, productId=1, price=8888.0, status=1, product=Product [pid=1, pname=iphone8, price=8888.0, proDetail=蘋果公司最新產品]], Detail [detailId=2, orderId=1, productId=2, price=188.0, status=1, product=Product [pid=2, pname=冰峰戰神, price=188.0, proDetail=關羽騷氣皮膚]]]]
DEBUG - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@1b97680c]
DEBUG - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@1b97680c]
DEBUG - Returned connection 462907404 to pool.

1.6、resultMap的繼承

resultMap元素可以通過繼承機制來減少冗余

<resultMap type="Order" id="OrderResultMap" autoMapping="true">
        <id column="oid" property="oid"/>
        <!-- 
            關聯的對象屬性
            property:屬性名
            javaType:這個屬性屬於什麽類型
            autoMapping:自動映射
         -->
        <association property="user" javaType="User" autoMapping="true">
            <id column="userid" property="userid"/>
        </association>
  </resultMap>

  <resultMap type="Order" id="OrderResultMap2" autoMapping="true" extends="OrderResultMap">
        <!-- 
            配置多的一方使用collection這個節點
            property:集合的屬性名稱
            javaType:類型
            ofType:集合中元素的類型
         -->
        <collection property="details" javaType="list" ofType="Detail" autoMapping="true">
            <id column="detail_id" property="detailId"/>
        </collection>
  </resultMap>

  <resultMap type="Order" id="OrderResultMap3" autoMapping="true" extends="OrderResultMap">
        <!-- 
            配置多的一方使用collection這個節點
            property:集合的屬性名稱
            javaType:類型
            ofType:集合中元素的類型
         -->
        <collection property="details" javaType="list" ofType="Detail" autoMapping="true">
            <id column="detail_id" property="detailId"/>
            <association property="product" javaType="Product" autoMapping="true">
                <id column="pid" property="pid"/>
            </association>
        </collection>
  </resultMap>

然後測試,運行ok

MyBatis學習(七)