本课程对应视频教程:http://edu.51cto.com/sd/3ec2c java
MyBatis做为一个ORM框架,也对sql的高级查询作了支持,这里以用户,订单,订单详情,商品为例讲解sql
案例说明:此案例的业务关系是用户、订单、订单详情、商品之间的关系、其中apache
一个订单只能属于一我的session
一个订单能够有多个订单详情mybatis
一个订单详情中包含一个商品信息oracle
他们的关系是:app
订单和人是一对一的关系框架
订单和订单详情是一对多的关系dom
订单和商品是多对多的关系iphone
一对一查询:查询订单,而且查询出下单人信息
一对多查询:查询订单,查询出下单人信息而且查询出订单详情
多对多查询:查询订单,查询出订单人信息而且查询出订单详情中的商品数据
将查询出来字段封装到一个新的类中,让这个类的属性包含全部查询出来的字段,
它的弊端在于,个人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.
让一个类持有另一个类的属性
定义一个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.
一对多查询:查询订单,查询出下单人信息而且查询出订单详情
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.
多对多查询:查询订单,查询出订单人信息而且查询出订单详情中的商品数据
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.
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