滿滿乾貨!收藏!最全MyBatis中XML映射文件標籤分析

useCache="true"
timeout="10000"
fetchSize="256"
statementType="PREPARED"
resultSetType="FORWARD_ONLY"
databaseId="mysql"
resultOrdered="false"
resultSets="xxx,xxx"
lang="">java

## id

必選標籤。同一個命名空間裏面的惟一標識符,若是須要被外部接口調用,則須要和Mapper接口中的方法名保持一致。

## parameterType

可選標籤。參數類的徹底限定名或別名,上面示例中的表示咱們傳入的參數是一個String類型(關於別名若是不清楚的能夠點擊這裏)。若是不寫這個屬性的話,MyBatis在解析xml文件的時候會默認設爲unset,而後根據TypeHandler推斷出參數類型。若是有多個參數的狀況下建議仍是不寫這個參數,不然可能會出現參數類型轉換錯誤

## parameterMap

這是一個過時的屬性,咱們不作討論。

## resultType

非必選標籤。注意這裏的非選是由於resultType和resultMap不能並存,二者能且只能選擇一個。主要是用來定義一個返回結果集對象的全限定名或者別名。若是接收參數是一個集合,那麼這裏定義的就是集合中能夠包含的類型,而並非集合自己。 好比示例中的寫法,那麼對應Mapper接口中,適用於如下兩種語句:

LwUser listUserByUserName(@Param("userName") String userName);
List listUserByUserName(@Param("userName") String userName); mysql

## resultMap

非必選標籤。注意這裏的非選是由於resultType和resultMap不能並存,二者能且只能選擇一個。resultMap類型的結果集映射,是MyBatis最強大的特性,在這裏咱們不展開,過兩天會有一篇單獨介紹MyBatis一對一和一對多等複雜查詢時候會單獨介紹該屬性。感興趣的能夠先關注我,留意後面的文章。

## flushCache

可選標籤。設置爲 true時,任什麼時候候只要語句被調用,都會致使本地緩存和二級緩存都會被清空,默認值:false。

## useCache
可選標籤。設置爲 true時將會致使本條語句的結果被二級緩存,對 select 標籤語句默認值爲true,對insert,delete,update等語句默認是false。

## timeout

可選標籤。這個設置是在拋出異常以前,驅動程序等待數據庫返回請求結果的秒數。默認值爲 unset(依賴驅動)。

## fetchSize

可選標籤。這是嘗試影響驅動程序每次批量返回的結果行數和這個設置值相等。默認值爲 unset(依賴驅動)。注意這個只是嘗試,假如把fetchSize設置爲10萬,而數據庫驅動最高只支持到5w,那麼也會只能返回5w數據

## statementType

可選標籤。能夠選擇:STATEMENT,PREPARED 或 CALLABLE 中的一個,這會讓 MyBatis 分別使用Statement,PreparedStatement 或 CallableStatement,默認值是PREPARED,也就是使用預編譯PreparedStatement 語句。

## resultSetType

可選標籤。能夠選擇如下三種類型中的一個,默認爲unset(依賴驅動)。

*   FORWARD_ONLY:只容許遊標向前訪問

*   SCROLL_SENSITIVE:容許遊標雙向滾動,但不會及時更新數據,也就是說若是數據庫中的數據被修改過,並不會在resultSet中體現出來

*   SCROLL_INSENSITIVE:許遊標雙向滾動,若是數據庫中的數據被修改過,會及時更新到resultSet

上面的解釋可能有些人仍是看不明白,咱們先來看一段JDBC讀取結果集的操做:

