最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mybatis中強(qiáng)大的resultMap功能介紹

 更新時(shí)間:2019年06月03日 09:54:02   作者:清幽之地  
這篇文章主要給大家介紹了關(guān)于Mybatis中強(qiáng)大的resultMap功能的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Mybatis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

在Mybatis中,有一個(gè)強(qiáng)大的功能元素resultMap。當(dāng)我們希望將JDBC ResultSets中的數(shù)據(jù),轉(zhuǎn)化為合理的Java對(duì)象時(shí),你就能感受到它的非凡之處。正如其官方所述的那樣:

resultMap元素是 MyBatis 中最重要最強(qiáng)大的元素。它可以讓你從 90% 的 JDBC ResultSets 數(shù)據(jù)提取代碼中解放出來(lái),并在一些情形下允許你進(jìn)行一些 JDBC 不支持的操作。實(shí)際上,在為一些比如連接的復(fù)雜語(yǔ)句編寫映射代碼的時(shí)候,一份 resultMap 能夠代替實(shí)現(xiàn)同等功能的長(zhǎng)達(dá)數(shù)千行的代碼。ResultMap 的設(shè)計(jì)思想是,對(duì)于簡(jiǎn)單的語(yǔ)句根本不需要配置顯式的結(jié)果映射,而對(duì)于復(fù)雜一點(diǎn)的語(yǔ)句只需要描述它們的關(guān)系就行了。

一、字段映射

在Mybatis中,最簡(jiǎn)單的結(jié)果映射方式,就是通過(guò)類型別名typeAliases來(lái)處理。

如果要這樣做,那么第一步需要配置實(shí)體類包的路徑:

mybatis.type-aliases-package=com.xxx.entity

該路徑下的所有類,就會(huì)被注冊(cè)到TYPE_ALIASES容器。我們?cè)谥付ǚ祷刂殿愋偷臅r(shí)候,就直接用別名即可。

比如,我們有一個(gè)User類:

@Data
public class User {
 private String id;
 private String username;
 private String password;
 private String address;
 private String email;
}

如果數(shù)據(jù)庫(kù)中表的字段與User類的屬性名稱一致,我們就可以使用resultType來(lái)返回。

<select id="getUsers" resultType="User">
	SELECT
		u.id,
		u.username,
		u.password,
		u.address,
		u.email
	FROM
		USER u
</select>

當(dāng)然,這是理想狀態(tài)下,屬性和字段名都完全一致的情況。但事實(shí)上,不一致的情況是有的,這時(shí)候我們的resultMap就要登場(chǎng)了。

如果User類保持不變,但SQL語(yǔ)句發(fā)生了變化,將id改成了uid。

<select id="getUsers" resultType="User">
	SELECT
		u.id as uid,
		u.username,
		u.password,
		u.address,
		u.email
	FROM
		USER u
</select>

那么,在結(jié)果集中,我們將會(huì)丟失id數(shù)據(jù)。這時(shí)候我們就可以定義一個(gè)resultMap,來(lái)映射不一樣的字段。

<resultMap id="getUserByIdMap" type="User">
	<result property="id" column="uid"></result>
</resultMap>

然后,我們把上面的select語(yǔ)句中的resultType修改為resultMap="getUserByIdMap"

這里面column對(duì)應(yīng)的是數(shù)據(jù)庫(kù)的列名或別名;property對(duì)應(yīng)的是結(jié)果集的字段或?qū)傩浴?br />

這就是resultMap最簡(jiǎn)單,也最基礎(chǔ)的用法:字段映射。

下面,我們看看其他幾種標(biāo)簽都是怎么應(yīng)用的。

元素名稱 描述
constructor 用于在實(shí)例化類時(shí),注入結(jié)果到構(gòu)造方法中
association 關(guān)聯(lián)一個(gè)對(duì)象
collection 關(guān)聯(lián)多個(gè)對(duì)象

二、構(gòu)造方法

如果你希望將結(jié)果注入構(gòu)造方法里,就可以用到constructor元素。

比如,我們的User類增加了一個(gè)構(gòu)造方法:

public User(String id, String name) {
	this.id = id+"--------";
	this.username = name+"--------";
}

我們需要在resultMap中定義constructor元素:

<resultMap id="getUserByIdMap" type="User">
	<constructor>
		<idArg column="id" name="id" javaType="string"></idArg>
		<arg column="username" name="name" javaType="string"></arg>
	</constructor>
</resultMap>

其中,column代表數(shù)據(jù)庫(kù)字段名稱或者別名;name則是構(gòu)造方法中的參數(shù)名稱;javaType指定了參數(shù)的類型。

