本課程對應視頻教程: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