高级映射
数据模型分析思路
- 每张表记录的数据内容
分模块对每张表记录的内容进行熟悉,相当于你学习系统需求(功能)的过程。
2.每张表重要的字段设置
非空字段,外键字段
3.数据库级别表与表之间的关系
外键关系
4.表与表之间的业务关系
在分析表与表之间的业务关系时一定要建立在某个业务意义基础上去分析,先分析数据级别之间有关系的表之间的业务关系
- user和orders
user—>orders:一个用户可以创建多个订单,一对多
orders—>user:一个订单只由一个用户创建,一对一
- orders和orderdetail
orders—>orderdetail:一个订单可以包括多个订单明细,因为一个订单可以购买多个商品,每个商品的购买信息在orderdetail记录,一对多的关系
orderdetail—>orders:一个订单明细只能包括在一个订单中,一对一
- orderdetail和items
orderdetail—>items:一个订单明细只对应一个商品信息,一对一
items—>orderdetail:一个商品可以包括在多个订单明细,一对多
一对一的查询
需求:查询订单信息,关联查询创建订单的用户信息
1. 确定查询的主表:订单表
2. 确定关联表:用户表
3. 关联查询使用内连接还是外连接?
由于在orders表中有一个外键(user_id),通过外键来关联查询用户只能查询出一条记录
resultType:
- sql语句
<select id = "findOrdersUser" resultType = "com.shagou.mybatis.po.OrdersCustom">
SELECT orders.*,
user.name,
user.address,
user.birthday,
user.sex
FROM orders,USER WHERE orders.user_id = user.id;
</select>
- 创建pojo
- 将上边查询的结果集映射到pojo中,pojo中必须要包括所有的查询列名原始的Oreder.java不能映射全部字段,需要创建pojo,创建一个pojo继承包括查询字段较多的po类
private int id;
private String name;
private String sex;
private Date birthday;
private String address;
//用户创建的订单列表
private List<Orders> orderslist;
public List<Orders> getOrderslist() {
return orderslist;
}
public void setOrderslist(List<Orders> orderslist) {
this.orderslist = orderslist;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", sex=" + sex + ", birthday=" + birthday + ", address=" + address
+ ", orderslist=" + orderslist + "]";
}
- 配置mapper.xml
<!-- 查询订单关联查询用户 -->
<select id = "findOrdersUser" resultType = "com.shagou.mybatis.po.OrdersCustom">
SELECT orders.*,
user.name,
user.address,
user.birthday,
user.sex
FROM orders,USER WHERE orders.user_id = user.id;
</select>
- 编写mapper.java抽象接口
//查询订单关联查询用户信息
public List<OrdersCustom> findOrdersUser()throws Exception;
- 测试类
private SqlSessionFactory SqlSessionFactory;
@Before
public void setUp() throws Exception{
//mybatis配置文件
String resource = "SqlMapConfig.xml";
//得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建会话工厂,传入mybatis的配置文件信息
SqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindOrdersUser() throws Exception {
SqlSession sqlSession = SqlSessionFactory.openSession();
//创建代理对象
OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
//调用mapper方法
List<OrdersCustom> list = ordersMapperCustom.findOrdersUser();
System.out.println(list);
sqlSession.close();
}
resultMap:
- sql语句
- 使用resultMap将查询结果中的订单信息映射到Orders对象中,在Orders这歌类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中。
- 需要Orders类中添加user属性:
private User user;
statement定义
- 配置mapper.xml
1. 定义resultMap
<!-- 定义一个resultMap,订单查询关联用户 -->
<resultMap type = "com.shagou.mybatis.po.Orders" id ="OrdersUserResultMap">
<!-- 配置映射的订单信息 -->
<!-- id:指定查询列中的唯一标识,订单信息中的唯一标识,如果有多个列组成唯一标识,配置多个id
column:订单信息的唯一标识列
property:订单信息的唯一标识列所映射到Orders中哪个属性
-->
<id column = "id" property = "id"/>
<result column = "user_id" property = "userId"/>
<result column = "number" property = "number"/>
<result column = "createtime" property = "createtime"/>
<result column = "note" property = "note"/>
<!-- 配置映射的关联的用户信息 -->
<!-- association:用于映射关联查询单个对象的信息
property:要将关联查询的用户信息映射到Orders中哪个属性
-->
<association property = "user" javaType = "com.shagou.mybatis.po.User">
<!-- id:关联查询用户的唯一标识
column:指定唯一标识用户信息的lie
javaType:映射到user的哪个属性
-->
<id column = "user_id" property = "id"/>
<result column = "name" property = "name"/>
<result column = "sex" property = "sex"/>
<result column = "address" property = "address"/>
</association>
</resultMap>
2.配置xml
<!-- 查询订单关联查询用户 -->
<select id = "findOrdersUser" resultType = "com.shagou.mybatis.po.OrdersCustom">
SELECT orders.*,
user.name,
user.address,
user.birthday,
user.sex
FROM orders,USER WHERE orders.user_id = user.id;
</select>
- 编写接口
//查询订单关联查询用户使用resultMap
public List<Orders> findOrdersUserResultMap()throws Exception;
- 测试类
//resultMap
@Test
public void testFindOrdersUserResultMap() throws Exception {
SqlSession sqlSession = SqlSessionFactory.openSession();
OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
List<Orders> list = ordersMapperCustom.findOrdersUserResultMap();
System.out.println(list);
sqlSession.close();
}
小结
- 实现一对一的查询:
resultType:实现较为简单,如果pojo中没有包括查询出来的列名,需要增加对应的属性,即可完成映射如果没有查询结果的特殊要求建议使用resultType
resultMap:需要单独定义resultMap,实现有点麻烦,如果有对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo属性中
resultMap可以实现延迟加载,resultType无法实现