『壹』 mybatis 是sax還是dom解析的
看了mybatis源碼,負責任告訴你,mybatis使用的是SAX解析XML的
『貳』 初看Mybatis 源碼 SQL是怎麼執行的
一條sql語句到底是怎麼執行的?我們知道Mybatis其實是對JDBC的一個封裝。假如我執行
session.update("com.mybatis..AuthUserDao.updateAuthUserEmailByName", [email protected]);
語句,追蹤下來,Executor、 BaseStatementHandler等等。在 SimpleExecutor 中有如下代碼:
public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
Statement stmt = null;
try {
Configuration configuration = ms.getConfiguration();
StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
stmt = prepareStatement(handler, ms.getStatementLog());
return handler.update(stmt);
} finally {
closeStatement(stmt);
}
}
1. 首先獲取相關配置信息,這個在初始化時,從配置文件中解析而來
2. 新建了一個handler
3. 做了執行statement之前的准備工作。看看準備了些什麼,跟蹤代碼,最後進入了DataSource類的doGetConnection方法,該方法做如下操作:
private Connection doGetConnection(Properties properties) throws SQLException {
initializeDriver();
Connection connection = DriverManager.getConnection(url, properties);
configureConnection(connection);
return connection;
}
private synchronized void initializeDriver() throws SQLException {
if (!registeredDrivers.containsKey(driver)) {
Class<?> driverType;
try {
if (driverClassLoader != null) {
driverType = Class.forName(driver, true, driverClassLoader);
} else {
driverType = Resources.classForName(driver);
}
// DriverManager requires the driver to be loaded via the system ClassLoader.
// http://www.kfu.com/~nsayer/java/dyn-jdbc.html
Driver driverInstance = (Driver)driverType.newInstance();
DriverManager.registerDriver(new DriverProxy(driverInstance));
registeredDrivers.put(driver, driverInstance);
} catch (Exception e) {
throw new SQLException("Error setting driver on UnpooledDataSource. Cause: " + e);
}
}
}
原來是通過prepareStatement 來執行了 我們初始化jdbc的操作。Class.forName DriverManager.getConnection. 這兩步是在這裡面完成的。
4. 將執行sql的部分交給handler
繼續跟蹤handler 可以看到SimpleStatementHandler 中。如下執行這個update語句
public int update(Statement statement)
throws SQLException {
String sql = boundSql.getSql();
Object parameterObject = boundSql.getParameterObject();
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
int rows;
if (keyGenerator instanceof Jdbc3KeyGenerator) {
statement.execute(sql, Statement.RETURN_GENERATED_KEYS);
rows = statement.getUpdateCount();
keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
} else if (keyGenerator instanceof SelectKeyGenerator) {
statement.execute(sql);
rows = statement.getUpdateCount();
keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
} else {
statement.execute(sql);
rows = statement.getUpdateCount();
}
return rows;
}
這邊就完成了statement的操作,整個過程就是我們Jdbc的過程。原來真的就是對JDBC的簡單封裝。
其實Mybatis的整個執行過程,理解起來分為如下幾個過程:
1. 載入配置文件
2. 解析配置文件,從配置文件中解析出來 datasource、mapper文件、事務配置等等。將配置信息保存在對象內
3. 調用相關語句,執行sql。在執行的方法中分別完成JDBC的一系列操作。
『叄』 Java架構的路上必學知識點,你又知道多少
Jenkins多套環境(test/pre/proction)系統自動化發布
Jenkins自動發布到遠程主機
MavenMaven私服搭建setting.xml文件剖析pom.xml詳解Maven實用插件教學(靜態代碼檢查、生成可執行jar包)profile使用
源碼分析
源碼分析 Spring源碼分析
Spring IOC的實現原理Spring BeanFactory源碼分析Spring AOP的實現原理及配置文件詳解Spring AOP的各種應用場景分析Spring MVC與Struts對比Spring HandlerMapping詳解手寫實現SpringMVC框架Spring與各種框架集成原理Spring JDBC操作原理基於Spring JDBC手寫ORM框架
MyBatis源碼分析
MyBatis3簡介MyBatis3 SqlMap那些事兒資料庫連接池到底是什麼MyBatis3 SessionFactory實現原理MyBatis3 配置文件詳解MyBatis3 事務管理與集成淺談HibernateMyBatis3與Hibernate框架對比Netty源碼分析
NIO通信原理剖析深入了解NIO緩沖區Buffer
NIO Selector原理AIO編程Netty產生的背景以及基礎入門
Netty高性能之道Netty的HTTP與Socket通信原理利用Netty搭建高性能的
WebSocket聊天室
Netty聊天室客戶端架構實現Netty的編碼解碼
Netty的拆包粘包操作MsgPack原理講解及各種序列化框架對比MsgPack與Netty整合
Netty HTTP通信與Spring整合Netty RPC架構Netty與各種架構整合以及Netty源碼分析
性能調優
性能調優 JVMJVM內存模型JVM運行時數據區垃圾回收機制GC日誌詳解
根據GC日誌調優系統,調優不靠碰運氣!Mysql資料庫優化
資料庫底層數據結構索引數據存儲結構 innodb詳解SQL調優及原理分庫、分表實現Nginx調優動靜資源分離
nginx參數詳解nginx + lua使用應用:ip過濾,扛DDOSTomcat調優
Tomcat源碼、架構分析Tomcat具體調優參數設置Tomcat壓力基準測試Tomcat NIO配置
『肆』 mybatis中怎麼創建sqlsession
首先, 通過翻閱源碼,我們來整理一下mybatis進行持久化操作時重要的幾個類:
SqlSessionFactoryBuilder:build方法創建SqlSessionFactory實例。
SqlSessionFactory:創建SqlSession實例的工廠。
SqlSession:用於執行持久化操作的對象,類似於jdbc中的Connection。
SqlSessionTemplate:MyBatis提供的持久層訪問模板化的工具,線程安全,可通過構造參數或依賴注入SqlSessionFactory實例。
Hibernate是與MyBatis類似的orm框架,這里與Hibernate進行一下對比,Hibernate中對於connection的管理,是通過以下幾個重要的類:
SessionFactory:創建Session實例的工廠,類似於MyBatis中的SqlSessionFactory。
Session:用來執行持久化操作的對象,類似於jdbc中的Connection。
HibernateTemplate:Hibernate提供的持久層訪問模板化的工具,線程安全,可通過構造參數或依賴注入SessionFactory實例。
在日常的開發中,我們經常需要這樣對MyBatis和Spring進行集成,把sqlSessionFactory交給Spring管理,通常情況下,我們這樣配置:
<code class="hljs nimrod"><bean id=<span class="hljs-string">"sqlSessionFactory" class=<span class="hljs-string">"org.mybatis.spring.SqlSessionFactoryBean">
<property name=<span class="hljs-string">"dataSource" <span class="hljs-keyword">ref=<span class="hljs-string">"dataSource" />
</bean></span></span></span></span></span></code>
通過上面的配置,Spring將自動創建一個SqlSessionFactory對象,其中使用到了org.mybatis.spring.SqlSessionFactoryBean,其 是MyBatis為Spring提供的用於創建SqlSessionFactory的類,將在Spring應用程序的上下文建議一下可共享的 MyBatis SqlSessionFactory實例,我們可以通過依賴注入將SqlSessionFactory傳遞給MyBatis的一些介面。
如果通過Spring進行事務的管理,我們需要增加Spring註解的事務管理機制,如下配置:
<code class="hljs nimrod"><bean id=<span class="hljs-string">"transactionManager" class=<span class="hljs-string">"org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name=<span class="hljs-string">"dataSource" <span class="hljs-keyword">ref=<span class="hljs-string">"dataSource" />
</bean>
<tx:annotation-driven/></span></span></span></span></span></code>
這樣,我們就可以使用Spring @Transactional註解,進行事務的控制,表明所注釋的方法應該在一個事務中運行。 Spring將在事務成功完成後提交事務,在事務發生錯誤時進行異常回滾,而且,Spring會將產生的MyBatis異常轉換成適當的 DataAccessExceptions,從而提供具體的異常信息。
下面,我們通過分析SqlSessionUtils中getSession的源碼,來詳細的了解一下sqlSession的產生過程,源碼如下:
<code class="hljs d"><span class="hljs-keyword">public <span class="hljs-keyword">static SqlSession getSqlSession(SqlSessionFactory sessionFactory, ExecutorType executorType, exceptionTranslator) {
notNull(sessionFactory, <span class="hljs-string">"No SqlSessionFactory specified");
notNull(executorType, <span class="hljs-string">"No ExecutorType specified");
SqlSessionHolder holder = (SqlSessionHolder) getResource(sessionFactory);
<span class="hljs-keyword">if (holder != <span class="hljs-literal">null && holder.isSynchronizedWithTransaction()) {
<span class="hljs-keyword">if (holder.getExecutorType() != executorType) {
<span class="hljs-keyword">throw <span class="hljs-keyword">new (<span class="hljs-string">"Cannot change the ExecutorType when there is an existing transaction");
}
holder.requested();
<span class="hljs-keyword">if (logger.isDebugEnabled()) {
logger.<span class="hljs-keyword">debug(<span class="hljs-string">"Fetched SqlSession [" + holder.getSqlSession() + <span class="hljs-string">"] from current transaction");
}
<span class="hljs-keyword">return holder.getSqlSession();
}
<span class="hljs-keyword">if (logger.isDebugEnabled()) {
logger.<span class="hljs-keyword">debug(<span class="hljs-string">"Creating a new SqlSession");
}
SqlSession session = sessionFactory.openSession(executorType);
<span class="hljs-comment">// Register session holder if synchronization is active (i.e. a Spring TX is active)
<span class="hljs-comment">//
<span class="hljs-comment">// Note: The DataSource used by the Environment should be synchronized with the
<span class="hljs-comment">// transaction either through DataSourceTxMgr or another tx synchronization.
<span class="hljs-comment">// Further assume that if an exception is thrown, whatever started the transaction will
<span class="hljs-comment">// handle closing / rolling back the Connection associated with the SqlSession.
<span class="hljs-keyword">if (isSynchronizationActive()) {
Environment environment = sessionFactory.getConfiguration().getEnvironment();
<span class="hljs-keyword">if (environment.getTransactionFactory() instanceof ) {
<span class="hljs-keyword">if (logger.isDebugEnabled()) {
logger.<span class="hljs-keyword">debug(<span class="hljs-string">"Registering transaction synchronization for SqlSession [" + session + <span class="hljs-string">"]");
}
holder = <span class="hljs-keyword">new SqlSessionHolder(session, executorType, exceptionTranslator);
bindResource(sessionFactory, holder);
registerSynchronization(<span class="hljs-keyword">new SqlSessionSynchronization(holder, sessionFactory));
holder.(<span class="hljs-literal">true);
holder.requested();
} <span class="hljs-keyword">else {
<span class="hljs-keyword">if (getResource(environment.getDataSource()) == <span class="hljs-literal">null) {
<span class="hljs-keyword">if (logger.isDebugEnabled()) {
logger.<span class="hljs-keyword">debug(<span class="hljs-string">"SqlSession [" + session + <span class="hljs-string">"] was not registered for synchronization because DataSource is not transactional");
}
} <span class="hljs-keyword">else {
<span class="hljs-keyword">throw <span class="hljs-keyword">new (
<span class="hljs-string">"SqlSessionFactory must be using a in order to use Spring transaction synchronization");
}
}
} <span class="hljs-keyword">else {
<span class="hljs-keyword">if (logger.isDebugEnabled()) {
logger.<span class="hljs-keyword">debug(<span class="hljs-string">"SqlSession [" + session + <span class="hljs-string">"] was not registered for synchronization because synchronization is not active");
}
}
<span class="hljs-keyword">return session;
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
『伍』 什麼是mybatis
MyBatis 是一個可以自定義SQL、存儲過程和高級映射的持久層框架。MyBatis 摒除了大部分的JDBC代碼、手工設置參數和結果集重獲。MyBatis 只使用簡單的XML 和註解來配置和映射基本數據類型、Map 介面和POJO 到資料庫記錄。相對Hibernate和Apache OJB等「一站式」ORM解決方案而言,Mybatis 是一種「半自動化」的ORM實現。
需要使用的Jar包:mybatis-3.0.2.jar(mybatis核心包)。mybatis-spring-1.0.0.jar(與Spring結合包)。
MyBatis的前身是ibatis,但是在配置sql的語法上有明顯的區別,並且spring目前的版本封裝mybatis,至於mybatis-spring.jar文件也是mybatis團隊復雜開發的jar包,用於和spring整合。之前ibatis的源碼託管方是apache,而mybatis是google。
『陸』 什麼是mybatis 為什麼要使用my batis
1、定義
MyBatis是一個支持普通SQL查詢,存儲過程和高級映射的優秀持久層框架。
2、使用原因
MyBatis消除了幾乎所有的JDBC代碼和參數的手工設置以及對結果集的檢索封裝。MyBatis可以使用簡單的XML或註解用於配置和原始映射,將介面和Java的POJO(Plain Old Java Objects,普通的Java對象)映射成資料庫中的記錄。
3、總體流程
(1)載入配置並初始化
觸發條件:載入配置文件
處理過程:將SQL的配置信息載入成為一個個MappedStatement對象(包括了傳入參數映射配置、執行的SQL語句、結果映射配置),存儲在內存中。
(2)接收調用請求
觸發條件:調用Mybatis提供的API
傳入參數:為SQL的ID和傳入參數對象
處理過程:將請求傳遞給下層的請求處理層進行處理。
(3)處理操作請求
觸發條件:API介面層傳遞請求過來
傳入參數:為SQL的ID和傳入參數對象
處理過程:
(A)根據SQL的ID查找對應的MappedStatement對象。
(B)根據傳入參數對象解析MappedStatement對象,得到最終要執行的SQL和執行傳入參數。
(C)獲取資料庫連接,根據得到的最終SQL語句和執行傳入參數到資料庫執行,並得到執行結果。
(D)根據MappedStatement對象中的結果映射配置對得到的執行結果進行轉換處理,並得到最終的處理結果。
(E)釋放連接資源。
(4)返回處理結果將最終的處理結果返回。
『柒』 《深入淺出MyBatis技術原理與實戰》pdf下載在線閱讀全文,求百度網盤雲資源
《深入淺出MyBatis技術原理與實戰》網路網盤pdf最新全集下載:
鏈接:https://pan..com/s/1LxgP-ibmyXjclY23yXMN-Q
『捌』 mybatis工作原理及為什麼要用
一、mybatis的工作原理:
MyBatis 是支持普通 SQL查詢,存儲過程和高級映射的優秀持久層框架。MyBatis 消除了幾乎所有的JDBC代碼和參數的手工設置以及結果集的檢索。
MyBatis使用簡單的 XML或註解用於配置和原始映射,將介面和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java對象)映射成資料庫中的記錄。
每個MyBatis應用程序主要都是使用SqlSessionFactory實例的,一個SqlSessionFactory實例可以通過SqlSessionFactoryBuilder獲得。用xml文件構建SqlSessionFactory實例是非常簡單的事情。
推薦在這個配置中使用類路徑資源,但可以使用任何Reader實例,包括用文件路徑或file://開頭的url創建的實例。MyBatis有一個實用類----Resources,它有很多方法,可以方便地從類路徑及其它位置載入資源。
二、使用mybatis的原因:因為mybatis具有許多的優點,具體如下:
1、簡單易學:本身就很小且簡單。沒有任何第三方依賴,最簡單安裝只要兩個jar文件+配置幾個sql映射文件易於學習,易於使用,通過文檔和源代碼,可以比較完全的掌握它的設計思路和實現。
2、靈活:mybatis不會對應用程序或者資料庫的現有設計強加任何影響。 sql寫在xml里,便於統一管理和優化。通過sql語句可以滿足操作資料庫的所有需求。
3、解除sql與程序代碼的耦合:通過提供DAO層,將業務邏輯和數據訪問邏輯分離,使系統的設計更清晰,更易維護,更易單元測試。sql和代碼的分離,提高了可維護性。
4、提供映射標簽,支持對象與資料庫的orm欄位關系映射。
5、提供對象關系映射標簽,支持對象關系組建維護。
6、提供xml標簽,支持編寫動態sql。
(8)ybatis源碼分析擴展閱讀:
mybatis的功能構架:
1、API介面層:提供給外部使用的介面API,開發人員通過這些本地API來操縱資料庫。介面層一接收到調用請求就會調用數據處理層來完成具體的數據處理。
2、數據處理層:負責具體的SQL查找、SQL解析、SQL執行和執行結果映射處理等。它主要的目的是根據調用的請求完成一次資料庫操作。
3、基礎支撐層:負責最基礎的功能支撐,包括連接管理、事務管理、配置載入和緩存處理,這些都是共用的東西,將他們抽取出來作為最基礎的組件。為上層的數據處理層提供最基礎的支撐。
『玖』 怎麼沒有mybatis源碼解析相關的文檔
我們還記得是這樣配置sqlSessionFactory的:
[java] view plain
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:configuration.xml"></property>
<property name="mapperLocations" value="classpath:com/xxx/mybatis/mapper/*.xml"/>
<property name="typeAliasesPackage" value="com.tiantian.mybatis.model" />
</bean>
這里配置了一個mapperLocations屬性,它是一個表達式,sqlSessionFactory會根據這個表達式讀取包com.xxx.myts.mapper下面的所有xml格式文件,那麼具體是怎麼根據這個屬性來讀取配置文件的呢?
答案就在SqlSessionFactoryBean類中的buildSqlSessionFactory方法中:
[java] view plain
if (!isEmpty(this.mapperLocations)) {
for (Resource mapperLocation : this.mapperLocations) {
if (mapperLocation == null) {
continue;
}
try {
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
configuration, mapperLocation.toString(), configuration.getSqlFragments());
xmlMapperBuilder.parse();
} catch (Exception e) {
throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
} finally {
ErrorContext.instance().reset();
}
if (logger.isDebugEnabled()) {
logger.debug("Parsed mapper file: '" + mapperLocation + "'");
}
}
}
mybatis使用XMLMapperBuilder類的實例來解析mapper配置文件。
[java] view plain
public XMLMapperBuilder(Reader reader, Configuration configuration, String resource, Map<String, XNode> sqlFragments) {
this(new XPathParser(reader, true, configuration.getVariables(), new XMLMapperEntityResolver()),
configuration, resource, sqlFragments);
}
[java] view plain
private XMLMapperBuilder(XPathParser parser, Configuration configuration, String resource, Map<String, XNode> sqlFragments) {
super(configuration);
this.builderAssistant = new MapperBuilderAssistant(configuration, resource);
this.parser = parser;
this.sqlFragments = sqlFragments;
this.resource = resource;
}
接著系統調用xmlMapperBuilder的parse方法解析mapper。
[java] view plain
public void parse() {
//如果configuration對象還沒載入xml配置文件(避免重復載入,實際上是確認是否解析了mapper節點的屬性及內容,
//為解析它的子節點如cache、sql、select、resultMap、parameterMap等做准備),
//則從輸入流中解析mapper節點,然後再將resource的狀態置為已載入
if (!configuration.isResourceLoaded(resource)) {
configurationElement(parser.evalNode("/mapper"));
configuration.addLoadedResource(resource);
bindMapperForNamespace();
}
//解析在configurationElement函數中處理resultMap時其extends屬性指向的父對象還沒被處理的<resultMap>節點
parsePendingResultMaps();
//解析在configurationElement函數中處理cache-ref時其指向的對象不存在的<cache>節點(如果cache-ref先於其指向的cache節點載入就會出現這種情況)
parsePendingChacheRefs();
//同上,如果cache沒載入的話處理statement時也會拋出異常
parsePendingStatements();
}
mybatis解析mapper的xml文件的過程已經很明顯了,接下來我們看看它是怎麼解析mapper的:
[java] view plain
private void configurationElement(XNode context) {
try {
//獲取mapper節點的namespace屬性
String namespace = context.getStringAttribute("namespace");
if (namespace.equals("")) {
throw new BuilderException("Mapper's namespace cannot be empty");
}
//設置當前namespace
builderAssistant.setCurrentNamespace(namespace);
//解析mapper的<cache-ref>節點
cacheRefElement(context.evalNode("cache-ref"));
//解析mapper的<cache>節點
cacheElement(context.evalNode("cache"));
//解析mapper的<parameterMap>節點
parameterMapElement(context.evalNodes("/mapper/parameterMap"));
//解析mapper的<resultMap>節點
resultMapElements(context.evalNodes("/mapper/resultMap"));
//解析mapper的<sql>節點
sqlElement(context.evalNodes("/mapper/sql"));
//使用XMLStatementBuilder的對象解析mapper的<select>、<insert>、<update>、<delete>節點,
//myts會使用MappedStatement.Builder類build一個MappedStatement對象,
//所以myts中一個sql對應一個MappedStatement
buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
} catch (Exception e) {
throw new BuilderException("Error parsing Mapper XML. Cause: " + e, e);
}
}
configurationElement函數幾乎解析了mapper節點下所有子節點,至此myts解析了mapper中的所有節點,並將其加入到了Configuration對象中提供給sqlSessionFactory對象隨時使用。這里我們需要補充講一下myts是怎麼使用XMLStatementBuilder類的對象的parseStatementNode函數借用MapperBuilderAssistant類對象builderAssistant的addMappedStatement解析MappedStatement並將其關聯到Configuration類對象的:
[java] view plain
public void parseStatementNode() {
//ID屬性
String id = context.getStringAttribute("id");
//databaseId屬性
String databaseId = context.getStringAttribute("databaseId");
if (!databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) {
return;
}
//fetchSize屬性
Integer fetchSize = context.getIntAttribute("fetchSize");
//timeout屬性
Integer timeout = context.getIntAttribute("timeout");
//parameterMap屬性
String parameterMap = context.getStringAttribute("parameterMap");
//parameterType屬性
String parameterType = context.getStringAttribute("parameterType");
Class<?> parameterTypeClass = resolveClass(parameterType);
//resultMap屬性
String resultMap = context.getStringAttribute("resultMap");
//resultType屬性
String resultType = context.getStringAttribute("resultType");
//lang屬性
String lang = context.getStringAttribute("lang");
LanguageDriver langDriver = getLanguageDriver(lang);
Class<?> resultTypeClass = resolveClass(resultType);
//resultSetType屬性
String resultSetType = context.getStringAttribute("resultSetType");
StatementType statementType = StatementType.valueOf(context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
ResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);
String nodeName = context.getNode().getNodeName();
SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
//是否是<select>節點
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
//flushCache屬性
boolean flushCache = context.getBooleanAttribute("flushCache", !isSelect);
//useCache屬性
boolean useCache = context.getBooleanAttribute("useCache", isSelect);
//resultOrdered屬性
boolean resultOrdered = context.getBooleanAttribute("resultOrdered", false);
// Include Fragments before parsing
XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);
includeParser.applyIncludes(context.getNode());
// Parse selectKey after includes and remove them.
processSelectKeyNodes(id, parameterTypeClass, langDriver);
// Parse the SQL (pre: <selectKey> and <include> were parsed and removed)
SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);
//resultSets屬性
String resultSets = context.getStringAttribute("resultSets");
//keyProperty屬性
String keyProperty = context.getStringAttribute("keyProperty");
//keyColumn屬性
String keyColumn = context.getStringAttribute("keyColumn");
KeyGenerator keyGenerator;
String keyStatementId = id + SelectKeyGenerator.SELECT_KEY_SUFFIX;
keyStatementId = builderAssistant.applyCurrentNamespace(keyStatementId, true);
if (configuration.hasKeyGenerator(keyStatementId)) {
keyGenerator = configuration.getKeyGenerator(keyStatementId);
} else {
//useGeneratedKeys屬性
keyGenerator = context.getBooleanAttribute("useGeneratedKeys",
configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType))
? new Jdbc3KeyGenerator() : new NoKeyGenerator();
}
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
resultSetTypeEnum, flushCache, useCache, resultOrdered,
keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);
}
由以上代碼可以看出myts使用XPath解析mapper的配置文件後將其中的resultMap、parameterMap、cache、statement等節點使用關聯的builder創建並將得到的對象關聯到configuration對象中,而這個configuration對象可以從sqlSession中獲取的,這就解釋了我們在使用sqlSession對資料庫進行操作時myts怎麼獲取到mapper並執行其中的sql語句的問題。
『拾』 怎麼學習mybatis框架的源碼
剛剛好我前段時間做了一個基於SpringMVC + Mybatis + Redis + Freemarker(JSP)的許可權控制Demo。地址看下面代碼:/** * 網路不讓輸入網址 * 地址為 */String url = "