![image](https://upload-images.jianshu.io/upload_images/24613101-eb503a5ee3dac968.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

而MyBatis只是把這些操做封裝了,底層實際上仍是這個操做,rs.next()遊標向前滾,其實還有一個rs.previous()表示遊標能夠向後滾。 因此FORWARD_ONLY只容許向前滾,訪問過的數據就會釋放內存,在某些場景中能夠提高性能。 後面那兩個都是容許雙向滾動,因此即便訪問過的數據,內存也不能釋放。這兩個的區別就是一個對數據敏感,一個對數據不敏感。

*   對數據不敏感 就是說當咱們查詢出結果以後,會將整個結果集都緩存在內存中,假若有一條數據還沒讀取到(還在while循環中)這時候有另一個線程修改了這條數據,那麼當咱們後面讀取這條數據的時候,仍是讀取到修改以前的。

*   對數據敏感 就是說當咱們查詢出結果以後,只會緩存一個rowid,而並不會緩存整條數據,假若有一條數據還沒讀取到(還在while循環中)這時候有另一個線程修改了這條數據,那麼當咱們後面讀取這條數據的時候,會根據rowid去查詢數據,查詢到的就是最新的數據。不過須要注意的是,由於delete的時候數據其實還在,只是打了個標記,因此若是一條數據被刪除了,是體現不出來的。同理,insert也不影響,由於查詢出來的數據不包含insert數據的rowid。

若是對於MySQL的InnoDB引擎的MVCC機制,那麼數據確定是不會敏感的,由於其餘事務改了當前事務也看不到。

## databaseId

可選標籤。

## resultOrdered

可選標籤。這個設置僅針對嵌套結果 select 語句適用。若是爲 true,就是假設包含了嵌套結果集或是分組了,這樣的話當返回一個主結果行的時候,就不會發生有對前面結果集的引用的狀況。這就使得在獲取嵌套的結果集的時候不至於致使內存不夠用。默認值: false 。

## resultSets

可選標籤。這個設置僅對多結果集的狀況適用,它將列出語句執行後返回的結果集並每一個結果集給一個名稱,名稱是逗號分隔的。

## lang

自定義語言,這個我也沒用過,因此就不介紹了

## insert

insert用來映射插入語句。如下就是一個insert標籤的所有二級標籤:

有一些標籤和select語句是重複的就再也不重複介紹,主要來關注一下其餘標籤。

## useGeneratedKeys

可選標籤。配置爲true時,MyBatis會使用JDBC的getGeneratedKeys方法來取出由數據庫內部生成的主鍵(好比:像 MySQL 和 SQL Server 這樣的關係數據庫管理系統的自動遞增字段),默認值爲false。

## keyProperty

可選標籤。惟一標記一個屬性,MyBatis會將經過getGeneratedKeys 的返回值或者經過insert 語句的selectKey 子元素設置它的鍵值,默認值是unset 。若是但願獲得多個生成的列,也能夠是逗號分隔的屬性名稱列表

## keyColumn

經過生成的鍵值設置表中的列名,這個設置僅在某些數據庫(像PostgreSQL)是必須的,當主鍵列不是表中的第一列的時候須要設置。若是但願獲得多個生成的列,也能夠是 逗號分隔的屬性名稱列表

## 獲取自增主鍵

獲取自增主鍵,能夠經過keyProperty來映射 定義一個實體類:

package com.lonelyWolf.mybatis.model;git

public class UserAddress {
private int id;
private String address;面試

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getAddress() {
    return address;
}

public void setAddress(String address) {
    this.address = address;
}

}redis

定義一個UserAddressMapper.java接口:

package com.lonelyWolf.mybatis.mapper;sql

import com.lonelyWolf.mybatis.model.UserAddress;
import org.apache.ibatis.annotations.Param;數據庫

public interface UserAddressMapper {
int insert(UserAddress userAddress);
}apache

注意:這裏參數若是直接只有一個的話能夠不使用@Param註解,這樣在xml文件中能夠直接使用JavaBean內的屬性名。若是使用了@Param註解,以下:

int insert(@Param("userAddress") UserAddress userAddress);設計模式

那麼xml文件中就可使用#{userAddress.屬性名}來獲取屬性JavaBean內的屬性

定義一個UserAddressMapper.xml映射文件(keyProperty="id"表示把主鍵的值設置到參數UserAddress類中的屬性id):
insert into lw_user_address (address) values (#{address})
mybatis-config.xml中要新增mapper映射文件配置:
而後寫一個測試類:

package com.lonelyWolf.mybatis;緩存

import com.lonelyWolf.mybatis.mapper.UserAddressMapper;
import com.lonelyWolf.mybatis.model.UserAddress;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;

public class TestMyBatisInsert {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
//讀取mybatis-config配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//建立SqlSessionFactory對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//建立SqlSession對象
SqlSession session = sqlSessionFactory.openSession();

try {
        UserAddress userAddress = new UserAddress();
        userAddress.setAddress("廣東深圳");
        UserAddressMapper userAddressMapper = session.getMapper(UserAddressMapper.class);
        int i = userAddressMapper.insert(userAddress);
        session.commit();
        System.out.println("插入成功數:" + i);
        System.out.println("插入數據的主鍵爲:" + userAddress.getId());
    }finally {
        session.close();
    }
}

}

輸出結果(成功獲取到了插入數據的主鍵):

插入成功數:1
插入數據的主鍵爲:1

## 經過selectKey獲取自定義列

假若有些數據庫不支持自增主鍵,或者說咱們想插入自定義的主鍵,而又不想在業務代碼中編寫邏輯,那麼就能夠經過MyBatis的selectKey來獲取。 UserAddressMapper.java中新建一個方法:

int insert2(UserAddress userAddress);

而後在UserAddressMapper.xml中對應新增一個insert2語句:
select uuid() from lw_user_address insert into lw_user_address (address) values (#{address})
而後修改測試類:

try {
UserAddress userAddress = new UserAddress();
UserAddressMapper userAddressMapper = session.getMapper(UserAddressMapper.class);
int i = userAddressMapper.insert2(userAddress);
session.commit();
System.out.println("插入成功數:" + i);
System.out.println("插入數據的address爲:" + userAddress.getAddress());
}finally {
session.close();
}

輸出結果以下,成功得到了咱們自定義的address:

插入成功數:1
插入數據的address爲:097dfc8b-f043-11ea-97c4-00163e12524a

selectKey中的order屬性有2個選擇:BEFORE和AFTER。

*   BEFORE:表示先執行selectKey的語句,而後將查詢到的值設置到JavaBean對應屬性上,而後再執行insert語句。

*   AFTER:表示先執行AFTER語句,而後再執行selectKey語句,並將selectKey獲得的值設置到JavaBean中的屬性。上面示例中若是改爲AFTER,那麼插入的address就會是空值,可是返回的JavaBean屬性內會有值。

PS:selectKey中返回的值只能有一條數據,若是知足條件的數據有多條會報錯,因此通常都是用於生成主鍵,確保惟一,或者在selectKey後面的語句加上條件,確保惟一

## update


### 最後

**給讀者們一個小福利,有須要這些資料的朋友們[能夠點擊我,便可免費](https://gitee.com/vip204888/java-p7)領取資料!**

### ActiveMQ消息中間件面試專題

*   什麼是ActiveMQ?
*   ActiveMQ服務器宕機怎麼辦?
*   丟消息怎麼辦?
*   持久化消息很是慢怎麼辦?
*   消息的不均勻消費怎麼辦?
*   死信隊列怎麼辦?
*   ActiveMQ中的消息重發時間間隔和重發次數嗎?

**ActiveMQ消息中間件面試專題解析拓展:**

![BAT面試文檔:ActiveMQ+redis+Spring+高併發多線程+JVM](https://upload-images.jianshu.io/upload_images/24616006-fa79b1b15dde1ab5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

* * *

# redis面試專題及答案

*   支持一致性哈希的客戶端有哪些?
*   Redis與其餘key-value存儲有什麼不一樣?
*   Redis的內存佔用狀況怎麼樣?
*   都有哪些辦法能夠下降Redis的內存使用狀況呢?
*   查看Redis使用狀況及狀態信息用什麼命令?
*   Redis的內存用完了會發生什麼?
*   Redis是單線程的,如何提升多核CPU的利用率?

![BAT面試文檔:ActiveMQ+redis+Spring+高併發多線程+JVM](https://upload-images.jianshu.io/upload_images/24616006-e5ba4e8af4bdfc80.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

* * *

# **Spring面試專題及答案**

*   談談你對 Spring 的理解
*   Spring 有哪些優勢?
*   Spring 中的設計模式
*   怎樣開啓註解裝配以及經常使用註解
*   簡單介紹下 Spring bean 的生命週期

**Spring面試答案解析拓展**

![BAT面試文檔:ActiveMQ+redis+Spring+高併發多線程+JVM](https://upload-images.jianshu.io/upload_images/24616006-a9d4433e066959fe.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

* * *

# 高併發多線程面試專題

*   如今有線程 T一、T2 和 T3。你如何確保 T2 線程在 T1 以後執行,而且 T3 線程在 T2 以後執行?
*   Java 中新的 Lock 接口相對於同步代碼塊(synchronized block)有什麼優點?若是讓你實現一個高性能緩存,支持併發讀取和單一寫入,你如何保證數據完整性。
*   Java 中 wait 和 sleep 方法有什麼區別?
*   如何在 Java 中實現一個阻塞隊列?
*   如何在 Java 中編寫代碼解決生產者消費者問題?
*   寫一段死鎖代碼。你在 Java 中如何解決死鎖?

**高併發多線程面試解析與拓展**

![BAT面試文檔:ActiveMQ+redis+Spring+高併發多線程+JVM](https://upload-images.jianshu.io/upload_images/24616006-c4541cf1119c4aa8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

* * *

# jvm面試專題與解析

*   JVM 由哪些部分組成?
*   JVM 內存劃分?
*   Java 的內存模型?
*   引用的分類?
*   GC何時開始?

**JVM面試專題解析與拓展!**

![BAT面試文檔:ActiveMQ+redis+Spring+高併發多線程+JVM](https://upload-images.jianshu.io/upload_images/24616006-95f797046a7bbaaf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
相關文章
相關標籤/搜索