如你所想,這樣指定構(gòu)造方法后,我們結(jié)果集中的id和username屬性都會(huì)發(fā)生變化。

{
 "id": "1001--------",
 "username": "后羿--------",
 "password": "123456",
 "address": "北京市海淀區(qū)",
 "email": "510273027@qq.com"
}

三、關(guān)聯(lián)

在實(shí)際的業(yè)務(wù)中,我們的用戶一般都會(huì)有一個(gè)角色。那么在User類里面一般也是以一個(gè)實(shí)體類來(lái)表示。

@Data
public class User {
 //省略用戶屬性...
	
 //角色信息
 private Role role;
}

我們?cè)诓樵冇脩舻臅r(shí)候,如果也希望看到它的角色信息,我們會(huì)這樣來(lái)寫查詢語(yǔ)句:

<select id="getUserById" resultType="User">
 SELECT
  u.id,
  u.username,
  u.password,
  u.address,
  u.email,
  r.id as 'role_id',
  r.name as 'role_name'
 FROM
  USER u
  LEFT JOIN user_roles ur ON u.id = ur.user_id
  LEFT JOIN role r ON r.id = ur.role_id
 where u.id=#{id}
 </select>

如上,就要查詢單個(gè)用戶以及用戶的角色信息。不過(guò)在這里,我們不能用resultType=User來(lái)返回。

畢竟,User類中只有一個(gè)Role對(duì)象,并沒(méi)有role_id和role_name字段屬性。

所以,我們要使用association來(lái)關(guān)聯(lián)它們。

<resultMap id="userMap" type="User">
	<id property="id" column="id"></id>
	<result property="username" column="username"></result>
	<result property="password" column="password"></result>
	<result property="address" column="address"></result>
	<result property="email" column="email"></result>
	
	<association property="role" javaType="Role">
		<id property="id" column="role_id"></id>
		<result property="name" column="role_name"></result>
	</association>
</resultMap>

最后我們就可以將角色信息一塊顯示出來(lái):

{
 "id": "1001",
 "username": "后羿",
 "password": "123456",
 "address": "北京市海淀區(qū)",
 "email": "510273027@qq.com",
 "role": {
 "id": "3",
 "name": "射手"
 }
}

事實(shí)上,如果你確定關(guān)聯(lián)信息是一對(duì)一的情況,有個(gè)更簡(jiǎn)便的方法可以替代association,我們?cè)诒疚牡牡谖宀糠?自動(dòng)填充關(guān)聯(lián)對(duì)象再看它是怎么實(shí)現(xiàn)的。

四、集合

1、集合的嵌套結(jié)果映射

上面我們看到一個(gè)用戶后羿,它的角色是射手;但大部分時(shí)候,我們每個(gè)人都不可能只擁有一種角色。所以,我們需要將User類中的角色屬性的類型改成List。

@Data
public class User {
 //省略用戶屬性...
	
 //角色信息
 private List<Role> roles;
}

現(xiàn)在就變成了一個(gè)用戶對(duì)應(yīng)多個(gè)角色,所以就不是簡(jiǎn)單的association。

因?yàn)閍ssociation處理的是有一個(gè)類型的關(guān)聯(lián);而我們這里是有多個(gè)類型的關(guān)聯(lián),所以就需要用到collection屬性。

我們整體的resultMap會(huì)變成下面這樣:

<resultMap id="userMap" type="User">
	<id property="id" column="id"></id>
	<result property="username" column="username"></result>
	<result property="password" column="password"></result>
	<result property="address" column="address"></result>
	<result property="email" column="email"></result>
	
	<collection property="roles" ofType="Role">
		<id property="id" column="role_id"></id>
		<result property="name" column="role_name"></result>
	</collection>
</resultMap>

這樣的話,即便你有多個(gè)角色也可以被正確顯示:

{
 "id": "1003",
 "username": "貂蟬",
 "password": "123456",
 "address": "北京市東城區(qū)",
 "email": "510273027@qq.com",
 "roles": [
  {
   "id": "1",
   "name": "中單"
  },
  {
   "id": "2",
   "name": "打野"
  }
 ]
}

2、集合的嵌套 Select 查詢

在大部分業(yè)務(wù)系統(tǒng)中,我們都會(huì)有一個(gè)菜單的表,比如像下面這樣,一張Menu表:

id name url parent_id
1 系統(tǒng)管理 0
1001 用戶管理 /user 1
1002 角色管理 /role 1
1003 單位管理 /employer 1
2 平臺(tái)監(jiān)控 0
2001 系統(tǒng)監(jiān)控 /system/monitor 2
2002 數(shù)據(jù)監(jiān)控 /data/monitor 2

