业务背景
根据订单id查询订单的信息,以及该订单所属的客户的基本信息(不包括该客户自己的订单信息)
两张数据表
- 客户表
- 订单表
实体类
- 客户实体类:Customer
private Integer id;
private String name;
private Integer age;
//封装客户存在的订单信息
List<Order> orders = new ArrayList<>();
- 订单实体类:Order
private Integer id;
private String orderNumber;
private Double orderPrice;
//封装订单所属的客户的基本信息
Customer customer = new Customer();
CustomerMapper.java接口
//根据订单id查询订单的信息,以及该订单所属的客户的基本信息
Order getOrderById(Integer id);
CustomerMapper.xml映射文件
<!--
//根据订单id查询订单的信息,以及该订单所属的客户的基本信息
Order getOrderById(Integer id);
Order实体类:
private Integer id;
private String orderNumber;
private Double orderPrice;
Customer customer = new Customer();
Customer实体类:
private Integer id;
private String name;
private Integer age;
-->
<resultMap id="orderMap" type="order">
<!-- 主键映射 -->
<id property="id" column="oid"/>
<!-- 非主键映射 -->
<result property="orderNumber" column="orderNumber"/>
<result property="orderPrice" column="orderPrice" />
<!-- 关于Customer实体类的映射 -->
<association property="customer" javaType="customer">
<id property="id" column="cid"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
</association>
</resultMap>
<select id="getOrderById" parameterType="int" resultMap="orderMap">
select
o.id oid, orderNumber, orderPrice, customer_id, c.id cid, name, age
from
orders o
join
customers c
on
o.customer_id = c.id
where
o.id=#{id}
</select>
- 关于< association >中对Customer实体类的映射
- 这里虽然两个属性的值都是customer,但是意义不同
- property="customer":是因为Order实体类的一个成员变量的名称为customer,指明该标签的映射规则对应到哪个成员变量
- javaType="customer":是因为该成员变量的类型是Customer,由于我们在SqlMapConfig.xml为实体类注册了包级别名,这里用customer指代此类型
<!-- 关于Customer实体类的映射 -->
<association property="customer" javaType="customer">
<id property="id" column="cid"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
</association>
测试
//SqlSession对象
SqlSession sqlSession;
//获取OrderMapper的mybatis动态代理对象
OrderMapper orderMapper;
//获取SqlSession
@Before
public void getSqlSession() throws IOException {
//读取核心配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//获取SqlSession
sqlSession = factory.openSession();
//获取各Mapper接口的mybatis动态代理对象
orderMapper = sqlSession.getMapper(OrderMapper.class);
}
//归还SqlSession
@After
public void closeSession(){
sqlSession.close();
}
//测试:根据订单id查询订单的信息,以及该订单所属的客户的基本信息
@Test
public void testGetOrderById(){
Order order = orderMapper.getOrderById(11);
System.out.println(order);
}
结果
==> Preparing:
select
o.id oid, orderNumber, orderPrice, customer_id, c.id cid, name, age
from
orders o
join
customers c
on
o.customer_id = c.id
where
o.id=?
==> Parameters: 11(Integer)
<== Columns: oid, orderNumber, orderPrice, customer_id, cid, name, age
<== Row: 11, 20, 22.22, 1, 1, 荷包蛋, 22
<== Total: 1
Order{id=11, orderNumber='20', orderPrice=22.22, customer=Customer{id=1, name='荷包蛋', age=22, orders=[]}}
结果分析
- sql语句的查询结果
<== Columns: oid, orderNumber, orderPrice, customer_id, cid, name, age
<== Row: 11, 20, 22.22, 1, 1, 荷包蛋, 22
<== Total: 1
- 实际注入到实体类中的数据
Order{id=11,
orderNumber='20',
orderPrice=22.22,
customer=Customer{
id=1,
name='荷包蛋',
age=22,
orders=[]
}
}
注意
- 由于每个订单必定对应一个客户,所以本例中连接语句使用内连接也正确
- 本例并未查询客户对应的订单信息,所以订单对应的客户的自己的订单信息都是空
- 一对一和多对多关联查询,可由一对多和多对一查询推导出