本文主要介紹了如何使用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);
}