MyBatis学习(七)

本课程对应视频教程:http://edu.51cto.com/sd/3ec2c java

一、高级查询

MyBatis做为一个ORM框架,也对sql的高级查询作了支持,这里以用户,订单,订单详情,商品为例讲解sql

案例说明:此案例的业务关系是用户、订单、订单详情、商品之间的关系、其中apache

一个订单只能属于一我的session

一个订单能够有多个订单详情mybatis

一个订单详情中包含一个商品信息oracle

他们的关系是:app

订单和人是一对一的关系框架

订单和订单详情是一对多的关系dom

订单和商品是多对多的关系iphone

1.一、数据模型分析

mark

1.二、需求分析

一对一查询:查询订单,而且查询出下单人信息

一对多查询:查询订单,查询出下单人信息而且查询出订单详情

多对多查询:查询订单,查询出订单人信息而且查询出订单详情中的商品数据

1.三、一对一查询

1.3.一、方式一

将查询出来字段封装到一个新的类中,让这个类的属性包含全部查询出来的字段,

它的弊端在于,个人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.二、采用面向对象的思惟

让一个类持有另一个类的属性

定义一个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.四、一对多查询

一对多查询:查询订单,查询出下单人信息而且查询出订单详情

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.五、多对多

多对多查询:查询订单,查询出订单人信息而且查询出订单详情中的商品数据

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.六、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

相关文章
相关标签/搜索