目录
一、简介
二、业务环境的准备
2.1、准备工作:
2.2、SQL
三、一对一和一对多
Sql语句:
POJO
OrderMapper
OrderMapper.xml
Test测试类
运行结果
MyBatis 是一个优秀的持久层框架,它提供了强大的支持来执行数据库操作,包括多表查询。多表查询是指从多个数据库表中检索数据的过程,这在实际的应用中非常常见。MyBatis 提供了多种方法来执行多表查询,以下是一些常见的技术和方法:
1.使用嵌套查询: 这是最基本的多表查询方法,通过在 SQL 语句中嵌套子查询来联合多个表的数据。例如,你可以在 SELECT 语句中使用子查询来从一个表中获取数据,然后再将其用于主查询中。这种方法在某些简单情况下是有效的,但对于复杂的多表查询可能会变得冗长和难以维护。
2.使用多个 SQL 语句: 在 MyBatis 中,你可以编写多个独立的 SQL 语句,每个语句都从一个表中检索数据,然后在 Java 代码中将这些数据组合起来。这通常需要在 Java 代码中手动执行每个查询并进行数据处理,但对于一些复杂的多表查询情况可能更加灵活。
3.使用关联查询: MyBatis 支持使用关联查询来执行多表查询,特别是在映射文件中配置了表之间的关联关系。通过在 Mapper XML 文件中配置 association 或 collection 来表示表之间的关联关系,MyBatis 可以自动根据关系从多个表中检索数据并构造结果对象。
4.使用自定义映射查询: 有时候,多表查询的结果可能不适合于一个实体类,这时你可以使用自定义映射查询来将结果映射到一个 Map 或者其他自定义的数据结构中,以适应查询的需要。
无论使用哪种方法,多表查询都需要仔细考虑性能和结果的数据结构。在执行多表查询时,需要注意数据库表之间的关联关系、连接方式(内连接、左连接等)以及查询结果的组织方式,以便在查询结果中获取所需的数据。 MyBatis 的强大灵活性使得你可以根据实际情况选择合适的方法来执行多表查询。
模拟的业务是用户与订单之间的关系,可以是一对一,一对多。比如:一个用户可以拥有多个订单,一个订单只能有一个用户。
下面准备三张表:
user(用户)表
order(订单)表
orderdetail(订单详情)表
--用户表创建
CREATE TABLE `user` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`password` varchar(50) DEFAULT NULL,
`gender` varchar(10) DEFAULT NULL,
`hobby` varchar(100) DEFAULT NULL,
`address` varchar(200) DEFAULT NULL,
`remark` varchar(500) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8
--订单表创建
CREATE TABLE `orders` (
`oid` int(50) NOT NULL AUTO_INCREMENT,
`oname` varchar(200) DEFAULT NULL,
`ocount` int(200) DEFAULT NULL,
`uid` int(50) DEFAULT NULL,
PRIMARY KEY (`oid`),
KEY `uid` (`uid`),
CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `user` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
--订单详情表创建
CREATE TABLE `orderdetail` (
`id` int(50) NOT NULL AUTO_INCREMENT,
`detail_name` varchar(200) DEFAULT NULL,
`detail_all_price` int(50) DEFAULT NULL,
`order_id` int(50) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `order_id` (`order_id`),
CONSTRAINT `orderdetail_ibfk_1` FOREIGN KEY (`order_id`) REFERENCES `orders` (`oid`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户。
因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单。
SELECT u.username,u.address,o.* FROM USER u,orders o WHERE u.id = o.uid;
User
package com.org.domain;
import java.io.Serializable;
import java.util.List;
public class User implements Serializable{
private int id;
private String username;
private String password;
private String gender;
private String hobby;
private String address;
private String remark;
private List orderList;
public User() {
}
public User( String username, String password, String gender, String address) {
this.username = username;
this.password = password;
this.gender = gender;
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public List getOrderList() {
return orderList;
}
public void setOrderList(List orderList) {
this.orderList = orderList;
}
}
Order
package com.org.domain;
public class Order {
private int o_id;
private String o_name;
private int o_count;
private User user;
public int getO_id() {
return o_id;
}
public void setO_id(int o_id) {
this.o_id = o_id;
}
public String getO_name() {
return o_name;
}
public void setO_name(String o_name) {
this.o_name = o_name;
}
public int getO_count() {
return o_count;
}
public void setO_count(int o_count) {
this.o_count = o_count;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
OrderDetail
package com.org.domain;
import java.util.List;
public class OrderDetail {
private int id;
private String detail_name;
private int detail_price;
private Order order;
private List itemList;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDetail_name() {
return detail_name;
}
public void setDetail_name(String detail_name) {
this.detail_name = detail_name;
}
public int getDetail_price() {
return detail_price;
}
public void setDetail_price(int detail_price) {
this.detail_price = detail_price;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
public List getItemList() {
return itemList;
}
public void setItemList(List itemList) {
this.itemList = itemList;
}
}
public interface OrderMapper {
public List findUserOrderDetail();
}
@Test
public void test18() {
SqlSession sqlSession = ssf.openSession();
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
List orderUserOrderDetails = mapper.findUserOrderDetail();
for (Order orderUserOrderDetail : orderUserOrderDetails) {
System.out.println(orderUserOrderDetail.getO_id()+","+orderUserOrderDetail.getO_count()+","+orderUserOrderDetail.getO_count()+","+orderUserOrderDetail.getUser().getUsername()+","+orderUserOrderDetail.getUser().getAddress());
List orderDetailsList = orderUserOrderDetail.getOrderDetailList();
for (OrderDetail orderDetail : orderDetailsList) {
System.out.println("\t"+orderDetail.getDetails_id()+","+orderDetail.getTrade_name()+","+orderDetail.getUnit_price());
}
}
}