本课程对应视频教程: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 one2one(@Param("orderNum")String orderNum);

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

测试类

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 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文件


        
        
        
            
        
  
  

测试类

@Test
    public void testone2one2()throws Exception{ 
        List 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 details ; 
    public List getDetails() {
        return details;
    }
    public void setDetails(List details) {
        this.details = details;
    }

mapper.xml文件


        
        
        
            
        
        
        
            
        
  
  

测试类

public void testone2many()throws Exception{
        List 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 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文件


        
        
        
            
        
        
        
            
            
                
            
        
  
  

测试类

@Test
    public void testmany2many()throws Exception{
        List 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元素可以通过继承机制来减少冗余


        
        
        
            
        
  

  
        
        
            
        
  

  
        
        
            
            
                
            
        
  

然后测试,运行ok