Mybatis 소스 코드
声明:此过程仅记录本人DEBUG过程,如有错误请指出!
JDBC
예:
public class JDBCTest {
12
13 public static void jdbcDemoSelect(String driver,String url,String user,String password) throws Exception {
14
15 //1.加载类驱动
16 Class.forName(driver);
17 Connection con = DriverManager.getConnection(url,user,password);
18
19 // if(!con.isClosed())
20 // System.out.println("succeeded connection to the database");
21
22 //2.创建statement类对象,用来执行SQL语句
23 Statement statement = con.createStatement();
24
25 //SQL语句
26 String sql = "select * from emp";
27
28 //3.ResultSet类,用来存放获取的结果集
29 ResultSet set = statement.executeQuery(sql);
30
31 String eid=null,ename=null,price=null;
32
33 while(set.next()) {
34 eid = set.getString("eid");
35 ename = set.getString("ename");
36 price = set.getString("price");
37
38 System.out.println(eid+"\t"+ename+"\t"+price);
39 }
40
41 }
여기에서 드라이버 받기
Mybatis 소스 코드 후속 조치
빌드 방법을 입구로 사용
구문 분석 방법 입력
parseConfiguration 메소드를 입력하십시오.
해당 mybatis.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<!-- 别名 -->
<typeAliases>
<!-- <typeAlias type="com.test.pojo.People" alias="po" /> -->
<package name="com.lmy.pojo" />
</typeAliases>
<environments default="default">
<environment id="default">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/usermanager?autoReconnect=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="121891"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- <mapper resource="com/test/mapper/StudentMapper.xml" />
<mapper resource="com/test/mapper/TeacherMapper.xml" /> -->
<!--<mapper class="com.test.mapper.TeacherMapper" />-->
<package name="com.lmy.mapper"/>
</mappers>
</configuration>
mapperElement 메소드 입력
xml에서 pachage를 구성한다고 가정합니다.
xml에서 mapper의 리소스를 구성한다고 가정합니다.
configurationElement 메소드 입력
parseStatementNode 메서드를 입력합니다. 여기에 일부 속성을 포함하여 노드에 대한 정보를 얻을 수 있습니다.
public void parseStatementNode() {
String id = context.getStringAttribute("id");
String databaseId = context.getStringAttribute("databaseId");
if (!databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) return;
Integer fetchSize = context.getIntAttribute("fetchSize");
Integer timeout = context.getIntAttribute("timeout");
String parameterMap = context.getStringAttribute("parameterMap");
String parameterType = context.getStringAttribute("parameterType");
Class<?> parameterTypeClass = resolveClass(parameterType);
String resultMap = context.getStringAttribute("resultMap");
String resultType = context.getStringAttribute("resultType");
String lang = context.getStringAttribute("lang");
LanguageDriver langDriver = getLanguageDriver(lang);
Class<?> resultTypeClass = resolveClass(resultType);
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));
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
boolean flushCache = context.getBooleanAttribute("flushCache", !isSelect);
boolean useCache = context.getBooleanAttribute("useCache", isSelect);
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);
String resultSets = context.getStringAttribute("resultSets");
String keyProperty = context.getStringAttribute("keyProperty");
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 {
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);
}
마지막으로 MappedStatement 생성
addMappedStatement 메소드를 입력하십시오.
public MappedStatement addMappedStatement(
String id,
SqlSource sqlSource,
StatementType statementType,
SqlCommandType sqlCommandType,
Integer fetchSize,
Integer timeout,
String parameterMap,
Class<?> parameterType,
String resultMap,
Class<?> resultType,
ResultSetType resultSetType,
boolean flushCache,
boolean useCache,
boolean resultOrdered,
KeyGenerator keyGenerator,
String keyProperty,
String keyColumn,
String databaseId,
LanguageDriver lang,
String resultSets) {
if (unresolvedCacheRef) throw new IncompleteElementException("Cache-ref not yet resolved");
id = applyCurrentNamespace(id, false);
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType);
statementBuilder.resource(resource);
statementBuilder.fetchSize(fetchSize);
statementBuilder.statementType(statementType);
statementBuilder.keyGenerator(keyGenerator);
statementBuilder.keyProperty(keyProperty);
statementBuilder.keyColumn(keyColumn);
statementBuilder.databaseId(databaseId);
statementBuilder.lang(lang);
statementBuilder.resultOrdered(resultOrdered);
statementBuilder.resulSets(resultSets);
setStatementTimeout(timeout, statementBuilder);
setStatementParameterMap(parameterMap, parameterType, statementBuilder);
setStatementResultMap(resultMap, resultType, resultSetType, statementBuilder);
setStatementCache(isSelect, flushCache, useCache, currentCache, statementBuilder);
MappedStatement statement = statementBuilder.build();
configuration.addMappedStatement(statement);
return statement;
}
여기에서 캡슐화 된 최종 MappedStatement 객체가 컬렉션에 추가 된 것을 볼 수 있습니다.
이것은 매퍼 컬렉션입니다
Map 컬렉션의 키가 같으면 덮어 쓰게된다는 것은 누구나 알고 있지만, 동일한 매퍼에서 몇 분 안에 메소드를 구성하면 오류가보고됩니다. 이유는 여기에서 다시 작성하는 put 메소드 때문입니다.
SQL 분석 및 실행
getMapper 입력
InvocationHandler 인터페이스를 상속합니다.
이제 invoke 메소드를 살펴 보겠습니다.
이 실행 방법 입력
SQL에 따른 처리
여기서 select를 사용하고 먼저 반환 값의 유형을 결정합니다. 여기에 목록 모음이 있으므로 여러
구성은 다음과 같습니다.
# {}을 정적 SQL로 사용하고 있기 때문에 여기서 SQL은 여전히 자리 표시자를 사용합니까? , 나중에 세트로 지정
여기에 값 설정