目錄
1 SQL 映射文件介紹
2 select 元素
3 insert 元素
4?update 和 delete 元素
5?sql 元素? ? ? ?
6?parameterType 元素
7?resultType 元素
8?resultMap 元素(重要)
9 參考文檔
1 SQL 映射文件介紹
????????映射器是 MyBatis 中最復雜并且是最重要的組件。它由一個接口和 SQL 映射文件(或者注解)組成。在映射器中我們可以配置各類 SQL、動態 SQL、緩存、存儲過程、級聯等復雜的內容。
以下是 SQL 映射文件的部分元素介紹
元素 | 描述 |
---|---|
cache | 該命名空間的緩存配置 |
cache-ref | 引用其它命名空間的緩存配置 |
resultMap | 描述如何從數據庫結果集中加載對象,它是最復雜也是最強大的元素 |
sql | 可被其它語句引用的可重用語句塊 |
select | 映射查詢語句 |
insert | 映射插入語句 |
update | 映射更新語句 |
delete | 映射刪除語句 |
2 select 元素
select 元素表示 SQL 的 select 語句,用于查詢,以下是 select 元素的部分屬性
屬性 | 描述 |
---|---|
id | 在命名空間中唯一的標識符,可以被用來引用這條語句 |
parameterType | 將會傳入這條語句的參數類的全類名或別名。這個屬性是可選的,因為 MyBatis 可以通過類型處理器(TypeHandler) 推斷出具體傳入語句的參數,默認值為未設置(unset) |
resultType | 從這條語句中返回的期望類型的類的全類名或別名。 注意如果返回的是集合,那應該設置為集合包含的類型,而不是集合本身。可以使用 resultType 或 resultMap,但不能同時使用 |
resultMap | 外部 resultMap 的命名引用。結果集的映射是 MyBatis 最強大的特性,如果你對其理解透徹,許多復雜映射的情形都能迎刃而解。可以使用 resultMap 或 resultType,但不能同時使用 |
flushCache | 將其設置為 true 后,只要語句被調用,都會導致本地緩存和二級緩存被清空,默認值:false |
useCache | 將其設置為 true 后,將會導致本條語句的結果被二級緩存緩存起來,默認值:對 select 元素為 true |
timeout | 這個設置是在拋出異常之前,驅動程序等待數據庫返回請求結果的秒數。默認值為未設置(unset)(依賴驅動) |
fetchSize | 這是一個給驅動的提示,嘗試讓驅動程序每次批量返回的結果行數和這個設置值相等。 默認值為未設置(unset)(依賴驅動) |
statementType | STATEMENT,PREPARED 或 CALLABLE 中的一個。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認值:PREPARED |
resultSetType | FORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等價于 unset) 中的一個,默認值為 unset (依賴驅動) |
databaseId | 如果配置了數據庫廠商標識 (databaseIdProvider) 并且存在兩個相同的語句,一個帶 databaseId 而另一個不帶,MyBatis 會優先加載帶有 databaseId 的語句。如果 databaseId 與當前數據庫匹配,則不帶 databaseId 的相同語句將被忽略。未設置?databaseId 使用通用 SQL 規則 |
resultOrdered | resultOrdered:這個設置僅對嵌套結果 select 語句適用:如果為 true,就是假設包含了嵌套結果集或是分組,這樣的話當返回一個主結果行的時候,就不會發生有對前面結果集的引用的情況。 這就使得在獲取嵌套的結果集的時候不至于導致內存不夠用。默認值:false |
resultSets | 這個設置僅對多結果集的情況適用。它將列出語句執行后返回的結果集并給每個結果集一個名稱,名稱是逗號分隔的 |
3 insert 元素
屬性 | 描述 |
---|---|
id | 在命名空間中唯一的標識符,可以被用來引用這條語句 |
parameterType | 將會傳入這條語句的參數的類全限定名或別名。這個屬性是可選的,因為 MyBatis 可以通過類型處理器(TypeHandler)推斷出具體傳入語句的參數,默認值為未設置(unset) |
flushCache | 將其設置為 true 后,只要語句被調用,都會導致本地緩存和二級緩存被清空,默認值:(對 insert、update 和 delete 語句)true |
timeout | 這個設置是在拋出異常之前,驅動程序等待數據庫返回請求結果的秒數。默認值為未設置(unset)(依賴數據庫驅動) |
statementType | 可選 STATEMENT,PREPARED 或 CALLABLE。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認值:PREPARED |
useGeneratedKeys | (僅適用于 insert 和 update)這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數據庫內部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關系型數據庫管理系統的自動遞增字段),默認值:false |
keyProperty | (僅適用于 insert 和 update)指定能夠唯一識別對象的屬性,MyBatis 會使用 getGeneratedKeys 的返回值或 insert 語句的 selectKey 子元素設置它的值,默認值:未設置(unset)。如果生成列不止一個,可以用逗號分隔多個屬性名稱。不能和keyColumn連用 |
keyColumn | (僅適用于 insert 和 update)設置生成鍵值在表中的列名,在某些數據庫(像 PostgreSQL)中,當主鍵列不是表中的第一列的時候,是必須設置的。如果生成列不止一個,可以用逗號分隔多個屬性名稱。不能和keyProperty連用 |
databaseId | 同 select 元素 |
主鍵回填
? ? ? ? 在 MyBatis 中,若表中的主鍵設置為自增,插入數據時沒有插入主鍵,但是又想獲得數據庫中該條數據的主鍵,那么可以通過設置 useGeneratedKeys=”true”,然后再把 keyProperty 設置到目標屬性(如 User 類中的 id 屬性)上來獲得該值。
<insert id="insertUser" parameterType="com.entity.User" useGeneratedKeys="true" keyProperty="id">insert into person(name, age, sex)values (#{name}, #{age}, #{sex});
</insert>
//添加一個用戶數據
@Test
public void testInsertUser() {String statement = "com.mapper.UserMapper.insertUser";User user = new User();user.setName("孫尚香");user.setAge(24);user.setSex("女");int i = sqlSession.insert(statement, user);System.out.println( (i>0)? "添加成功!":"添加失敗!");//提交插入的數據sqlSession.commit();sqlSession.close();// 輸出返回的主鍵值System.out.println("返回的主鍵值=" + user.getId());
}
自定義主鍵并且可以在 Java 中通過屬性獲得該值
在 MyBatis 中可以通過?selectKey 元素自定義主鍵,以下是其屬性介紹
- keyProperty:selectKey 需要設置的目標屬性
- resultType:結果類型
- order:可以設置為 BEFORE 或 AFTER ,表示先設置主鍵,后執行插入語句或先執行插入語句,后設置主鍵
<insert id="insertUser" parameterType="com.entity.User" ><selectKey keyProperty="id" resultType="int" order="BEFORE">select ROUND(RAND()*1000)</selectKey>insert into person(id, name, age, sex)values (#{id}, #{name}, #{age}, #{sex});
</insert>
@Test
public void testInsertUser() {String statement = "com.mapper.UserMapper.insertUser";User user = new User();user.setName("鄭旦");user.setAge(24);user.setSex("女");int i = sqlSession.insert(statement, user);System.out.println( (i>0)? "添加成功!":"添加失敗!");//提交插入的數據sqlSession.commit();sqlSession.close();// 輸出返回的主鍵值System.out.println("返回的主鍵值=" + user.getId());
}
??
4?update 和 delete 元素
????????update 和 delete 元素在使用上比較簡單,所以這里把它們放在一起論述。它們和 insert 元素的屬性差不多,執行完后也會返回一個整數,用來表示該 SQL 語句影響了多少條數據庫記錄。
<!-- 根據 id 更新用戶 -->
<update id="updateUser">update person set name = #{name},age = #{age},sex = #{sex} where id = #{id}
</update>
<!-- 根據 id 刪除用戶 -->
<delete id="deleteUser" parameterType="int">delete from person where id = #{id}
</delete>
5?sql 元素? ? ? ?
????????sql 元素是用來定義可重用的 sql 代碼片段,這樣在字段比較多的時候,以便在其它語句中使用。需要結合 include 元素一起使用,以下是代碼示例。
<!--定義sql代碼片段-->
<sql id="userCols">id,username,age,sex
</sql>
<!-- 查詢所有用戶 -->
<select id="selectAllUser" resultType="com.entity.User">select <include refid="userCols"/> from person
</select>
6?parameterType 元素
parameterType 元素可以輸入以下類型:
- Java 基本數據類型
- POJO 類型
- Map 類型
<!-- 通過 普通數據類型 int 查詢一個用戶 -->
<select id="selectUserById" parameterType="int" resultType="com.entity.User">select * from person where id = #{id};
</select><!-- 通過 POJO 類型 User 添加用戶-->
<insert id="insertUser" parameterType="com.entity.User">insert into person(id,username,age,sex) values (#{id},#{username},#{age},#{sex});
</insert><!-- 通過 嵌套 POJO 類型 查詢一個用戶,QueryVo 類中定義了 User user 屬性 -->
<select id="selectUserByUserNameAndAge" parameterType="com.entity.QueryVo" resultType="com.entity.User">select * from person where name = #{user.name} and age = #{user.age};
</select><!-- 通過 Map 類型 查詢一個用戶, HashMap<String, Object> map = new HashMap<>();
map.put("name","趙飛燕"); map.put("age",24); 通過 key 獲得 map 中的 value-->
<select id="selectUserByMap" parameterType="hashmap" resultType="com.entity.User">select * from person where name = #{name} and age = #{age};
</select>
7?resultType 元素
resultType 元素和 parameterType 元素用法差不多,一個是輸出,一個是輸入。resultType 元素可以輸出以下類型:
- Java 基本數據類型
- POJO 對象
- POJO 對象列表
- Map 對象列表
<!-- 統計用戶總數量,輸出為一個整數 int -->
<select id="countUsers" resultType="int">select count(1) from person
</select><!-- 通過 id 查詢一個用戶,輸出為一個 User -->
<select id="selectUserById" parameterType="int" resultType="com.entity.User">select * from personwhere id = #{id};
</select><!-- 查詢所有用戶,輸出為一個 List<User> 列表 -->
<select id="selectAllUser" resultType="com.entity.User">select * from person
</select><!-- 查詢所有用戶, 輸出為一個 List<HashMap<String, Object>> Map 列表-->
<select id="selectAllUser" resultType="hashmap">select * from person
</select>
8?resultMap 元素(重要)
????????我們在使用 resultType 的時候,需要保證數據庫表中的字段名和表對應實體類的屬性名稱一致才行(包括駝峰命名規則)。那不一致怎么辦,查詢的時候可以給列名起個別名,但是一般不建議這樣做,而是通過 resultMap 元素進行一個轉換。
<!-- id:唯一標識,type:需要映射的 Java 類型-->
<resultMap id="userMap" type="com.entity.User"><!-- 與主鍵字段的對應,property對應實體屬性,column對應表字段 --><id property="userId" column="id"/><!-- 與非主鍵字段的對應,property對應實體屬性,column對應表字段 --><result property="userName" column="username"/><result property="userAge" column="age"/><result property="userSex" column="sex"/>
</resultMap><!-- 查詢所有用戶,返回集為resultMap類型,resultMap的value上面配置的 id=userMap 要一致-->
<select id="selectAllUser" resultMap="userMap">select * from person
</select>
上述代碼是不是很眼熟,在 MyBatis 案例中使用了?@ResultMap 注解來實現上述代碼
resultMap 元素的組成
<!-- autoMapping:指定是否自動映射查詢結果的列到 Java 對象的屬性。
默認為開啟(true),如果設置為 false,則需要手動配置每個屬性的映射關系 -->
<resultMap id="標識" type="輸出類型" extends="繼承其他 <resultMap>" autoMapping="自動映射"><constructor><!--構造器注入屬性值--><!-- 構造器標識,一般為主鍵 --><!-- column對應表字段,name對應實體屬性 --><idArg column="id" name="userId" javaType="int"/><!-- 構造器參數 --><arg column="username" name="userName" javaType="string"/> </constructor><!-- id 與主鍵字段的對應,property對應實體屬性,column對應表字段 --><id property="userId" column="id"/><!-- result 與非主鍵字段的對應,property對應實體屬性,column對應表字段 --><result property="userName" column="username"/><association/><!--高級映射,一對一映射--><collection /><!--高級映射,一對多映射--><discriminator><case/></discriminator><!--根據返回的字段的值封裝不同的類型-->
</resultMap>
9 參考文檔
Mybatis3詳解(四)----SQL映射文件詳解(XxxMapper.xml) - 唐浩榮 - 博客園 (cnblogs.com)