這里我們給菜單分為兩級(jí)。我們給前端返回菜單的時(shí)候,也是需要分級(jí)的,不可能將這7條數(shù)據(jù)平級(jí)展示。那么,在這里我們的Menu實(shí)體類如下:

@Data
public class Menu {
 private String id;
 private String name;
 private String url;
 private String parent_id;
 private List<Menu> childMenu;
}

一級(jí)菜單,包含一個(gè)二級(jí)菜單的列表,這里用childMenu來(lái)表示。

SQL語(yǔ)句中,如果沒(méi)有parent_id字段屬性,我們就先查所有的一級(jí)菜單:

<select id="getMenus" resultMap="menusMap">
	SELECT
		m.id,
		m.name,
		m.url,
		m.parent_id
	FROM
		m_menu m
	where 1=1
	<choose>
		<when test="parent_id!=null">
			and m.parent_id = #{parent_id}
		</when>
		<otherwise>
			and m.parent_id = '0'
		</otherwise>
	</choose>
</select>

這個(gè)查詢語(yǔ)句,在不傳輸任何參數(shù)的情況下,我們會(huì)得到兩條一級(jí)菜單的數(shù)據(jù)。

那么在只調(diào)用此方法一次的情況下,怎么把所有的菜單信息查詢出來(lái),并按層級(jí)展示呢?

我們來(lái)看menusMap的定義:

<resultMap id="menusMap" type="Menu">
	<id property="id" column="id"></id>
	<result property="name" column="name"></result>
	<result property="url" column="url"></result>
	<result property="m_desc" column="m_desc"></result>
	<result property="parent_id" column="parent_id"></result>
	
	<collection property="childMenu" ofType="Menu" select="getMenus" column="{parent_id=id}"></collection>
</resultMap>

重點(diǎn)來(lái)看collection元素:

property="childMenu" 對(duì)應(yīng)的是菜單中的子級(jí)菜單列表;

ofType="Menu" 對(duì)應(yīng)返回?cái)?shù)據(jù)的類型;

select="getMenus" 指定了SELECT語(yǔ)句的id;

column="{parent_id=id}" 則是參數(shù)的表達(dá)式。

這個(gè)collection整體的含義可以這樣理解:

通過(guò)getMenus這個(gè)SELECT語(yǔ)句來(lái)獲取一級(jí)菜單中的childMenu屬性結(jié)果;在上面的SELECT語(yǔ)句中,需要傳遞一個(gè)parent_id參數(shù);這個(gè)參數(shù)的值就是一級(jí)菜單中的id。

通過(guò)這種方式,我們就可以得到已分級(jí)的所有菜單信息。

[
 {
  "id": "1",
  "name": "系統(tǒng)管理",
  "parent_id": "0",
  "childMenu": [
   {
    "id": "1001",
    "name": "用戶管理",
    "url": "/user",
    "parent_id": "1"
   },
   {
    "id": "1002",
    "name": "角色管理",
    "url": "/role",
    "parent_id": "1"
   },
   {
    "id": "1003",
    "name": "單位管理",
    "url": "/employer",
    "parent_id": "1"
   }
  ]
 },
 {
  "id": "2",
  "name": "平臺(tái)監(jiān)控",
  "parent_id": "0",
  "childMenu": [
   {
    "id": "2001",
    "name": "系統(tǒng)監(jiān)控",
    "url": "/system/monitor",
    "parent_id": "2"
   },
   {
    "id": "2002",
    "name": "數(shù)據(jù)監(jiān)控",
    "url": "/data/monitor",
    "parent_id": "2"
   }
  ]
 }
]

五、自動(dòng)填充關(guān)聯(lián)對(duì)象

我們知道,在Mybatis解析返回值的時(shí)候。

第一步是獲取返回值類型,拿到Class對(duì)象,然后獲取構(gòu)造器,設(shè)置可訪問(wèn)并返回實(shí)例,然后又把它包裝成MetaObject對(duì)象。

從數(shù)據(jù)庫(kù)rs中拿到結(jié)果之后,會(huì)調(diào)用MetaObject.setValue(String name, Object value) 來(lái)填充對(duì)象。

在這過(guò)程中,有趣的是,它會(huì)以.來(lái)分隔這個(gè)name屬性。

如果name屬性中包含.符號(hào),就找到.符號(hào)之前的屬性名稱,把它當(dāng)做一個(gè)實(shí)體對(duì)象來(lái)處理。

可能筆者在這里描述的不夠直觀,我們還是來(lái)看例子。

在本文第三部分中,我們有一個(gè)用戶對(duì)應(yīng)一個(gè)角色的例子。

其中,User類定義如下:

@Data
public class User {
 //省略用戶屬性...
	
 //角色信息
 private Role role;
}

