當下,註解很是流行,之前很長篇的代碼,如今基本上一個註解就能搞定。java
那,在Mybatis
中又有哪些註解呢?spring
Mybatis
中的註解基本上都在org.apache.ibatis.annotations
目錄下:數據庫
@MapperScan
該註解存在着爭議,但不能否認的是這個註解確實是Mybatis
的註解,是爲了集成Spring而寫的註解。該註解主要是掃描某個包目錄下的Mapper,將Mapper接口類交給Spring進行管理。apache
org.mybatis.spring.annotation.MapperScan
@SpringBootApplication
@MapperScan("com.tian.mybatis.mapper")
public class Application {
}
其實,從名字上就能看出,是用來掃描的Mapper的。數組
掃描包路徑能夠是一個或者多個,也能夠在路徑中可使用 * 做爲通配符對包名進行匹配 。緩存
@SpringBootApplication
@MapperScan("com.tian.*.mapper")
public class Application {
}
@SpringBootApplication
@MapperScan({"com.tian.mybatis.mapper","com.tian.mybatis.mapper1"})
public class Application {
}
靈活度至關高,這樣在實際上項目中,咱們就能夠指定掃描想要被掃描的包路徑。mybatis
該註解目的就是爲了避免再寫mapper映射文件 (UserMapper.xml
)。能夠大大的簡化編寫xml的繁瑣。該註解是由Mybatis框架中定義的一個描述數據層接口的註解,註解每每起到的都是一個描述性做用,用於告訴Spring框架此接口的實現類由Mybatis負責建立,並將其實現類對象存儲到spring容器中。app
@Mapper
public interface UserMapper {
User selectById(Integer id);
}
插入記錄的時候主鍵如何生成?對此基本上有三種方案,分別是:手動指定(應用層)、自增主鍵(數據層單表)、選擇主鍵(數據層多表)。框架
對應xml文件中的<insert>
標籤。ide
手動指定的方式不把主鍵區別看待,插入以前在應用層生成對象的時候就會給主鍵一個值,插入的時候與普通字段沒啥區別。
/**
* 插入記錄,手動分配主鍵
*/
@Insert("INSERT INTO t_user (id, username, passwd) VALUES (#{id}, #{username}, #{passwd})")
int addUserAssignKey(User user);
在上面的這個例子中,mybatis並不知道到底哪一個字段是主鍵,id雖然是主鍵字段,但並無被區別對待。
「注意」
#{username}這種寫法,是把User做爲了當前上下文,這樣訪問User的屬性的時候直接寫屬性名字就能夠了。
自增主鍵對應着XML配置中的主鍵回填,一個簡單的例子:
/**
* 插入記錄,數據庫生成主鍵
*/
@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("INSERT INTO t_user (username, passwd) VALUES (#{username}, #{passwd})")
int addUserGeneratedKey(User user);
使用Option來對應着XML設置的select標籤的屬性,userGeneratordKeys表示要使用自增主鍵,keyProperty用來指定主鍵字段的字段名。自增主鍵會使用數據庫底層的自增特性。
選擇主鍵從數據層生成一個值,並用這個值做爲主鍵的值。
/**
* 插入記錄,選擇主鍵
*/
@Insert("INSERT INTO t_user (username, passwd) VALUES (#{username}, #{passwd})")
@SelectKey(statement = "SELECT UNIX_TIMESTAMP(NOW())", keyColumn = "id", keyProperty = "id", resultType = Long.class, before = true)
int addUserSelectKey(User user);
刪除的時候只要把語句條件神馬的寫在@Delete註解的value裏就行了,返回一個int類型是被成功刪除的記錄數。對應xml文件中的<delete>
標籤。
/**
* 刪除記錄
*/
@Delete("DELETE FROM t_user WHERE id=#{id}")
int delete(Long id);
修改的時候和刪除同樣只要把SQL
語句寫在@Update的value中就行了,返回一個int類型表示被修改的記錄行數。
對應xml文件中的<update>
標籤。
/**
* 修改記錄
*/
@Update("UPDATE t_user SET username=#{username}, passwd=#{passwd} WHERE id=#{id}")
int update(User user);
查詢的時候稍稍有些複雜,由於查詢會涉及到如何將查出來的字段設置到對象上,對應xml文件中的<select>
標籤。
一般有那麼三種辦法:
在寫SQL語句的時候,手動爲每個字段指定一個別名來跟對象的屬性作匹配,適用於表字段名與對象屬性名差別很大沒有規律而且表字段很少的狀況。
/**
* 根據ID查詢,手動設置別名
*/
@Select("SELECT id, username, passwd, birth_day AS birthDay FROM t_user WHERE id=#{id}")
User loadByIdHandAlias(Long id);
mybatis有一個選項叫mapUnderscoreToCamelCase,當表中的字段名與對象的屬性名相同只是下劃線和駝峯寫法的差別時適用。
配置了mapUnderscoreToCamelCase以後mybatis在將ResultSet查出的數據設置到對象的時候會嘗試先將下劃線轉換爲駝峯而後前面拼接set去設置屬性。
開啓轉換:
而後查詢
/**
* 根據ID查詢,開了自動駝峯轉換
*/
@Select("SELECT * FROM t_user WHERE id=#{id}")
User loadByIdAutoAlias(Long id);
查看打印的結果,birth_day屬性填充到了對象中:
對於表的字段名和對象的屬性名沒有太大相同點而且表中的字段挺多的狀況下,應該使用ResultMap作適配。
/**
* 使用ResultMap
*/
@Results(id = "userMap", value = {
//可使用這種方式來處理字段名和數據庫表字段名不一致的狀況
@Result(id=true, column = "id", property = "id"),
@Result(column = "username", property = "username"),
@Result(column = "passwd", property = "passwd"),
@Result(column = "birth_day", property = "birthDay")
})
@Select("SELECT * FROM t_user WHERE id=#{id}")
User loadByIdResultMap(Long id);
@Results對應着XML中的ResultMap,同時能夠爲其指定一個id,其它地方可使用這個id來引用它,好比要引用上面的這個Results:
/**
* 引用其餘的Result
*/
@ResultMap("userMap")
@Select("SELECT * FROM t_user WHERE id=#{id}")
User loadByIdResultMapReference(Long id);
使用@ResultMap來引用一個已經存在的ResultMap,這個ResultMap能夠是在Java中使用@Results註解定義的,也能夠是在XML中使用resultMap標籤訂義的。
@Results:結果映射的列表, 包含了一個特別結果列如何被映射到屬性或字段的詳情。屬 性:value, id。value 屬性是 Result 註解的數組。對應xml中的<resultMap>
標籤。
@Result:在列和屬性或字段之間的單獨結果映 射。屬 性:id,column, property, javaType ,jdbcType ,type Handler, one,many。id 屬性是一個布爾值,表 示了應該被用於比較(和在 XML 映射 中的類似)的屬性。one 屬性是單 獨 的 聯 系, 和 <association>
相 似 , 而 many 屬 性 是 對 集 合 而 言 的 , 和 <collection>
類似。它們這樣命名是爲了 避免名稱衝突。相似於<resultMap>
的子標籤 <result>``<id>
。
@One:複雜類型的單獨屬性值映射。屬性: select,已映射語句(也就是映射器方 法)的徹底限定名,它能夠加載合適類 型的實例。注意:聯合映射在註解 API 中是不支持的。這是由於 Java 註解的 限制,不容許循環引用。相似於<association>
標籤。
@Many:與@One相似,一對多的關係,相似於<collection>
@Param :參數標籤,咱們在Mapper的方法簽名上標註的參數,咱們能夠指定參數名稱,而後在註解中或者xml中的SQL裏就可使用咱們自定義的參數名稱。
@SelectKey :獲取最新插入id。
@CacheNamespace :爲給定的命名空間 (好比類) 配置緩存。對應xml中的<cache>
。
@CacheNamespaceRef :參照另一個命名空間的緩存來使用。屬性:value,應該是一個名空間的字 符串值(也就是類的徹底限定名) 。對應xml中的<cacheRef>
標籤。
@ConstructorArgs :收集一組結果傳遞給一個劫奪對象的 構造方法。屬性:value,是形式參數 的數組。
@Arg :單 獨 的 構 造 方 法 參 數 , 是 ConstructorArgs 集合的一部分。屬性: id,column,javaType,typeHandler。id 屬性是布爾值, 來標識用於比較的屬 性,和XML 元素類似。對應xml中的<arg>
標籤。
@Case :單獨實例的值和它對應的映射。屬性: value,type,results。Results 屬性是結 果數組,所以這個註解和實際的 ResultMap 很類似,由下面的 Results 註解指定。對應xml中標籤<case>
。
mybatis最初配置信息是基於 XML ,映射語句(SQL)也是定義在 XML 中的。而到了 MyBatis 3提供了新的基於註解的配置。mybatis提供的註解有不少,筆者進行了分類:
絕大部分註解,在xml映射文件中都有元素與之對應,可是不是全部。此外在mybatis-spring中提供了@Mapper註解和@MapperScan註解,用於和spring進行整合。