mybatis中嵌套查詢的使用解讀
mybatis嵌套查詢的使用
在使用mybatis時,當(dāng)我們遇到表與表之之間存在關(guān)聯(lián)的時候,就可以使用嵌套查詢
比如說
當(dāng)一個對象包含了另一個對象
/**
* 公交實(shí)體類中包含了司機(jī)信息和路線信息
*/
public class Bus implements Serializable {
private Integer id;
private String card;
private Integer driverid;
private Integer wayid;
private Double price;
private Date topen;
private Date tclose;
private Driver driver;//司機(jī)
private Way way;//路線
//省略封裝方法
}
當(dāng)一個對象中包含另一個對象的泛型集合
public class Way implements Serializable {
private Integer id;
private String name;
private Date topen;
private Date tclose;
private List<Station> stations;
private String topenString;
private String tcloseString;
//省略封裝方法
}
當(dāng)一個對象中包含了另外一個對象時,在resultMap中就可以使用嵌套查詢
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.whx.bus.mapper.BusMapper" >
<resultMap id="BaseResultMap" type="com.whx.bus.entity.Bus" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="card" property="card" jdbcType="VARCHAR" />
<result column="driverId" property="driverid" jdbcType="INTEGER" />
<result column="wayId" property="wayid" jdbcType="INTEGER" />
<result column="price" property="price" jdbcType="DOUBLE" />
<result column="topen" property="topen" jdbcType="TIMESTAMP" />
<result column="tclose" property="tclose" jdbcType="TIMESTAMP" />
<!-- 在select屬性中指向需要調(diào)用哪個sql執(zhí)行(可以指向其它命名空間的,比如:com.whx.bus.mapper.WayMapper.selectByPrimaryKey)-->
<!-- 在column屬性中指定需傳遞給子查詢的參數(shù) -->
<!-- 在property屬性中指定Java對象中的變量名 -->
<!-- 在javaType屬性中指定當(dāng)前對象的限定名(如果是集合的話就是ofType) -->
<association property="driver" column="driverId" javaType="com.whx.bus.entity.Driver" select="selectDriverById">
</association>
<!-- 在select屬性中指向需要調(diào)用哪個sql執(zhí)行(可以指向其它命名空間的,比如:com.whx.bus.mapper.WayMapper.selectByPrimaryKey)-->
<!-- 在column屬性中指定需傳遞給子查詢的參數(shù) -->
<!-- 在property屬性中指定Java對象中的變量名 -->
<!-- 在javaType屬性中指定當(dāng)前對象的限定名(如果是集合的話就是ofType) -->
<association property="way" column="wayId" javaType="com.whx.bus.entity.Way" select="selectWayById">
</association>
</resultMap>
<!-- 司機(jī)結(jié)果集 -->
<resultMap id="DriverResultMap" type="com.whx.bus.entity.Driver">
<id column="id" property="id" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="driver_card" property="driverCard" jdbcType="VARCHAR" />
<result column="mobile" property="mobile" jdbcType="VARCHAR" />
</resultMap>
<!-- 路線結(jié)果集 -->
<resultMap id="WayResultMap" type="com.whx.bus.entity.Way">
<id column="id" property="id" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="topen" property="topen" jdbcType="TIMESTAMP" />
<result column="tclose" property="tclose" jdbcType="TIMESTAMP" />
<result column="topenString" property="topenString" jdbcType="VARCHAR" />
<result column="tcloseString" property="tcloseString" jdbcType="VARCHAR" />
<!-- 在select屬性中指向需要調(diào)用哪個sql執(zhí)行(可以指向其它命名空間的,比如:com.whx.bus.mapper.WayMapper.selectByPrimaryKey)-->
<!-- 在column屬性中指定需傳遞給子查詢的參數(shù) -->
<!-- 在property屬性中指定Java對象中的變量名 -->
<!-- 在ofType屬性中指定泛型集合對應(yīng)的對象的限定名(如果是單個對象的話就是javaType) -->
<collection property="stations" ofType="com.whx.bus.entity.Station" column="id" javaType="java.util.ArrayList" select="selectStationsByWay">
</collection>
</resultMap>
<!-- 站點(diǎn)結(jié)果集 -->
<resultMap id="StationResultMap" type="com.whx.bus.entity.Station" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
</resultMap>
<!-- 通過主鍵獲取公交信息 -->
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
from bus
where id = #{id,jdbcType=INTEGER}
</select>
<!-- 通過路線獲取站點(diǎn)信息 -->
<select id="selectStationsByWay" parameterType="java.lang.Integer" resultMap="StationResultMap">
select station.* from station inner join way_station on station.id = way_station.stationId where way_station.wayId = #{value}
</select>
<!-- 通過司機(jī)id查詢司機(jī)信息 -->
<select id="selectDriverById" parameterType="java.lang.Integer" resultMap="DriverResultMap">
select driver.* from driver where id = #{value}
</select>
<!-- 通過路線id查詢路線信息 -->
<select id="selectWayById" parameterType="java.lang.Integer" resultMap="WayResultMap">
select way.* from way where id = #{value}
</select>
</mapper>
配置了resultMap的嵌套查詢之后,調(diào)用自己的查詢只要調(diào)用相應(yīng)的resultMap之后就可以了,執(zhí)行查詢之后就會自己會調(diào)用子查詢(注意:子查詢其實(shí)也是對應(yīng)一個查詢語句,也要有相應(yīng)的結(jié)果集)。
附上一個查詢結(jié)果的debug

從圖中也是可以看出Bus中的Way對象是有數(shù)據(jù)的,并且Way中的泛型集合stations也是有數(shù)據(jù)的,這是因?yàn)樽硬樵冎械慕Y(jié)果集也配置了嵌套查詢,所以相對于嵌套了兩次~
如果使用多個嵌套需要額外注意,在多對多的情況下,切勿嵌套死循環(huán)了,不然就尷尬了~233
需要嵌套對象還是集合就根據(jù)自己的需求來了,注意單個對象是association、集合是collection(屬性在代碼中有說明)
還有一個點(diǎn)需要注意的就是:如果配置了嵌套了,在原查詢語句中就不要查嵌套的表了,只查原表中的就行~不然就會出錯——切記切記
傳遞多個參數(shù)
如果嵌套查詢需傳遞多個參數(shù)
<resultMap id="BaseResultMap" type="com.whx.bus.entity.Bus" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="card" property="card" jdbcType="VARCHAR" />
<result column="driverId" property="driverid" jdbcType="INTEGER" />
<result column="wayId" property="wayid" jdbcType="INTEGER" />
<result column="price" property="price" jdbcType="DOUBLE" />
<result column="topen" property="topen" jdbcType="TIMESTAMP" />
<result column="tclose" property="tclose" jdbcType="TIMESTAMP" />
<!-- 如果這里需要傳遞一個card和一個driverId到子查詢中 -->
<!-- cardParam表示自查詢中用到的鍵(鍵可自己定義)、card表示當(dāng)前結(jié)果集的card列的值(列根據(jù)上面的結(jié)果集來) -->
<!-- driverIdParam表示自查詢中用到的鍵(鍵可自己定義)、driverId表示當(dāng)前結(jié)果集的driverId列的值(列根據(jù)上面的結(jié)果集來) -->
<association property="driver" column="{cardParam=card,driverIdParam=driverId}" javaType="com.whx.bus.entity.Driver" select="selectDriverById">
</association>
</resultMap>
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java動態(tài)線程池插件dynamic-tp集成zookeeper
ZooKeeper是一個分布式的,開放源碼的分布式應(yīng)用程序協(xié)調(diào)服務(wù),是Google的Chubby一個開源的實(shí)現(xiàn),是Hadoop和Hbase的重要組件。它是一個為分布式應(yīng)用提供一致性的軟件,提供的功能包括:配置維護(hù)、域名服務(wù)、分布式同步、組服務(wù)等2023-03-03
Java?深入理解創(chuàng)建型設(shè)計(jì)模式之抽象工廠模式
當(dāng)系統(tǒng)所提供的工廠所需生產(chǎn)的具體產(chǎn)品并不是一個簡單的對象,而是多個位于不同產(chǎn)品等級結(jié)構(gòu)中屬于不同類型的具體產(chǎn)品時需要使用抽象工廠模式,抽象工廠模式是所有形式的工廠模式中最為抽象和最具一般性的一種形態(tài)2022-02-02
Java用Cookie限制點(diǎn)贊次數(shù)(簡版)
最近做了一個項(xiàng)目,其中有項(xiàng)目需求是,要用cookie實(shí)現(xiàn)限制點(diǎn)贊次數(shù),特此整理,把實(shí)現(xiàn)代碼分享給大家供大家學(xué)習(xí)2016-02-02