在這里,我們無(wú)需定義resultMap,直接返回resultType=User即可。不過(guò)需要把role信息的別名修改一下,重點(diǎn)是.符號(hào)

<select id="getUserList" resultType="User">
	SELECT
		u.id,
		u.username,
		u.password,
		u.address,
		u.email,
		r.id as 'role.id',
		r.name as 'role.name'
	FROM
		USER u
			LEFT JOIN user_roles ur ON u.id = ur.user_id
			LEFT JOIN role r ON r.id = ur.role_id
</select>

這樣,在Mybatis解析到role.id屬性的時(shí)候,以.符號(hào)分隔之后發(fā)現(xiàn),role別名對(duì)應(yīng)的是Role對(duì)象,則會(huì)先初始化Role對(duì)象,并將值賦予id屬性。

相關(guān)代碼如圖:


總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • Java運(yùn)行時(shí)jar終端輸出的中文日志亂碼兩種解決方式

    Java運(yùn)行時(shí)jar終端輸出的中文日志亂碼兩種解決方式

    jar包啟動(dòng),今天java開發(fā)過(guò)來(lái)找,說(shuō)jar包啟動(dòng)日志是亂碼,這篇文章主要給大家介紹了關(guān)于Java運(yùn)行時(shí)jar終端輸出的中文日志亂碼的兩種解決方式,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • Java中用內(nèi)存映射處理大文件的實(shí)現(xiàn)代碼

    Java中用內(nèi)存映射處理大文件的實(shí)現(xiàn)代碼

    下面小編就為大家?guī)?lái)一篇Java中用內(nèi)存映射處理大文件的實(shí)現(xiàn)代碼。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-06-06
  • Java中枚舉類enum的values()方法舉例詳解

    Java中枚舉類enum的values()方法舉例詳解

    這篇文章主要給大家介紹了關(guān)于Java中枚舉類enum的values()方法舉例詳解,作為一種常用方法,可以在枚舉中對(duì)數(shù)組里的枚舉值進(jìn)行遍歷,這就是values()方法的使用,需要的朋友可以參考下
    2023-11-11
  • Tomcat版本與Java版本的關(guān)系及說(shuō)明

    Tomcat版本與Java版本的關(guān)系及說(shuō)明

    這篇文章主要介紹了Tomcat版本與Java版本的關(guān)系及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • java生成驗(yàn)證碼圖片的方法

    java生成驗(yàn)證碼圖片的方法

    這篇文章主要為大家詳細(xì)介紹了java生成驗(yàn)證碼圖片的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-02-02
  • Java計(jì)算幾何圖形面積的實(shí)例代碼

    Java計(jì)算幾何圖形面積的實(shí)例代碼

    這篇文章主要介紹了Java計(jì)算幾何圖形面積的實(shí)例代碼,需要的朋友可以參考下
    2014-03-03
  • MyBatis中使用#{}和${}占位符傳遞參數(shù)的各種報(bào)錯(cuò)信息處理方案

    MyBatis中使用#{}和${}占位符傳遞參數(shù)的各種報(bào)錯(cuò)信息處理方案

    這篇文章主要介紹了MyBatis中使用#{}和${}占位符傳遞參數(shù)的各種報(bào)錯(cuò)信息處理方案,分別介紹了兩種占位符的區(qū)別,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • eclipse中自動(dòng)生成構(gòu)造函數(shù)的兩種方法

    eclipse中自動(dòng)生成構(gòu)造函數(shù)的兩種方法

    下面小編就為大家?guī)?lái)一篇eclipse中自動(dòng)生成構(gòu)造函數(shù)的兩種方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • Java實(shí)現(xiàn)AES/CBC/PKCS7Padding加解密的方法

    Java實(shí)現(xiàn)AES/CBC/PKCS7Padding加解密的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)AES/CBC/PKCS7Padding加解密的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • JUnit4 Hamcrest匹配器常用方法總結(jié)

    JUnit4 Hamcrest匹配器常用方法總結(jié)

    這篇文章主要介紹了JUnit4 Hamcrest匹配器常用方法總結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11

最新評(píng)論

邓州市| 内乡县| 临颍县| 内江市| 五原县| 来凤县| 新昌县| 蒙阴县| 开远市| 白山市| 富川| 临安市| 菏泽市| 淮阳县| 长春市| 桐柏县| 通化县| 三原县| 巴青县| 河源市| 丰镇市| 观塘区| 宽甸| 九江县| 蒲江县| 安陆市| 武清区| 滨州市| 通道| 自贡市| 淮南市| 汉源县| 辉县市| 固原市| 麻城市| 嘉禾县| 马鞍山市| 蕲春县| 稷山县| 长沙县| 综艺|