既然你已經(jīng)知道如何配置 MyBatis 和創(chuàng)建映射文件,你就已經(jīng)準(zhǔn)備好來提升技能了。 MyBatis 的 Java API 就是你收獲你所做的努力的地方。正如你即將看到的,和 JDBC 相比, MyBatis 很大程度簡化了你的代碼而且保持簡潔,很容易理解和維護。MyBatis 3 已經(jīng)引入 了很多重要的改進來使得 SQL 映射更加優(yōu)秀。
在我們深入 Java API 之前,理解關(guān)于目錄結(jié)構(gòu)的最佳實踐是很重要的。MyBatis 非常靈 活, 你可以用你自己的文件來做幾乎所有的事情。 但是對于任一框架, 都有一些最佳的方式。
讓我們看一下典型應(yīng)用的目錄結(jié)構(gòu):
/my_application
/bin
/devlib
/lib <-- MyBatis *.jar文件在這里。
/src
/org/myapp/
/action
/data <-- MyBatis配置文件在這里, 包括映射器類, XML配置, XML映射文件。
/mybatis-config.xml
/BlogMapper.java
/BlogMapper.xml
/model
/service
/view
/properties <-- 在你XML中配置的屬性 文件在這里。
/test
/org/myapp/
/action
/data
/model
/service
/view
/properties
/web
/WEB-INF
/web.xml
Remember, these are preferences, not requirements, but others will thank you for using a common directory structure.
這部分內(nèi)容剩余的示例將假設(shè)你使用了這種目錄結(jié)構(gòu)。
使用 MyBatis 的主要 Java 接口就是 SqlSession。盡管你可以使用這個接口執(zhí)行命令,獲 取映射器和管理事務(wù)。我們會討論 SqlSession 本身更多,但是首先我們還是要了解如果獲取 一個 SqlSession 實例。SqlSessions 是由 SqlSessionFactory 實例創(chuàng)建的。SqlSessionFactory 對 象 包 含 創(chuàng) 建 SqlSession 實 例 的 所 有 方 法 。 而 SqlSessionFactory 本 身 是 由 SqlSessionFactoryBuilder 創(chuàng)建的,它可以從 XML 配置,注解或手動配置 Java 來創(chuàng)建 SqlSessionFactory。
注意 當(dāng) MyBatis 與 Spring 或 Guice 等依賴注入框架一起使用時,SqlSessions 由 DI 框架創(chuàng)建和注入,因此您不需要使用 SqlSessionFactoryBuilder 或 SqlSessionFactory,可以直接進入 SqlSession 部分。 請參閱 MyBatis-Spring 或 MyBatis-Guice 手冊以獲取更多信息。
SqlSessionFactoryBuilder 有五個 build()方法,每一種都允許你從不同的資源中創(chuàng)建一個 SqlSession 實例。
SqlSessionFactory build(InputStream inputStream)
SqlSessionFactory build(InputStream inputStream, String environment)
SqlSessionFactory build(InputStream inputStream, Properties properties)
SqlSessionFactory build(InputStream inputStream, String env, Properties props)
SqlSessionFactory build(Configuration config)
第一種方法是最常用的,它使用了一個參照了 XML 文檔或上面討論過的更特定的 mybatis-config.xml 文件的 Reader 實例。 可選的參數(shù)是 environment 和 properties。 Environment 決定加載哪種環(huán)境,包括數(shù)據(jù)源和事務(wù)管理器。比如:
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
...
<dataSource type="POOLED">
...
</environment>
<environment id="production">
<transactionManager type="MANAGED">
...
<dataSource type="JNDI">
...
</environment>
</environments>
如果你調(diào)用了 一個使用 environment 參數(shù) 方 式的 build 方法, 那么 MyBatis 將會使用 configuration 對象來配置這個 environment。 當(dāng)然, 如果你指定了一個不合法的 environment, 你會得到錯誤提示。 如果你調(diào)用了其中之一沒有 environment 參數(shù)的 build 方法, 那么就使用 默認(rèn)的 environment(在上面的示例中就會指定為 default="development")。
如果你調(diào)用了使用 properties 實例的方法,那么 MyBatis 就會加載那些 properties(屬性 配置文件) ,并你在你配置中可使用它們。那些屬性可以用${propName}語法形式多次用在 配置文件中。
回想一下,屬性可以從 mybatis-config.xml 中被引用,或者直接指定它。因此理解優(yōu)先 級是很重要的。我們在文檔前面已經(jīng)提及它了,但是這里要再次重申:
如果一個屬性存在于這些位置,那么 MyBatis 將會按找下面的順序來加載它們:
因此,最高優(yōu)先級的屬性是通過方法參數(shù)傳遞的,之后是 resource/url 屬性指定的,最 后是在 properties 元素體中指定的屬性。
總結(jié)一下,前四個方法很大程度上是相同的,但是由于可以覆蓋,就允許你可選地指定 environment 和/或 properties。 這里給出一個從 mybatis-config.xml 文件創(chuàng)建 SqlSessionFactory 的示例:
String **resource** = "org/mybatis/builder/mybatis-config.xml";
InputStream **inputStream** = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder **builder** = new SqlSessionFactoryBuilder();
SqlSessionFactory **factory** = builder.build(inputStream);
注意這里我們使用了 Resources 工具類,這個類在 org.mybatis.io 包中。Resources 類正 如其名,會幫助你從類路徑下,文件系統(tǒng)或一個 web URL 加載資源文件。看一下這個類的 源代碼或者通過你的 IDE 來查看,就會看到一整套有用的方法。這里給出一個簡表:
URL getResourceURL(String resource)
URL getResourceURL(ClassLoader loader, String resource)
InputStream getResourceAsStream(String resource)
InputStream getResourceAsStream(ClassLoader loader, String resource)
Properties getResourceAsProperties(String resource)
Properties getResourceAsProperties(ClassLoader loader, String resource)
Reader getResourceAsReader(String resource)
Reader getResourceAsReader(ClassLoader loader, String resource)
File getResourceAsFile(String resource)
File getResourceAsFile(ClassLoader loader, String resource)
InputStream getUrlAsStream(String urlString)
Reader getUrlAsReader(String urlString)
Properties getUrlAsProperties(String urlString)
Class classForName(String className)
最后一個 build 方法使用了一個 Configuration 實例。configuration 類包含你可能需要了 解 SqlSessionFactory 實例的所有內(nèi)容。Configuration 類對于配置的自查很有用,包含查找和 操作 SQL 映射(不推薦使用,因為應(yīng)用正接收請求) 。configuration 類有所有配置的開關(guān), 這些你已經(jīng)了解了,只在 Java API 中露出來。這里有一個簡單的示例,如何手動配置 configuration 實例,然后將它傳遞給 build()方法來創(chuàng)建 SqlSessionFactory。
DataSource dataSource = BaseDataTest.createBlogDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.setLazyLoadingEnabled(true);
configuration.setEnhancementEnabled(true);
configuration.getTypeAliasRegistry().registerAlias(Blog.class);
configuration.getTypeAliasRegistry().registerAlias(Post.class);
configuration.getTypeAliasRegistry().registerAlias(Author.class);
configuration.addMapper(BoundBlogMapper.class);
configuration.addMapper(BoundAuthorMapper.class);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(configuration);
現(xiàn)在你有一個 SqlSessionFactory,可以用來創(chuàng)建 SqlSession 實例。
SqlSessionFactory 有六個方法可以用來創(chuàng)建 SqlSession 實例。通常來說,如何決定是你 選擇下面這些方法時:
重載的 openSession()方法簽名設(shè)置允許你選擇這些可選中的任何一個組合。
SqlSession openSession()
SqlSession openSession(boolean autoCommit)
SqlSession openSession(Connection connection)
SqlSession openSession(TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType,TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType)
SqlSession openSession(ExecutorType execType, boolean autoCommit)
SqlSession openSession(ExecutorType execType, Connection connection)
Configuration getConfiguration();
默認(rèn)的 openSession()方法沒有參數(shù),它會創(chuàng)建有如下特性的 SqlSession:
這些方法大都可以自我解釋的。 開啟自動提交, "true" 傳遞 給可選的 autoCommit 參數(shù)。 提供自定義的連接,傳遞一個 Connection 實例給 connection 參數(shù)。注意沒有覆蓋同時設(shè)置 Connection 和 autoCommit 兩者的方法,因為 MyBatis 會使用當(dāng)前 connection 對象提供的設(shè) 置。 MyBatis 為事務(wù)隔離級別調(diào)用使用一個 Java 枚舉包裝器, 稱為 TransactionIsolationLevel, 否則它們按預(yù)期的方式來工作,并有 JDBC 支持的 5 級 ( NONE,READ_UNCOMMITTED,READ_COMMITTED,REPEA TABLE_READ,SERIALIZA BLE)
還有一個可能對你來說是新見到的參數(shù),就是 ExecutorType。這個枚舉類型定義了 3 個 值:
ExecutorType.SIMPLE
: 這個執(zhí)行器類型不做特殊的事情。它為每個語句的執(zhí)行創(chuàng)建一個新的預(yù)處理語句。ExecutorType.REUSE
: 這個執(zhí)行器類型會復(fù)用預(yù)處理語句。ExecutorType.BATCH
: 這個執(zhí)行器會批量執(zhí)行所有更新語句,如果 SELECT 在它們中間執(zhí)行還會標(biāo)定它們是 必須的,來保證一個簡單并易于理解的行為。注意 在 SqlSessionFactory 中還有一個方法我們沒有提及,就是 getConfiguration()。這 個方法會返回一個 Configuration 實例,在運行時你可以使用它來自檢 MyBatis 的配置。
注意 如果你已經(jīng)使用之前版本 MyBatis,你要回憶那些 session,transaction 和 batch 都是分離的?,F(xiàn)在和以往不同了,這些都包含在 session 的范圍內(nèi)了。你需要處理分開處理 事務(wù)或批量操作來得到它們的效果。
如上面所提到的,SqlSession 實例在 MyBatis 中是非常強大的一個類。在這里你會發(fā)現(xiàn) 所有執(zhí)行語句的方法,提交或回滾事務(wù),還有獲取映射器實例。
在 SqlSession 類中有超過 20 個方法,所以將它們分開成易于理解的組合。
這些方法被用來執(zhí)行定義在 SQL 映射的 XML 文件中的 SELECT,INSERT,UPDA E T 和 DELETE 語句。它們都會自行解釋,每一句都使用語句的 ID 屬性和參數(shù)對象,參數(shù)可以 是原生類型(自動裝箱或包裝類) ,JavaBean,POJO 或 Map。
T selectOne(String statement, Object parameter)
List selectList(String statement, Object parameter)
Map selectMap(String statement, Object parameter, String mapKey)
int insert(String statement, Object parameter)
int update(String statement, Object parameter)
int delete(String statement, Object parameter)
selectOne 和 selectList 的不同僅僅是 selectOne 必須返回一個對象。 如果多余一個, 或者 沒有返回 (或返回了 null) 那么就會拋出異常。 , 如果你不知道需要多少對象, 使用 selectList。
如果你想檢查一個對象是否存在,那么最好返回統(tǒng)計數(shù)(0 或 1) 。因為并不是所有語句都需 要參數(shù),這些方法都是有不同重載版本的,它們可以不需要參數(shù)對象。
T selectOne(String statement)
List selectList(String statement)
Map selectMap(String statement, String mapKey)
int insert(String statement)
int update(String statement)
int delete(String statement)
最后,還有查詢方法的三個高級版本,它們允許你限制返回行數(shù)的范圍,或者提供自定 義結(jié)果控制邏輯,這通常用于大量的數(shù)據(jù)集合。
<E> List<E> selectList (String statement, Object parameter, RowBounds rowBounds)
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowbounds)
void select (String statement, Object parameter, ResultHandler<T> handler)
void select (String statement, Object parameter, RowBounds rowBounds, ResultHandler<T> handler)
RowBounds 參數(shù)會告訴 MyBatis 略過指定數(shù)量的記錄,還有限制返回結(jié)果的數(shù)量。 RowBounds 類有一個構(gòu)造方法來接收 offset 和 limit,否則是不可改變的。
int offset = 100;
int limit = 25;
RowBounds rowBounds = new RowBounds(offset, limit);
不同的驅(qū)動會實現(xiàn)這方面的不同級別的效率。對于最佳的表現(xiàn),使用結(jié)果集類型的 SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE(或句話說:不是 FORWARD_ONLY)。
ResultHandler 參數(shù)允許你按你喜歡的方式處理每一行。你可以將它添加到 List 中,創(chuàng) 建 Map, 或拋出每個結(jié)果而不是只保留總計。 Set 你可以使用 ResultHandler 做很多漂亮的事, 那就是 MyBatis 內(nèi)部創(chuàng)建結(jié)果集列表。
它的接口很簡單。
package org.apache.ibatis.session;
public interface ResultHandler {
void handleResult(ResultContext context);
}
ResultContext 參數(shù)給你訪問結(jié)果對象本身的方法, 大量結(jié)果對象被創(chuàng)建, 你可以使用布 爾返回值的 stop()方法來停止 MyBatis 加載更多的結(jié)果。
控制事務(wù)范圍有四個方法。 當(dāng)然, 如果你已經(jīng)選擇了自動提交或你正在使用外部事務(wù)管 理器,這就沒有任何效果了。然而,如果你正在使用 JDBC 事務(wù)管理員,由 Connection 實 例來控制,那么這四個方法就會派上用場:
void commit()
void commit(boolean force)
void rollback()
void rollback(boolean force)
默認(rèn)情況下 MyBatis 不會自動提交事務(wù), 除非它偵測到有插入, 更新或刪除操作改變了 數(shù)據(jù)庫。如果你已經(jīng)做出了一些改變而沒有使用這些方法,那么你可以傳遞 true 到 commit 和 rollback 方法來保證它會被提交(注意,你不能在自動提交模式下強制 session,或者使用 了外部事務(wù)管理器時) 。很多時候你不用調(diào)用 rollback(),因為如果你沒有調(diào)用 commit 時 MyBatis 會替你完成。然而,如果你需要更多對多提交和回滾都可能的 session 的細(xì)粒度控 制,你可以使用回滾選擇來使它成為可能。
NOTE MyBatis-Spring and MyBatis-Guice provide declarative transaction handling. So if you are using MyBatis with Spring or Guice please refer to their specific manuals.
void clearCache()
SqlSession 實例有一個本地緩存在執(zhí)行 update,commit,rollback 和 close 時被清理。要 明確地關(guān)閉它(獲取打算做更多的工作) ,你可以調(diào)用 clearCache()。
void close()
你必須保證的最重要的事情是你要關(guān)閉所打開的任何 session。保證做到這點的最佳方 式是下面的工作模式:
SqlSession session = sqlSessionFactory.openSession();
try {
// following 3 lines pseudocod for "doing some work"
session.insert(...);
session.update(...);
session.delete(...);
session.commit();
} finally {
session.close();
}
Or, If you are using jdk 1.7+ and MyBatis 3.2+, you can use the try-with-resources statement:
try (SqlSession session = sqlSessionFactory.openSession()) {
// following 3 lines pseudocode for "doing some work"
session.insert(...);
session.update(...);
session.delete(...);
session.commit();
}
注意 就像 SqlSessionFactory,你可以通過調(diào)用 getConfiguration()方法獲得 SqlSession 使用的 Configuration 實例
Configuration getConfiguration()
T getMapper(Class type)
上述的各個 insert,update,delete 和 select 方法都很強大,但也有些繁瑣,沒有類型安 全,對于你的 IDE 也沒有幫助,還有可能的單元測試。在上面的入門章節(jié)中我們已經(jīng)看到 了一個使用映射器的示例。
因此, 一個更通用的方式來執(zhí)行映射語句是使用映射器類。 一個映射器類就是一個簡單 的接口,其中的方法定義匹配于 SqlSession 方法。下面的示例展示了一些方法簽名和它們是 如何映射到 SqlSession 的。
public interface AuthorMapper {
// (Author) selectOne("selectAuthor",5);
Author selectAuthor(int id);
// (List) selectList("selectAuthors")
List selectAuthors();
// (Map) selectMap("selectAuthors", "id")
@MapKey("id")
Map selectAuthors();
// insert("insertAuthor", author)
int insertAuthor(Author author);
// updateAuthor("updateAuthor", author)
int updateAuthor(Author author);
// delete("deleteAuthor",5)
int deleteAuthor(int id);
}
總之, 每個映射器方法簽名應(yīng)該匹配相關(guān)聯(lián)的 SqlSession 方法, 而沒有字符串參數(shù) ID。 相反,方法名必須匹配映射語句的 ID。
此外,返回類型必須匹配期望的結(jié)果類型。所有常用的類型都是支持的,包括:原生類 型,Map,POJO 和 JavaBean。
映射器接口不需要去實現(xiàn)任何接口或擴展任何類。 只要方法前面可以被用來唯一標(biāo)識對 應(yīng)的映射語句就可以了。
映射器接口可以擴展其他接口。當(dāng)使用 XML 來構(gòu)建映射器接口時要保證在合適的命名 空間中有語句。 而且, 唯一的限制就是你不能在兩個繼承關(guān)系的接口中有相同的方法簽名 (這 也是不好的想法)。
你可以傳遞多個參數(shù)給一個映射器方法。 如果你這樣做了, 默認(rèn)情況下它們將會以它們 在參數(shù)列表中的位置來命名,比如:#{param1},#{param2}等。如果你想改變參數(shù)的名稱(只在多參數(shù) 情況下) ,那么你可以在參數(shù)上使用@Param("paramName")注解。
你也可以給方法傳遞一個 RowBounds 實例來限制查詢結(jié)果。
因為最初設(shè)計時,MyBatis 是一個 XML 驅(qū)動的框架。配置信息是基于 XML 的,而且 映射語句也是定義在 XML 中的。而到了 MyBatis 3,有新的可用的選擇了。MyBatis 3 構(gòu)建 在基于全面而且強大的 Java 配置 API 之上。這個配置 API 是基于 XML 的 MyBatis 配置的 基礎(chǔ),也是新的基于注解配置的基礎(chǔ)。注解提供了一種簡單的方式來實現(xiàn)簡單映射語句,而 不會引入大量的開銷。
注意 不幸的是,Java 注解限制了它們的表現(xiàn)和靈活。盡管很多時間都花調(diào)查,設(shè)計和 實驗上,最強大的 MyBatis 映射不能用注解來構(gòu)建,那并不可笑。C#屬性(做示例)就沒 有這些限制,因此 MyBatis.NET 將會比 XML 有更豐富的選擇。也就是說,基于 Java 注解 的配置離不開它的特性。
注解有下面這些:
注解 | 使用對象 | XML 等價形式 | 描述 |
---|---|---|---|
?@CacheNamespace ? |
類 | ?<cache> ? |
為給定的命名空間(比如類)配置緩存。屬性:?implemetation ?、?eviction ?、?flushInterval ?、?size ?、?readWrite ?、?blocking ?、?properties ?。 |
?@Property ? |
N/A | ?<property> ? |
指定參數(shù)值或占位符(?placeholder ?)(該占位符能被 ?mybatis-config.xml ? 內(nèi)的配置屬性替換)。屬性:?name ?、?value ?。(僅在 MyBatis 3.4.2 以上可用) |
?@CacheNamespaceRef ? |
類 | ?<cacheRef> ? |
引用另外一個命名空間的緩存以供使用。注意,即使共享相同的全限定類名,在 XML 映射文件中聲明的緩存仍被識別為一個獨立的命名空間。屬性:?value ?、?name ?。如果你使用了這個注解,你應(yīng)設(shè)置 value 或者 ?name ? 屬性的其中一個。?value ?屬性用于指定能夠表示該命名空間的
Java 類型(命名空間名就是該 Java 類型的全限定類名),name 屬性(這個屬性僅在 MyBatis 3.4.2 以上可用)則直接指定了命名空間的名字。 |
?@ConstructorArgs ? |
方法 | ?<constructor> ? |
收集一組結(jié)果以傳遞給一個結(jié)果對象的構(gòu)造方法。屬性:value,它是一個 Arg 數(shù)組。 |
?@Arg ? |
N/A |
|
ConstructorArgs 集合的一部分,代表一個構(gòu)造方法參數(shù)。屬性:id、column、javaType、jdbcType、typeHandler、select、resultMap。id 屬性和 XML 元素 <idArg> 相似,它是一個布爾值,表示該屬性是否用于唯一標(biāo)識和比較對象。從版本 3.5.4 開始,該注解變?yōu)榭芍貜?fù)注解。 |
?@TypeDiscriminator ? |
方法 | ?<discriminator> ? |
決定使用何種結(jié)果映射的一組取值(case)。屬性:column、javaType、jdbcType、typeHandler、cases。cases 屬性是一個 Case 的數(shù)組。 |
?@Case ? |
N/A | ?<case> ? |
表示某個值的一個取值以及該取值對應(yīng)的映射。屬性:value、type、results。results 屬性是一個 Results 的數(shù)組,因此這個注解實際上和 ResultMap 很相似,由下面的 Results 注解指定。 |
?@Results ? |
方法 | ?<resultMap> ? |
一組結(jié)果映射,指定了對某個特定結(jié)果列,映射到某個屬性或字段的方式。屬性:value、id。value 屬性是一個 Result 注解的數(shù)組。而 id 屬性則是結(jié)果映射的名稱。從版本 3.5.4 開始,該注解變?yōu)榭芍貜?fù)注解。 |
?@Result ? |
N/A |
|
在列和屬性或字段之間的單個結(jié)果映射。屬性:id、column、javaType、jdbcType、typeHandler、one、many。id 屬性和 XML 元素 <id> 相似,它是一個布爾值,表示該屬性是否用于唯一標(biāo)識和比較對象。one 屬性是一個關(guān)聯(lián),和 <association> 類似,而 many 屬性則是集合關(guān)聯(lián),和 <collection> 類似。這樣命名是為了避免產(chǎn)生名稱沖突。 |
?@One ? |
N/A | ?<association> ? |
復(fù)雜類型的單個屬性映射。屬性: select,指定可加載合適類型實例的映射語句(也就是映射器方法)全限定名; fetchType,指定在該映射中覆蓋全局配置參數(shù) lazyLoadingEnabled; resultMap(available since 3.5.5), which is the fully qualified name of a result map that map to a single container object from select result; columnPrefix(available since 3.5.5), which is column prefix for grouping select columns at nested result map. 提示 注解 API 不支持聯(lián)合映射。這是由于 Java 注解不允許產(chǎn)生循環(huán)引用。 |
?@Many ? |
N/A | ?<collection> ? |
復(fù)雜類型的集合屬性映射。屬性: select,指定可加載合適類型實例集合的映射語句(也就是映射器方法)全限定名; fetchType,指定在該映射中覆蓋全局配置參數(shù) lazyLoadingEnabled resultMap(available since 3.5.5), which is the fully qualified name of a result map that map to collection object from select result; columnPrefix(available since 3.5.5), which is column prefix for grouping select columns at nested result map. 提示 注解 API 不支持聯(lián)合映射。這是由于 Java 注解不允許產(chǎn)生循環(huán)引用。 |
?@MapKey ? |
方法 | 供返回值為 Map 的方法使用的注解。它使用對象的某個屬性作為 key,將對象 List 轉(zhuǎn)化為 Map。屬性:value,指定作為 Map 的 key 值的對象屬性名。 | |
?@Options ? |
方法 | 映射語句的屬性 | 該注解允許你指定大部分開關(guān)和配置選項,它們通常在映射語句上作為屬性出現(xiàn)。與在注解上提供大量的屬性相比,Options 注解提供了一致、清晰的方式來指定選項。屬性:useCache=true、flushCache=FlushCachePolicy.DEFAULT、resultSetType=DEFAULT、statementType=PREPARED、fetchSize=-1、timeout=-1、useGeneratedKeys=false、keyProperty=""、keyColumn=""、resultSets="", databaseId=""。注意,Java
注解無法指定 null 值。因此,一旦你使用了 Options 注解,你的語句就會被上述屬性的默認(rèn)值所影響。要注意避免默認(rèn)值帶來的非預(yù)期行為。 The databaseId(Available since 3.5.5), in case there is a configured DatabaseIdProvider, the MyBatis use the Options with no databaseId attribute
or with a databaseId that matches the current one. If found with and without the databaseId the latter will be discarded.
注意:keyColumn 屬性只在某些數(shù)據(jù)庫中有效(如 Oracle、PostgreSQL 等)。要了解更多關(guān)于 keyColumn 和 keyProperty 可選值信息,請查看“insert, update 和 delete”一節(jié)。 |
|
方法 |
|
每個注解分別代表將會被執(zhí)行的 SQL 語句。它們用字符串?dāng)?shù)組(或單個字符串)作為參數(shù)。如果傳遞的是字符串?dāng)?shù)組,字符串?dāng)?shù)組會被連接成單個完整的字符串,每個字符串之間加入一個空格。這有效地避免了用 Java 代碼構(gòu)建 SQL 語句時產(chǎn)生的“丟失空格”問題。當(dāng)然,你也可以提前手動連接好字符串。屬性:value,指定用來組成單個 SQL 語句的字符串?dāng)?shù)組。 The databaseId(Available since 3.5.5), in case there is a configured DatabaseIdProvider, the MyBatis use a statement with no databaseId attribute or with a databaseId that matches the current one. If found with and without the databaseId the latter will be discarded. |
|
方法 |
|
允許構(gòu)建動態(tài) SQL。這些備選的 SQL 注解允許你指定返回 SQL 語句的類和方法,以供運行時執(zhí)行。(從 MyBatis 3.4.6 開始,可以使用 CharSequence 代替 String 來作為返回類型)。當(dāng)執(zhí)行映射語句時,MyBatis 會實例化注解指定的類,并調(diào)用注解指定的方法。你可以通過 ProviderContext 傳遞映射方法接收到的參數(shù)、"Mapper interface type" 和 "Mapper method"(僅在 MyBatis 3.4.5 以上支持)作為參數(shù)。(MyBatis 3.4 以上支持傳入多個參數(shù))屬性:type、method。type 屬性用于指定類名。method 用于指定該類的方法名(從版本 3.5.1 開始,可以省略 method 屬性,MyBatis 將會使用 ProviderMethodResolver 接口解析方法的具體實現(xiàn)。如果解析失敗,MyBatis 將會使用名為 provideSql 的降級實現(xiàn))。提示 接下來的“SQL 語句構(gòu)建器”一章將會討論該話題,以幫助你以更清晰、更便于閱讀的方式構(gòu)建動態(tài) SQL。 The databaseId(Available since 3.5.5), in case there is a configured DatabaseIdProvider, the MyBatis will use a provider method with no databaseId attribute or with a databaseId that matches the current one. If found with and without the databaseId the latter will be discarded. |
?@Param ? |
參數(shù) | N/A | 如果你的映射方法接受多個參數(shù),就可以使用這個注解自定義每個參數(shù)的名字。否則在默認(rèn)情況下,除 RowBounds 以外的參數(shù)會以 "param" 加參數(shù)位置被命名。例如 #{param1}, #{param2}。如果使用了 @Param("person"),參數(shù)就會被命名為 #{person}。 |
?@SelectKey ? |
方法 | ?<selectKey> ? |
這個注解的功能與 <selectKey> 標(biāo)簽完全一致。該注解只能在 @Insert 或 @InsertProvider 或 @Update 或 @UpdateProvider 標(biāo)注的方法上使用,否則將會被忽略。如果標(biāo)注了 @SelectKey 注解,MyBatis 將會忽略掉由 @Options 注解所設(shè)置的生成主鍵或設(shè)置(configuration)屬性。屬性:statement 以字符串?dāng)?shù)組形式指定將會被執(zhí)行的 SQL 語句,keyProperty 指定作為參數(shù)傳入的對象對應(yīng)屬性的名稱,該屬性將會更新成新的值,before 可以指定為 true 或 false 以指明 SQL 語句應(yīng)被在插入語句的之前還是之后執(zhí)行。resultType 則指定 keyProperty 的 Java 類型。statementType 則用于選擇語句類型,可以選擇 STATEMENT、PREPARED 或 CALLABLE 之一,它們分別對應(yīng)于 Statement、PreparedStatement 和 CallableStatement。默認(rèn)值是 PREPARED。 The databaseId(Available since 3.5.5), in case there is a configured DatabaseIdProvider, the MyBatis will use a statement with no databaseId attribute or with a databaseId that matches the current one. If found with and without the databaseId the latter will be discarded. |
?@ResultMap ? |
方法 | N/A | 這個注解為 @Select 或者 @SelectProvider 注解指定 XML 映射中 <resultMap> 元素的 id。這使得注解的 select 可以復(fù)用已在 XML 中定義的 ResultMap。如果標(biāo)注的 select 注解中存在 @Results 或者 @ConstructorArgs 注解,這兩個注解將被此注解覆蓋。 |
?@ResultType ? |
方法 | N/A | 在使用了結(jié)果處理器的情況下,需要使用此注解。由于此時的返回類型為 void,所以 Mybatis 需要有一種方法來判斷每一行返回的對象類型。如果在 XML 有對應(yīng)的結(jié)果映射,請使用 @ResultMap 注解。如果結(jié)果類型在 XML 的 <select> 元素中指定了,就不需要使用其它注解了。否則就需要使用此注解。比如,如果一個標(biāo)注了 @Select 的方法想要使用結(jié)果處理器,那么它的返回類型必須是 void,并且必須使用這個注解(或者 @ResultMap)。這個注解僅在方法返回類型是 void 的情況下生效。 |
?@Flush ? |
方法 | N/A | 如果使用了這個注解,定義在 Mapper 接口中的方法就能夠調(diào)用 SqlSession#flushStatements() 方法。(Mybatis 3.3 以上可用) |
映射申明樣例
這個例子展示了如何使用 @SelectKey 注解來在插入前讀取數(shù)據(jù)庫序列的值:
@Insert("insert into table3 (id, name) values(#{nameId}, #{name})")
@SelectKey(statement="call next value for TestSequence", keyProperty="nameId", before=true, resultType=int.class)
int insertTable3(Name name);
這個例子展示了如何使用 @SelectKey 注解來在插入后讀取數(shù)據(jù)庫識別列的值:
@Insert("insert into table2 (name) values(#{name})")
@SelectKey(statement="call identity()", keyProperty="nameId", before=false, resultType=int.class)
int insertTable2(Name name);
更多建議: