本文主要介绍了如何使用resultMap完成高级映照;分析数据库中表之间的关系(1对1、1对多、多对多)
如何在mapper.xml文件中配置resultMap实现1对1、1对多、多对多;mybatis如何实现延迟加载
数据库中有已导入的4个表:items:(商品信息表);orderdetail:(定单明细表);orders:(定单表);user:(用户表)
用户表user:
记录了购买商品的用户
定单表orders:
记录了用户所创建的定单信息
定单明细表orderdetail:
记录了用户创建定单的详细信息
商品信息表items:
记录了商家提供的商品信息
分析表与表之间的关系:
用户user和定单orders:
user---->orders:1个用户可以创建多个定单 1对多
orders-->user:1个定单只能由1个用户创建 1对1
定单orders和定单明细orderdetail:
orders-->orderdetail:1个定单可以包括多个定单明细 1对多
orderdetail-->orders:1个定单明细只属于1个定单 1对1
定单明细orderdetail和商品信息items:
orderdetail-->items:1个定单明细对应1个商品信息1对1
items--> orderdetail:1个商品对应多个定单明细 1对多
以下是这4个表的对应关系:
使用Mapper接口代理的方式查询定单信息关联查询用户信息
查询语句:
先肯定主查询表:定单信息表
再肯定关联查询表:用户信息
通过orders关联查询用户使用user_id1个外键,只能关联查询出1条用户记录就能够使用内连接
SELECT
orders.*,
user.username,
user.sex
FROM
orders,
USER
WHERE orders.user_id = user.id
这里输出的结果包括 定单信息和用户信息,之前创建的pojo都是单表的实体类,所以这里需要自定义1个组合的pojo才能完成resultType的映照。
创建OrderCustom作为自定义pojo,补充相应的get()和set()方法
packagecn.itcast.mybatis.po;
public class OrderCustomextends Orders {
//补充用户信息
privateStringusername;
privateStringsex;
privateString address;
}
定义OrdersMapperCustom.xml文件,
<!--1对1查询使用reusltType完成
查询定单关联查询用户信息使用resultType的方式
-->
<selectid="findOrderUserList"resultType="orderCustom">
SELECT
orders.*,
user.username,
user.sex
FROM
orders,
USER
WHEREorders.user_id = user.id
</select>
定义OrderMapperCustomer.java文件
packagecn.itcast.mybatis.mapper;
public interfaceOrdersMapperCustom {
// 1对1查询,查询定单关联查询用户,使用resultType
publicList<OrderCustom> findOrderUserList()throwsException;
}
package cn.itcast.mybatis.mapper;
public class OrdersMapperCustomTest {
//会话工厂
privateSqlSessionFactory sqlSessionFactory;
//创建工厂
@Before
publicvoid init() throws IOException {
//配置文件(SqlMapConfig.xml)
Stringresource = "SqlMapConfig.xml";
//加载配置文件到输入流
InputStreaminputStream = Resources.getResourceAsStream(resource);
//创建会话工厂
sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
publicvoid testFindOrderUserList() throws Exception {
SqlSessionsqlSession = sqlSessionFactory.openSession();
//创建mapper代理对象
OrdersMapperCustomordersMapperCustom = sqlSession
.getMapper(OrdersMapperCustom.class);
//调用方法
List<OrderCustom>list = ordersMapperCustom.findOrderUserList();
System.out.println(list);
}
}
resultMap提供1对1关联查询的映照和1对多关联查询映照,1对1映照思路:将关联查询的信息映照到查询的POJO中,以下:
在Orders类中创建1个User属性,将关联查询的信息映照到User属性中。
Orders.java补充相应的get()和set()方法
package cn.itcast.mybatis.po;
public class Orders implements Serializable{
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
//关联用户信息
private User user;
}
OrdersMapperCustomer.xml定义sql语句和resultMap映照之间的关系
<!-- 1对1查询resultMap,这里的ID是1个唯1的标识,与输出参数resultMap定义的相同(用黄色标出)
-->
<resultMaptype="orders"id="ordersUserResultMap">
<!--完成了定单信息的映照配置-->
<!--id:定单关联用户查询的唯1标识 -->
<!--column: sql语句中查询的列,property:pojo中对应的属性-->
<idcolumn="id"property="id"/>
<resultcolumn="user_id"property="userId"/>
<resultcolumn="number"property="number"/>
<resultcolumn="createtime"property="createtime"/>
<resultcolumn="note"property="note"/>
<!--下边完成关联信息的映照
association:用于对关联信息映照到单个pojo
property:要将关联信息映照到orders的哪一个属性中
javaType:关联信息映照到orders的属性的类型,是user的类型
-->
<associationproperty="user"javaType="user">
<!--id:关联信息的唯1标识 -->
<!--property:要映照到user的哪一个属性中-->
<idcolumn="user_id"property="id"/>
<!--result就是普通列的映照-->
<resultcolumn="username"property="username"/>
<resultcolumn="sex"property="sex"/>
</association>
</resultMap>
<!-- 1对1查询使用reusltMap完成
查询定单关联查询用户信息 -->
<selectid="findOrderUserListResultMap"resultMap="ordersUserResultMap">
SELECT
orders.*,
user.username,
user.sex
FROM
orders,
USER
WHEREorders.user_id = user.id
</select>
在OrderMapperCustomer.java中添加使用resultMap进行1对1查询的接口
packagecn.itcast.mybatis.mapper;
public interfaceOrdersMapperCustom {
// 1对1查询,使用resultMap
publicList<Orders> findOrderUserListResultMap()throwsException;
}
package cn.itcast.mybatis.mapper;
public class OrdersMapperCustomTest {
//会话工厂
privateSqlSessionFactory sqlSessionFactory;
//创建工厂
@Before
publicvoid init() throws IOException {
//配置文件(SqlMapConfig.xml)
Stringresource = "SqlMapConfig.xml";
// 加载配置文件到输入流
InputStreaminputStream = Resources.getResourceAsStream(resource);
//创建会话工厂
sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
}
// 1对1查询使用resultMap
@Test
public voidtestFindOrderUserListResultMap() throwsException {
SqlSessionsqlSession = sqlSessionFactory.openSession();
// 创建mapper代理对象
OrdersMapperCustomordersMapperCustom = sqlSession
.getMapper(OrdersMapperCustom.class);
// 调用方法
List<Orders>list = ordersMapperCustom.findOrderUserListResultMap();
System.out.println(list);
}
}
resultType:要自定义pojo 保证sql查询列和pojo的属性对应,加入sql语句使用别名,则查询不到该列的信息,这类方法相对较简单,所以利用广泛。
resultMap:使用association完成1对1映照需要配置1个resultMap,进程有点复杂,如果要实现延迟加载就只能用resultMap实现 ,如果为了方便对关联信息进行解析,也能够用association将关联信息映照到pojo中方便解析。
使用mapper接口代理的方式查询所有定单信息(关联用户)及定单下的定单明细信息。
主查询表:定单表
关联查询表:定单明细
SELECT
orders.*,
user.username,
user.sex ,
orderdetail.id orderdetail_id,
orderdetail.items_num,
orderdetail.items_id
FROM
orders,
USER,
orderdetail
WHERE orders.user_id = user.id AND orders.id = orderdetail.orders_id
resultMap 提供collection完成关联信息映照到集合对象中。
在orders类中创建集合属性:
package cn.itcast.mybatis.po;
public class Orders implements Serializable{
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
//关联用户信息
private User user;
//定单明细
privateList<Orderdetail> orderdetails;
}
<!-- 1对多,查询定单及定单明细 -->
<resultMaptype="orders"id="orderAndOrderDetails"extends="ordersUserResultMap">
<!--映照定单信息,和用户信息,这里使用继承ordersUserResultMap-->
<!--映照定单明细信息
property:要将关联信息映照到orders的哪一个属性中
ofType:集合中pojo的类型
-->
<collectionproperty="orderdetails"ofType="cn.itcast.mybatis.po.Orderdetail">
<!--id:关联信息定单明细的唯1标识
property:Orderdetail的属性名
-->
<idcolumn="orderdetail_id"property="id"/>
<resultcolumn="items_num"property="itemsNum"/>
<resultcolumn="items_id"property="itemsId"/>
</collection>
</resultMap>
<!-- 1对多查询使用reusltMap完成
查询定单关联查询定单明细
-->
<selectid="findOrderAndOrderDetails"resultMap="orderAndOrderDetails">
SELECT
orders.*,
user.username,
user.sex ,
orderdetail.id orderdetail_id,
orderdetail.items_num,
orderdetail.items_id
FROM
orders,
USER,
orderdetail
WHEREorders.user_id = user.id AND orders.id =orderdetail.orders_id
</select>
在OrderMapperCustomer.java中添加使用resultMap进行1对多查询的接口
packagecn.itcast.mybatis.mapper;
public interfaceOrdersMapperCustom {
// 1对多查询,使用resultMap
publicList<Orders> findOrderAndOrderDetails()throwsException;
}
package cn.itcast.mybatis.mapper;
public class OrdersMapperCustomTest {
//会话工厂
privateSqlSessionFactory sqlSessionFactory;
//创建工厂
@Before
publicvoid init() throws IOException {
//配置文件(SqlMapConfig.xml)
Stringresource = "SqlMapConfig.xml";
//加载配置文件到输入流
InputStreaminputStream = Resources.getResourceAsStream(resource);
//创建会话工厂
sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
}