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
## 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):
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語句:
而後修改測試類:
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)